aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2010-09-13 19:24:53 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2010-09-13 19:24:53 +0200
commitb230b69539c1ec84c425da9808dceb5b13a37bb0 (patch)
tree11e0eb6338f03246ed7fc38d5dad6ccd649f1686
downloadlogdiag-b230b69539c1ec84c425da9808dceb5b13a37bb0.tar.gz
logdiag-b230b69539c1ec84c425da9808dceb5b13a37bb0.tar.xz
logdiag-b230b69539c1ec84c425da9808dceb5b13a37bb0.zip
Initial commit
-rw-r--r--CMakeLists.txt134
-rw-r--r--LICENSE26
-rw-r--r--cmake/FindGTK2.cmake546
-rw-r--r--cmake/FindGettext.cmake105
-rw-r--r--cmake/FindGtkDoc.cmake366
-rw-r--r--cmake/ProcessArguments.cmake140
-rw-r--r--config.h.in84
-rw-r--r--po/logdiag.pot23
-rwxr-xr-xpo/make-template.sh33
-rw-r--r--share/gui/window-main.ui26
-rw-r--r--share/logdiag.desktop9
-rw-r--r--src/canvas.c1
-rw-r--r--src/canvas.h0
-rw-r--r--src/document.c0
-rw-r--r--src/document.h0
-rw-r--r--src/main.c40
-rw-r--r--src/symbol-category.h69
-rw-r--r--src/symbol-library.c307
-rw-r--r--src/symbol-library.h69
-rw-r--r--src/symbol.h69
-rw-r--r--src/window-main.c283
-rw-r--r--src/window-main.h60
22 files changed, 2390 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..63529e4
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,134 @@
+project (logdiag)
+cmake_minimum_required (VERSION 2.6.2)
+
+# Default to 2.6.3 behaviour
+cmake_policy (VERSION 2.6.3)
+
+# Options
+option (OPTION_NOINSTALL "Only for developers; work without installing" OFF)
+
+if (OPTION_NOINSTALL)
+ set (OPTION_NOINSTALL 1)
+else (OPTION_NOINSTALL)
+ set (OPTION_NOINSTALL 0)
+endif (OPTION_NOINSTALL)
+
+
+# Version
+set (project_VERSION_MAJOR "0")
+set (project_VERSION_MINOR "0")
+set (project_VERSION_PATCH "1")
+set (project_VERSION "0.0.1")
+
+# For custom modules
+set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+
+# Gather package information
+find_package (GTK2 2.8 REQUIRED gtk)
+
+# Test this machine
+include (CheckCSourceCompiles)
+
+CHECK_C_SOURCE_COMPILES (
+"typedef struct abc *d;
+int test (d __restrict x);
+int main (void) {return 0;}"
+HAVE_SANE___RESTRICT)
+
+CHECK_C_SOURCE_COMPILES (
+"int test (void *restrict x);
+int main (void) {return 0;}"
+HAVE_RESTRICT)
+
+include (CheckFunctionExists)
+
+CHECK_FUNCTION_EXISTS ("snprintf" HAVE_SNPRINTF)
+CHECK_FUNCTION_EXISTS ("sprintf_s" HAVE_SPRINTF_S)
+
+CHECK_FUNCTION_EXISTS ("strdup" HAVE_STRDUP)
+CHECK_FUNCTION_EXISTS ("_strdup" HAVE__STRDUP)
+
+CHECK_FUNCTION_EXISTS ("strtok_r" HAVE_STRTOK_R)
+CHECK_FUNCTION_EXISTS ("strtok_s" HAVE_STRTOK_S)
+
+if (WIN32)
+ set (HAVE_THREADSAFE_STRTOK true)
+endif (WIN32)
+
+# Localization
+find_package (Gettext)
+if (GETTEXT_FOUND)
+ set (HAVE_GETTEXT true)
+ file (GLOB project_TRANSLATIONS ${CMAKE_CURRENT_SOURCE_DIR}/po/*.po)
+ GETTEXT_CREATE_TRANSLATIONS (
+ ${CMAKE_CURRENT_SOURCE_DIR}/po/${PROJECT_NAME}.pot
+ ALL ${project_TRANSLATIONS})
+endif (GETTEXT_FOUND)
+
+# Documentation
+# TODO: Pregenerated docs
+
+#set (GTK_DOC_ENABLE OFF CACHE BOOL
+# "Use gtk-doc to build documentation")
+#set (GTK_DOC_ENABLE_HTML ON CACHE BOOL
+# "Build documentation in HTML format")
+
+find_package (GtkDoc REQUIRED)
+set (project_DOC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/docs/reference")
+GTK_DOC_RUN (WORKING_DIR ${project_DOC_DIR}
+ SOURCE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src
+ XML ${project_DOC_DIR}/xml --sgml-mode
+ HTML ${project_DOC_DIR}/html)
+
+# Project source files
+set (logdiag_SOURCES
+ src/main.c
+ src/window-main.c
+ src/document.c
+ src/canvas.c
+ src/symbol-library.c)
+set (logdiag_HEADERS
+ ${CMAKE_CURRENT_BINARY_DIR}/config.h
+ src/window-main.h
+ src/document.h
+ src/canvas.h
+ src/symbol.h
+ src/symbol-category.h
+ src/symbol-library.h)
+
+# Generate a configure file
+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+include_directories (${CMAKE_CURRENT_BINARY_DIR})
+
+# Build the executable
+include_directories (${GTK2_INCLUDE_DIRS})
+add_executable (logdiag ${logdiag_SOURCES} ${logdiag_HEADERS})
+target_link_libraries (logdiag ${GTK2_LIBRARIES})
+
+# Installation
+install (TARGETS logdiag DESTINATION bin)
+install (FILES share/logdiag.desktop DESTINATION share/applications)
+install (DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/docs/html/"
+ DESTINATION usr/gtk-doc/${CMAKE_PROJECT_NAME})
+
+# CPack
+set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Electric diagram designer.")
+set (CPACK_PACKAGE_VENDOR "Přemysl Janouch")
+set (CPACK_PACKAGE_CONTACT "p.janouch@gmail.com")
+set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+set (CPACK_PACKAGE_VERSION_MAJOR ${project_VERSION_MAJOR})
+set (CPACK_PACKAGE_VERSION_MINOR ${project_VERSION_MINOR})
+set (CPACK_PACKAGE_VERSION_PATCH ${project_VERSION_PATCH})
+set (CPACK_GENERATOR "TGZ;ZIP")
+set (CPACK_PACKAGE_FILE_NAME
+ "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
+set (CPACK_PACKAGE_INSTALL_DIRECTORY
+ "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")
+set (CPACK_SOURCE_GENERATOR "TGZ;ZIP")
+set (CPACK_SOURCE_IGNORE_FILES "/build;/.svn;/.git")
+set (CPACK_SOURCE_PACKAGE_FILE_NAME
+ "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")
+
+include (CPack)
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..37280c3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright Přemysl Janouch 2010
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * The names of the copyright holders and contributors may not be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
+
diff --git a/cmake/FindGTK2.cmake b/cmake/FindGTK2.cmake
new file mode 100644
index 0000000..39beae9
--- /dev/null
+++ b/cmake/FindGTK2.cmake
@@ -0,0 +1,546 @@
+# - FindGTK2.cmake
+# This module can find the GTK2 widget libraries and several of its other
+# optional components like gtkmm, glade, and glademm.
+#
+# NOTE: If you intend to use version checking, CMake 2.6.2 or later is
+# required.
+#
+# Specify one or more of the following components
+# as you call this find module. See example below.
+#
+# gtk
+# gtkmm
+# glade
+# glademm
+#
+# The following variables will be defined for your use
+#
+# GTK2_FOUND - Were all of your specified components found?
+# GTK2_INCLUDE_DIRS - All include directories
+# GTK2_LIBRARIES - All libraries
+#
+# GTK2_VERSION - The version of GTK2 found (x.y.z)
+# GTK2_MAJOR_VERSION - The major version of GTK2
+# GTK2_MINOR_VERSION - The minor version of GTK2
+# GTK2_PATCH_VERSION - The patch version of GTK2
+#
+# Optional variables you can define prior to calling this module:
+#
+# GTK2_DEBUG - Enables verbose debugging of the module
+# GTK2_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced
+#
+#=================
+# Example Usage:
+#
+# Call find_package() once, here are some examples to pick from:
+#
+# Require GTK 2.6 or later
+# find_package(GTK2 2.6 REQUIRED gtk)
+#
+# Require GTK 2.10 or later and Glade
+# find_package(GTK2 2.10 REQUIRED gtk glade)
+#
+# Search for GTK/GTKMM 2.8 or later
+# find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
+#
+# if(GTK2_FOUND)
+# include_directories(${GTK2_INCLUDE_DIRS})
+# add_executable(mygui mygui.cc)
+# target_link_libraries(mygui ${GTK2_LIBRARIES})
+# endif()
+#
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2008-2009 Philip Lowman <philip@yhbt.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Version 0.7 (3/22/09)
+# * Checked into CMake CVS
+# * Added versioning support
+# * Module now defaults to searching for GTK if COMPONENTS not specified.
+# * Added HKCU prior to HKLM registry key and GTKMM specific environment
+# variable as per mailing list discussion.
+# * Added lib64 to include search path and a few other search paths where GTK
+# may be installed on Unix systems.
+# * Switched to lowercase CMake commands
+# * Prefaced internal variables with _GTK2 to prevent collision
+# * Changed internal macros to functions
+# * Enhanced documentation
+# Version 0.6 (1/8/08)
+# Added GTK2_SKIP_MARK_AS_ADVANCED option
+# Version 0.5 (12/19/08)
+# Second release to cmake mailing list
+
+#=============================================================
+# _GTK2_GET_VERSION
+# Internal function to parse the version number in gtkversion.h
+# _OUT_major = Major version number
+# _OUT_minor = Minor version number
+# _OUT_micro = Micro version number
+# _gtkversion_hdr = Header file to parse
+#=============================================================
+function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr)
+ file(READ ${_gtkversion_hdr} _contents)
+ if(_contents)
+ string(REGEX REPLACE ".*#define GTK_MAJOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_major} "${_contents}")
+ string(REGEX REPLACE ".*#define GTK_MINOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_minor} "${_contents}")
+ string(REGEX REPLACE ".*#define GTK_MICRO_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_micro} "${_contents}")
+
+ if(NOT ${_OUT_major} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MAJOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_minor} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MINOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_micro} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MICRO_VERSION!")
+ endif()
+
+ set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE)
+ set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE)
+ set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "Include file ${_gtkversion_hdr} does not exist")
+ endif()
+endfunction()
+
+#=============================================================
+# _GTK2_FIND_INCLUDE_DIR
+# Internal function to find the GTK include directories
+# _var = variable to set
+# _hdr = header file to look for
+#=============================================================
+function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_FIND_INCLUDE_DIR( ${_var} ${_hdr} )")
+ endif()
+
+ set(_relatives
+ # FIXME
+ glibmm-2.4
+ glib-2.0
+ atk-1.0
+ atkmm-1.6
+ cairo
+ cairomm-1.0
+ gdkmm-2.4
+ giomm-2.4
+ gtk-2.0
+ gtkmm-2.4
+ libglade-2.0
+ libglademm-2.4
+ pango-1.0
+ pangomm-1.4
+ sigc++-2.0
+ )
+
+ set(_suffixes)
+ foreach(_d ${_relatives})
+ list(APPEND _suffixes ${_d})
+ list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include
+ endforeach()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "include suffixes = ${_suffixes}")
+ endif()
+
+ find_path(${_var} ${_hdr}
+ PATHS
+ /usr/local/lib64
+ /usr/local/lib
+ /usr/lib64
+ /usr/lib
+ /opt/gnome/include
+ /opt/gnome/lib
+ /opt/openwin/include
+ /usr/openwin/lib
+ $ENV{GTKMM_BASEPATH}/include
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/include
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/include
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ PATH_SUFFIXES
+ ${_suffixes}
+ )
+
+ if(${_var})
+ set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE)
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var})
+ endif()
+ endif()
+
+endfunction(_GTK2_FIND_INCLUDE_DIR)
+
+#=============================================================
+# _GTK2_FIND_LIBRARY
+# Internal function to find libraries packaged with GTK2
+# _var = library variable to create
+#=============================================================
+function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )")
+ endif()
+
+ # Not GTK versions per se but the versions encoded into Windows
+ # import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example)
+ # Also the MSVC libraries use _ for . (this is handled below)
+ set(_versions 2.20 2.18 2.16 2.14 2.12
+ 2.10 2.8 2.6 2.4 2.2 2.0
+ 1.20 1.18 1.16 1.14 1.12
+ 1.10 1.8 1.6 1.4 1.2 1.0)
+
+ set(_library)
+ set(_library_d)
+
+ set(_library ${_lib})
+
+ if(_expand_vc)
+ # Add vc80/vc90 midfixes
+ if(MSVC80)
+ set(_library ${_library}-vc80)
+ set(_library_d ${_library}-d)
+ elseif(MSVC90)
+ set(_library ${_library}-vc90)
+ set(_library_d ${_library}-d)
+ endif()
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "After midfix addition = ${_library} and ${_library_d}")
+ endif()
+
+ set(_lib_list)
+ set(_libd_list)
+ if(_append_version)
+ foreach(_ver ${_versions})
+ list(APPEND _lib_list "${_library}-${_ver}")
+ list(APPEND _libd_list "${_library_d}-${_ver}")
+ endforeach()
+ else()
+ set(_lib_list ${_library})
+ set(_libd_list ${_library_d})
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "library list = ${_lib_list} and library debug list = ${_libd_list}")
+ endif()
+
+ # For some silly reason the MSVC libraries use _ instead of .
+ # in the version fields
+ if(_expand_vc AND MSVC)
+ set(_no_dots_lib_list)
+ set(_no_dots_libd_list)
+ foreach(_l ${_lib_list})
+ string(REPLACE "." "_" _no_dots_library ${_l})
+ list(APPEND _no_dots_lib_list ${_no_dots_library})
+ endforeach()
+ # And for debug
+ set(_no_dots_libsd_list)
+ foreach(_l ${_libd_list})
+ string(REPLACE "." "_" _no_dots_libraryd ${_l})
+ list(APPEND _no_dots_libd_list ${_no_dots_libraryd})
+ endforeach()
+
+ # Copy list back to original names
+ set(_lib_list ${_no_dots_lib_list})
+ set(_libd_list ${_no_dots_libd_list})
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "While searching for ${_var}, our proposed library list is ${_lib_list}")
+ endif()
+
+ find_library(${_var}
+ NAMES ${_lib_list}
+ PATHS
+ /opt/gnome/lib
+ /opt/gnome/lib64
+ /usr/openwin/lib
+ /usr/openwin/lib64
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ )
+
+ if(_expand_vc AND MSVC)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}")
+ endif()
+
+ find_library(${_var}_DEBUG
+ NAMES ${_libd_list}
+ PATHS
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ )
+
+ if(${_var} AND ${_var}_DEBUG)
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var}_DEBUG)
+ endif()
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG})
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ endif()
+ else()
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var})
+ endif()
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}})
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ # Set debug to release
+ set(${_var}_DEBUG ${${_var}})
+ set(${_var}_DEBUG ${${_var}} PARENT_SCOPE)
+ endif()
+endfunction(_GTK2_FIND_LIBRARY)
+
+#=============================================================
+
+#
+# main()
+#
+
+set(GTK2_FOUND)
+set(GTK2_INCLUDE_DIRS)
+set(GTK2_LIBRARIES)
+
+if(NOT GTK2_FIND_COMPONENTS)
+ # Assume they only want GTK
+ set(GTK2_FIND_COMPONENTS gtk)
+endif()
+
+#
+# If specified, enforce version number
+#
+if(GTK2_FIND_VERSION)
+ cmake_minimum_required(VERSION 2.6.2)
+ set(GTK2_FAILED_VERSION_CHECK true)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "Searching for version ${GTK2_FIND_VERSION}")
+ endif()
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
+ if(GTK2_GTK_INCLUDE_DIR)
+ _GTK2_GET_VERSION(GTK2_MAJOR_VERSION
+ GTK2_MINOR_VERSION
+ GTK2_PATCH_VERSION
+ ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
+ set(GTK2_VERSION
+ ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
+ if(GTK2_FIND_VERSION_EXACT)
+ if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION)
+ set(GTK2_FAILED_VERSION_CHECK false)
+ endif()
+ else()
+ if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION OR
+ GTK2_VERSION VERSION_GREATER GTK2_FIND_VERSION)
+ set(GTK2_FAILED_VERSION_CHECK false)
+ endif()
+ endif()
+ else()
+ # If we can't find the GTK include dir, we can't do version checking
+ if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
+ message(FATAL_ERROR "Could not find GTK2 include directory")
+ endif()
+ return()
+ endif()
+
+ if(GTK2_FAILED_VERSION_CHECK)
+ if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
+ if(GTK2_FIND_VERSION_EXACT)
+ message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, version ${GTK2_FIND_VERSION} is needed exactly.")
+ else()
+ message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, at least version ${GTK2_FIND_VERSION} is required")
+ endif()
+ endif()
+
+ # If the version check fails, exit out of the module here
+ return()
+ endif()
+endif()
+
+#
+# Find all components
+#
+
+foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
+ if(_GTK2_component STREQUAL "gtk")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true)
+ _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
+ _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-x11 false true)
+ _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-win32 false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h)
+ _GTK2_FIND_LIBRARY (GTK2_CAIRO_LIBRARY cairo false false)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h)
+ _GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h)
+ _GTK2_FIND_LIBRARY (GTK2_ATK_LIBRARY atk false true)
+
+ #elseif(_GTK2_component STREQUAL "gdk_pixbuf")
+ #_GTK2_FIND_INCLUDE_DIR(GTK2_GDKPIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
+ #_GTK2_FIND_LIBRARY (GTK2_GDKPIXBUF_LIBRARY gdk_pixbuf false true)
+
+ elseif(_GTK2_component STREQUAL "gtkmm")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GTKMM_LIBRARY gtkmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
+ _GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h)
+ _GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
+ _GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GIOMM_LIBRARY giomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h)
+ _GTK2_FIND_LIBRARY (GTK2_ATKMM_LIBRARY atkmm true true)
+
+ elseif(_GTK2_component STREQUAL "glade")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLADE_LIBRARY glade false true)
+
+ elseif(_GTK2_component STREQUAL "glademm")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM_INCLUDE_DIR libglademm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLADEMM_LIBRARY glademm true true)
+
+ else()
+ message(FATAL_ERROR "Unknown GTK2 component ${_component}")
+ endif()
+endforeach()
+
+#
+# Solve for the GTK2 version if we haven't already
+#
+if(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR)
+ _GTK2_GET_VERSION(GTK2_MAJOR_VERSION
+ GTK2_MINOR_VERSION
+ GTK2_PATCH_VERSION
+ ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
+ set(GTK2_VERSION ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
+endif()
+
+#
+# Try to enforce components
+#
+
+set(_GTK2_did_we_find_everything true) # This gets set to GTK2_FOUND
+
+include(FindPackageHandleStandardArgs)
+
+foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
+ string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER)
+
+ if(_GTK2_component STREQUAL "gtk")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found."
+ GTK2_GTK_LIBRARY
+ GTK2_GTK_INCLUDE_DIR
+
+ GTK2_GLIB_INCLUDE_DIR
+ GTK2_GLIBCONFIG_INCLUDE_DIR
+ GTK2_GLIB_LIBRARY
+
+ GTK2_GDK_INCLUDE_DIR
+ GTK2_GDKCONFIG_INCLUDE_DIR
+ GTK2_GDK_LIBRARY
+ )
+ elseif(_GTK2_component STREQUAL "gtkmm")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found."
+ GTK2_GTKMM_LIBRARY
+ GTK2_GTKMM_INCLUDE_DIR
+ GTK2_GTKMMCONFIG_INCLUDE_DIR
+
+ GTK2_GLIBMM_INCLUDE_DIR
+ GTK2_GLIBMMCONFIG_INCLUDE_DIR
+ GTK2_GLIBMM_LIBRARY
+
+ GTK2_GDKMM_INCLUDE_DIR
+ GTK2_GDKMMCONFIG_INCLUDE_DIR
+ GTK2_GDKMM_LIBRARY
+ )
+ elseif(_GTK2_component STREQUAL "glade")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found."
+ GTK2_GLADE_LIBRARY
+ GTK2_GLADE_INCLUDE_DIR
+ )
+ elseif(_GTK2_component STREQUAL "glademm")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glademm library was not found."
+ GTK2_GLADEMM_LIBRARY
+ GTK2_GLADEMM_INCLUDE_DIR
+ GTK2_GLADEMMCONFIG_INCLUDE_DIR
+ )
+ endif()
+
+ if(NOT GTK2_${_COMPONENT_UPPER}_FOUND)
+ set(_GTK2_did_we_find_everything false)
+ endif()
+endforeach()
+
+if(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED)
+ set(GTK2_FOUND true)
+else()
+ # Unset our variables.
+ set(GTK2_FOUND false)
+ set(GTK2_VERSION)
+ set(GTK2_VERSION_MAJOR)
+ set(GTK2_VERSION_MINOR)
+ set(GTK2_VERSION_PATCH)
+ set(GTK2_INCLUDE_DIRS)
+ set(GTK2_LIBRARIES)
+endif()
+
+if(GTK2_INCLUDE_DIRS)
+ list(REMOVE_DUPLICATES GTK2_INCLUDE_DIRS)
+endif()
+
diff --git a/cmake/FindGettext.cmake b/cmake/FindGettext.cmake
new file mode 100644
index 0000000..4f8e6fb
--- /dev/null
+++ b/cmake/FindGettext.cmake
@@ -0,0 +1,105 @@
+# - Find GNU gettext tools
+# This module looks for the GNU gettext tools. This module defines the
+# following values:
+# GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool.
+# GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool.
+# GETTEXT_FOUND: True if gettext has been found.
+#
+# Additionally it provides the following macros:
+# GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] file1 ... fileN )
+# This will create a target "${PROJECT_NAME}_translations" which will
+# convert the given input po files into the binary output mo file.
+# If the ALL option is used, the translations will also be created
+# when building the default target.
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+# Copyright 2010 Přemysl Janouch
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the Kitware nor the names of contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+# OF SUCH DAMAGE.
+#=============================================================================
+
+find_program (GETTEXT_MSGMERGE_EXECUTABLE msgmerge)
+
+find_program (GETTEXT_MSGFMT_EXECUTABLE msgfmt)
+
+macro (GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg)
+ # Make it a real variable, so we can modify it here.
+ set (_firstPoFile "${_firstPoFileArg}")
+
+ set (_gmoFiles)
+ get_filename_component (_potBasename ${_potFile} NAME_WE)
+ get_filename_component (_absPotFile ${_potFile} ABSOLUTE)
+
+ set (_addToAll)
+ if (${_firstPoFile} STREQUAL "ALL")
+ set (_addToAll "ALL")
+ set (_firstPoFile)
+ endif (${_firstPoFile} STREQUAL "ALL")
+
+ foreach (_currentPoFile ${_firstPoFile} ${ARGN})
+ get_filename_component (_absFile ${_currentPoFile} ABSOLUTE)
+ get_filename_component (_abs_PATH ${_absFile} PATH)
+ get_filename_component (_lang ${_absFile} NAME_WE)
+ set (_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo)
+
+ # msgmerge versions older than 0.11 don't actually support --update
+ # and --backup, let's try to workaround that (tested on 0.10.40).
+ execute_process (COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} -V
+ OUTPUT_VARIABLE _msgmergeVersion)
+ string (REGEX MATCH "0[.][0-9]+" _msgmergeVersion ${_msgmergeVersion})
+ if ("${_msgmergeVersion}" MATCHES "[.]10|[.][0-9]")
+ set (_msgmergeParams --quiet -s
+ ${_absFile} -o ${_absFile} ${_absPotFile})
+ else ("${_msgmergeVersion}" MATCHES "[.]10|[.][0-9]")
+ set (_msgmergeParams --quiet --update --backup=none -s
+ ${_absFile} ${_absPotFile})
+ endif ("${_msgmergeVersion}" MATCHES "[.]10|[.][0-9]")
+
+ add_custom_command (
+ OUTPUT ${_gmoFile}
+ COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} ${_msgmergeParams}
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile}
+ DEPENDS ${_absPotFile} ${_absFile}
+ )
+
+ install (FILES ${_gmoFile} DESTINATION
+ share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo)
+ set (_gmoFiles ${_gmoFiles} ${_gmoFile})
+ endforeach (_currentPoFile)
+
+ add_custom_target (${PROJECT_NAME}_translations ${_addToAll}
+ DEPENDS ${_gmoFiles})
+endmacro (GETTEXT_CREATE_TRANSLATIONS)
+
+if (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE)
+ set (GETTEXT_FOUND TRUE)
+else (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE)
+ set (GETTEXT_FOUND FALSE)
+ if (GetText_REQUIRED)
+ message (FATAL_ERROR "GetText not found")
+ endif (GetText_REQUIRED)
+endif (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE)
+
+
diff --git a/cmake/FindGtkDoc.cmake b/cmake/FindGtkDoc.cmake
new file mode 100644
index 0000000..97d849b
--- /dev/null
+++ b/cmake/FindGtkDoc.cmake
@@ -0,0 +1,366 @@
+# - Finding gtk-doc and building documentation
+# This module provides the following function:
+#
+# GTK_DOC_RUN (
+# [ALL]
+# [MODULE <module-name>]
+# [WORKING_DIR <working-dir>]
+# SOURCE_DIRS <source-dir> ...
+# [IGNORE_FILES <file> ...]
+# [{SGML | XML} [<mkdb-output-dir> [<mkdb-options>]]
+# [HTML <html-output-dir> <backend-options>]]
+# )
+#
+# The function creates a target named <module-name>_gtkdocize
+# which will build the documentation as specified by parameters.
+#
+# ALL - always build the target
+# MODULE - the name of the module
+# CMAKE_PROJECT_NAME by default
+# WORKING_DIR - path to the working directory
+# CMAKE_CURRENT_BINARY_DIR by default
+# SOURCE_DIRS - documentation sources
+# IGNORE_FILES - ignore these files in the process
+# SGML - make SGML output in the spec. directory
+# XML - make XML output in the spec. directory
+# HTML - make HTML output in the spec. directory
+# (requires either SGML or XML)
+#
+# Also creates these virtual symbolic outputs if appropriate:
+# <module-name>_gtkdocize_scan
+# <module-name>_gtkdocize_scan_rebuild_types
+# <module-name>_gtkdocize_scan_rebuild_sections
+# <module-name>_gtkdocize_mkdb
+# <module-name>_gtkdocize_mkhtml
+#
+#
+
+#=============================================================================
+# Copyright Přemysl Janouch 2010
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+# OF SUCH DAMAGE.
+#=============================================================================
+
+# Useful resources
+# ================
+#
+# /usr/share/cmake-2.8/Modules/readme.txt
+#
+# Autotools stack
+# - /usr/share/aclocal/gtk-doc.m4
+# - /usr/share/gtk-doc/data/gtk-doc{.notmpl}.make
+#
+# gtk+-2.0, glib-2.0, totem, ... packages -- docs subdir etc.
+#
+# Python wrapper -- useful resource
+# - http://bjourne.webfactional.com/browser/gtkimageview/gtkdoc.py
+#
+# Overview of the process
+# - http://library.gnome.org
+# /devel/gtk-doc-manual/stable/howdoesgtkdocwork.html.en
+#
+# Documenting
+# - http://live.gnome.org/DocumentationProject/GtkDoc
+# - http://library.gnome.org
+# /devel/gtk-doc-manual/stable/documenting_syntax.html.en
+# - http://library.gnome.org
+# /devel/gtk-doc-manual/stable/metafiles.html.en
+#
+# TODO
+# ====
+# - Since it doesn't work without the full Unix environment,
+# it might be actually proper to use pkg-config
+#
+# - <module-name>_gtkdocize_scangobj
+# - <module-name>_gtkdocize_mktmpl
+# - <module-name>_gtkdocize_fixxref
+# - Content files (included by the main SGML file)
+#
+
+
+find_program (GTK_DOC_SCAN_EXECUTABLE "gtkdoc-scan")
+find_program (GTK_DOC_SCANGOBJ_EXECUTABLE "gtkdoc-scangobj")
+find_program (GTK_DOC_MKTMPL_EXECUTABLE "gtkdoc-mktmpl")
+find_program (GTK_DOC_MKDB_EXECUTABLE "gtkdoc-mkdb")
+find_program (GTK_DOC_MKHTML_EXECUTABLE "gtkdoc-mkhtml")
+find_program (GTK_DOC_FIXXREF_EXECUTABLE "gtkdoc-fixxref")
+
+set (GTK_DOC_FOUND TRUE)
+if (NOT GTK_DOC_SCAN_EXECUTABLE)
+ set (GTK_DOC_FOUND FALSE)
+endif (NOT GTK_DOC_SCAN_EXECUTABLE)
+
+if (GtkDoc_FIND_REQUIRED AND NOT GTK_DOC_FOUND)
+ message (FATAL_ERROR "gtk-doc NOT found")
+endif (GtkDoc_FIND_REQUIRED AND NOT GTK_DOC_FOUND)
+
+
+include (ProcessArguments)
+
+function (GTK_DOC_RUN)
+ # Parse arguments given to this function
+ set (__names ALL MODULE WORKING_DIR)
+ set (__need NO NO NO)
+ set (__want 0 1 1)
+ set (__more NO NO NO)
+ set (__skip 0 0 0)
+
+ list (APPEND __names SOURCE_DIRS IGNORE_FILES SGML XML HTML)
+ list (APPEND __need YES NO NO NO NO)
+ list (APPEND __want 1 1 0 0 1)
+ list (APPEND __more YES YES YES YES YES)
+ list (APPEND __skip 0 0 1 0 0)
+
+ set (__argv ${ARGV})
+ PROCESS_ARGUMENTS (__argv __names __need __want __more __skip "_opt_")
+
+ # Further process the arguments
+ if (_opt_all)
+ set (_all ALL)
+ else (_opt_all)
+ set (_all)
+ endif (_opt_all)
+
+ if (_opt_module)
+ set (_module_name ${_opt_module_param})
+ else (_opt_module)
+ set (_module_name ${CMAKE_PROJECT_NAME})
+ endif (_opt_module)
+
+ if (_opt_working_dir)
+ set (_working_dir ${_opt_working_dir_param})
+ else (_opt_working_dir)
+ set (_working_dir ${CMAKE_CURRENT_BINARY_DIR})
+ endif (_opt_working_dir)
+
+ set (_source_dirs)
+ foreach (_dir ${_opt_source_dirs_param})
+ list (APPEND _source_dirs "--source-dir" "${_dir}")
+ endforeach (_dir ${_opt_source_dirs_param})
+
+ set (_ignores)
+ if (_opt_ignore_files)
+ foreach (_file ${_opt_ignore_files_param})
+ set (_ignores "${_ignores} ${_file}")
+ endforeach (_file ${_opt_ignore_files_param})
+ string (STRIP "${_ignores}" _ignores)
+ endif (_opt_ignore_files)
+
+ if (_opt_sgml)
+ set (_mkdb_format "sgml")
+ set (_mkdb_options "${_opt_sgml_param}")
+ elseif (_opt_xml)
+ set (_mkdb_format "xml")
+ set (_mkdb_options "${_opt_xml_param}")
+ else (_opt_sgml)
+ set (_mkdb_format OFF)
+ endif (_opt_sgml)
+
+ if (_mkdb_format)
+ set (_mkdb_driver ${_working_dir}/${_module_name}-docs.${_mkdb_format})
+ list (LENGTH _mkdb_options _length)
+ if (${_length} GREATER 0)
+ list (GET _mkdb_options 0 _mkdb_output_dir)
+ list (REMOVE_AT _mkdb_options 0)
+ else (${_length} GREATER 0)
+ set (_mkdb_output_dir ${_working_dir}/${_mkdb_format})
+ endif (${_length} GREATER 0)
+ endif (_mkdb_format)
+
+ # The basic target name
+ set (_target_name ${_module_name}_gtkdocize)
+
+ # Scan the source files
+ set (_scan_target_base
+ # These files are created if they don't exist
+ # ${_working_dir}/${_module_name}.types
+ # ${_working_dir}/${_module_name}-sections.txt
+ # ${_working_dir}/${_module_name}-overrides.txt
+ ${_working_dir}/${_module_name}-decl.txt
+ ${_working_dir}/${_module_name}-decl-list.txt
+ COMMAND ${GTK_DOC_SCAN_EXECUTABLE}
+ --module=${_module_name}
+ ${_source_dirs} "--ignore-headers=${_ignores}"
+ --output-dir=${_working_dir})
+ add_custom_command (
+ OUTPUT ${_target_name}_scan
+ ${_scan_target_base}
+ COMMENT "Calling gtkdoc-scan" VERBATIM)
+
+ # Special target to force rebuild of ${_module_name}.types
+ add_custom_command (
+ OUTPUT ${_target_name}_scan_rebuild_types
+ ${_scan_target_base} --rebuild-types
+ COMMENT "Calling gtkdoc-scan to rebuild types" VERBATIM)
+ add_custom_target (${_target_name}_rebuild_types
+ DEPENDS ${_target_name}_scan_rebuild_types)
+
+ # Special target to force rebuild of ${_module_name}-sections.txt
+ add_custom_command (
+ OUTPUT ${_target_name}_scan_rebuild_sections
+ ${_scan_target_base} --rebuild-sections
+ COMMENT "Calling gtkdoc-scan to rebuild sections" VERBATIM)
+ add_custom_target (${_target_name}_rebuild_sections
+ DEPENDS ${_target_name}_scan_rebuild_sections)
+
+ set_source_files_properties (
+ ${_target_name}_scan
+ ${_target_name}_scan_rebuild_types
+ ${_target_name}_scan_rebuild_sections
+ PROPERTIES SYMBOLIC TRUE)
+
+ # gtkdoc-scangobj
+ #
+ # gtkdoc-scangobj builds and runs an inspection program. You must
+ # tell it how to do that by running it
+ #
+ # CC=.. CFLAGS=.. LD=.. LDFLAGS=.. RUN=.. gtkdoc-scangobj
+ #
+ # where the variables contain the right compiler, linker and their flags
+ # to build a program using your library. See the source of
+ # gtkdoc-scangobj around line containing `Compiling scanner' if you want
+ # to know how exactly are the variables used.
+
+ # gtkdoc-mktmpl
+ #
+ # See: cd /usr/share/gtk-doc/data/
+ # && diff -u gtk-doc.make gtk-doc.notmpl.make
+ #
+ # add_custom_command (
+ # OUTPUT ${_working_dir}/${_module_name}-unused.txt
+ # ${_working_dir}/tmpl.stamp
+ ## This file is updated with unused templates
+ ## ${_tmpl_dir}/${_module_name}-unused.sgml
+ ## The directory is created if it didn't exist
+ ## ${_tmpl_dir}
+ # COMMAND ${GTK_DOC_MKTMPL_EXECUTABLE}
+ # --module=${_module_name}
+ # --output-dir=${_tmpl_dir}
+ # WORKING_DIRECTORY ${_working_dir}
+ # COMMENT "Calling gtkdoc-mktmpl" VERBATIM)
+
+ # Create XML or SGML files
+ if (_mkdb_format)
+ add_custom_command (
+ OUTPUT ${_target_name}_mkdb
+ ${_mkdb_output_dir}
+ ${_working_dir}/sgml.stamp
+ ${_working_dir}/${_module_name}-undeclared.txt
+ ${_working_dir}/${_module_name}-undocumented.txt
+ ${_working_dir}/${_module_name}-unused.txt
+ # --outputallsymbols --outputsymbolswithoutsince
+ # ${_working_dir}/${_module_name}-symbols.txt
+ # ${_working_dir}/${_module_name}-nosince.txt
+ COMMAND ${GTK_DOC_MKDB_EXECUTABLE}
+ --module=${_module_name}
+ ${_source_dirs} "--ignore-files=${_ignores}"
+ --output-format=${_mkdb_format}
+ --output-dir=${_mkdb_output_dir}
+ ${_mkdb_options} --main-sgml-file=${_mkdb_driver}
+ DEPENDS ${_target_name}_scan
+ WORKING_DIRECTORY ${_working_dir}
+ COMMENT "Calling gtkdoc-mkdb" VERBATIM)
+
+ set_source_files_properties (${_target_name}_mkdb
+ PROPERTIES SYMBOLIC TRUE)
+ set (_top_output ${_target_name}_mkdb)
+ else (_mkdb_format)
+ set (_top_output ${_target_name}_scan)
+ endif (_mkdb_format)
+
+ # Create HTML documentation
+ if (_opt_html)
+ if (NOT _mkdb_format)
+ message (FATAL_ERROR "Given HTML but neither XML nor SGML")
+ endif (NOT _mkdb_format)
+
+ list (GET _opt_html_param 0 _html_output_dir)
+ list (REMOVE_AT _opt_html_param 0)
+
+ add_custom_command (
+ OUTPUT ${_target_name}_mkhtml
+ ${_html_output_dir}/../html.stamp
+ # We probably don't want this to be removed either
+ # ${_html_output_dir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${_html_output_dir}
+ COMMAND ${CMAKE_COMMAND} -E chdir ${_html_output_dir}
+ ${GTK_DOC_MKHTML_EXECUTABLE}
+ ${_module_name} ${_mkdb_driver} ${_opt_html_param}
+ DEPENDS ${_target_name}_mkdb
+ COMMENT "Calling gtkdoc-mkhtml" VERBATIM)
+
+ set_source_files_properties (${_target_name}_mkhtml
+ PROPERTIES SYMBOLIC TRUE)
+ set (_top_output ${_target_name}_mkhtml)
+ endif (_opt_html)
+
+ # gtkdoc-fixxref
+ # ? copy ${_html_output_dir} to CMAKE_BINARY_DIR,
+ # run gtkdoc-fixxref in there and install the directory
+ # -> FIXXREF <output-dir> [INSTALL]
+ #
+ #? set (_fixxref_dir ${CMAKE_CURRENT_BINARY_DIR}/html-fixxref)
+ # add_custom_command (
+ # OUTPUT ${_target_name}_fixxref
+ #? ${_fixxref_dir}
+ #? COMMAND ${CMAKE_COMMAND} -E remove_directory ${_fixxref_dir}
+ #? COMMAND ${CMAKE_COMMAND} -E copy_directory
+ #? ${_html_output_dir} ${_fixxref_dir}
+ # COMMAND ${GTK_DOC_FIXXREF_EXECUTABLE}
+ # --module=${_module_name}
+ # --module-dir=${_html_output_dir}
+ #? --module-dir=${_fixxref_dir}
+ # DEPENDS ${_html_output_dir}
+ # WORKING_DIRECTORY ${_working_dir}
+ # COMMENT "Calling gtkdoc-fixxref" VERBATIM)
+ #? install (DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html-fixxref/
+ #? DESTINATION share/gtk-doc/html/${_module_name})
+ #& COMPONENT docs) -- see CPack component install
+
+ # gtkdoc-rebase -- how to do this?
+ #
+ # Probably omit this because source tarball cannot be hooked
+ # to do some action before.
+ # -> Custom dist target?
+ # add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
+ # -> ${_html_output_dir} could contain online links by default,
+ # then it could be copied to binary dir and rebased to relative
+ # * Looks like a very good idea, can work even without gtk-doc
+ # -> Or it can be first xreffed in the binary dir and then
+ # converted to online links in ${_html_output_dir}
+ # * Which one of those should be installed?
+ # The one in the binary directory or should the
+ # ${_html_output_dir} be rebased?
+ # * A rebasing custom command may create the binary directory
+ # if it doesn't exist
+ #
+ # When creating the source tarball for distribution,
+ # gtkdoc-rebase turns all external links into web-links.
+ # When installing distributed (pregenerated) docs the same
+ # application will try to turn links back to local links
+ # (where those docs are installed).
+
+ add_custom_target (${_target_name} ${_all}
+ DEPENDS ${_top_output})
+endfunction (GTK_DOC_RUN)
+
+
diff --git a/cmake/ProcessArguments.cmake b/cmake/ProcessArguments.cmake
new file mode 100644
index 0000000..1fafe26
--- /dev/null
+++ b/cmake/ProcessArguments.cmake
@@ -0,0 +1,140 @@
+# - Parse the arguments in ARGS.
+# This module provides the following macro:
+# PROCESS_ARGUMENTS (ARGS NAMES NEED WANT MORE SKIP [PREFIX])
+#
+# ARGS - the list of arguments
+# NAMES - a list of accepted option names, in order
+# NEED - a list of boolean values specifying whether the corresponding
+# options are required
+# WANT - a list of integer values specifying how many arguments
+# the corresponding options require
+# MORE - a list of boolean values specifying whether the corresponding
+# options accept more arguments than they want
+# SKIP - a list of integer values for skipping control
+# PREFIX - output variables prefix, "_" by default
+#
+# If an option is present, ${PREFIX}${lower cased name of the option}
+# will be set to TRUE. If it's got any parameters, they will be stored
+# in ${PREFIX}${lower case name of the option}_param.
+#
+# All the lists are indirect and the arguments to this macro
+# specify names of the lists within the current scope.
+#
+
+#=============================================================================
+# Copyright Přemysl Janouch 2010
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+# OF SUCH DAMAGE.
+#=============================================================================
+
+macro (PROCESS_ARGUMENTS ARGS NAMES NEED WANT MORE SKIP)
+ # Get the prefix
+ if ("${ARGN}" STREQUAL "")
+ set (__pa_prefix "_")
+ else ("${ARGN}" STREQUAL "")
+ set (__pa_value ${ARGN})
+ list (GET __pa_value 0 __pa_prefix)
+ endif ("${ARGN}" STREQUAL "")
+
+ # By default, no parameters have been read
+ foreach (__pa_value ${${NAMES}})
+ string (TOLOWER ${__pa_value} __pa_value)
+ set (${__pa_prefix}${__pa_value} FALSE)
+ set (${__pa_prefix}${__pa_value}_param)
+ endforeach (__pa_value)
+
+ # Find the first required option or -1
+ list (FIND ${NEED} "YES" __pa_need)
+
+ # Currently processed option
+ set (__pa_cur "")
+ # Index of the option
+ set (__pa_cur_index -1)
+ # In lowercase, prefixed with an underscore
+ set (__pa_cur_base "")
+ # How many arguments we want for this option
+ set (__pa_want 0)
+ # Do we accept additional arguments?
+ set (__pa_more FALSE)
+ # The next expected index minus one
+ set (__pa_cur_nextmm -1)
+
+ foreach (__pa_arg ${${ARGS}})
+ list (FIND ${NAMES} ${__pa_arg} __pa_found)
+
+ # Found an option name
+ if (${__pa_found} GREATER ${__pa_cur_nextmm})
+ # Missing arguments
+ if (${__pa_want} GREATER 0)
+ message (FATAL_ERROR "Argument(s) required for ${__pa_cur}")
+ # Missing option
+ elseif (${__pa_need} GREATER -1
+ AND ${__pa_found} GREATER ${__pa_need})
+ list (GET ${NAMES} ${__pa_need} __pa_value)
+ message (FATAL_ERROR "Option ${__pa_value} needed")
+ endif (${__pa_want} GREATER 0)
+
+ set (__pa_cur ${__pa_arg})
+ set (__pa_cur_index ${__pa_found})
+ string (TOLOWER ${__pa_arg} __pa_value)
+ set (__pa_cur_base "${__pa_prefix}${__pa_value}")
+
+ list (GET ${WANT} ${__pa_found} __pa_want)
+ list (GET ${MORE} ${__pa_found} __pa_more)
+
+ # Skipping control
+ list (GET ${SKIP} ${__pa_found} __pa_value)
+ math (EXPR __pa_cur_nextmm "${__pa_found} + ${__pa_value}")
+
+ # Option found
+ set (${__pa_cur_base} TRUE)
+
+ # Since we read it, it's not needed anymore
+ if (${__pa_found} EQUAL ${__pa_need})
+ list (INSERT ${NEED} ${__pa_need} "NO")
+ math (EXPR __pa_value "${__pa_need} + 1")
+ list (REMOVE_AT ${NEED} ${__pa_value})
+
+ list (FIND ${NEED} "YES" __pa_need)
+ endif (${__pa_found} EQUAL ${__pa_need})
+ # Storing the required parameters for the current option
+ elseif (${__pa_want} GREATER 0)
+ list (APPEND ${__pa_cur_base}_param ${__pa_arg})
+ math (EXPR __pa_want "${__pa_want} - 1")
+ # Storing optional parameters for the current option
+ elseif (__pa_more)
+ list (APPEND ${__pa_cur_base}_param ${__pa_arg})
+ else (${__pa_found} GREATER ${__pa_cur_nextmm})
+ message (FATAL_ERROR "Unexpected ${__pa_arg}")
+ endif (${__pa_found} GREATER ${__pa_cur_nextmm})
+ endforeach (__pa_arg ${${ARGS}})
+
+ # Missing arguments at the end of list
+ if (${__pa_want} GREATER 0)
+ message (FATAL_ERROR "Argument(s) required for ${__pa_cur}")
+ # Missing options at the end of list
+ elseif (${__pa_need} GREATER -1)
+ list (GET ${NAMES} ${__pa_need} __pa_value)
+ message (FATAL_ERROR "Option ${__pa_value} needed")
+ endif (${__pa_want} GREATER 0)
+endmacro (PROCESS_ARGUMENTS)
+
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..19a43db
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,84 @@
+/**
+ * @file configure.h.in
+ * @brief Tries to fix various differences in compilers and libraries.
+ *
+ */
+
+#ifndef CONFIGURE_H_INCLUDED
+#define CONFIGURE_H_INCLUDED
+
+#define PROJECT_NAME "${PROJECT_NAME}"
+#define PROJECT_VERSION "${project_VERSION}"
+
+#if ${OPTION_NOINSTALL}
+ /* For developers. */
+ #define PROJECT_SHARE_DIR "${CMAKE_SOURCE_DIR}/share/"
+#else
+ #define PROJECT_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/"
+#endif
+
+
+#cmakedefine HAVE_SANE___RESTRICT
+#cmakedefine HAVE_RESTRICT
+
+#cmakedefine HAVE_SNPRINTF
+#cmakedefine HAVE_SPRINTF_S
+
+#cmakedefine HAVE_STRDUP
+#cmakedefine HAVE__STRDUP
+
+#cmakedefine HAVE_STRTOK_R
+#cmakedefine HAVE_STRTOK_S
+#cmakedefine HAVE_THREADSAFE_STRTOK
+
+#cmakedefine HAVE_GETTEXT
+
+
+#define Q_(s) (s)
+#ifdef HAVE_GETTEXT
+ #include <locale.h>
+ #include <libintl.h>
+ #define _(s) gettext(s)
+ #define N_(s1, s2, n) ngettext(s1, s2, n)
+
+ #define GETTEXT_DOMAIN "${PROJECT_NAME}"
+ #define GETTEXT_DIRNAME "${CMAKE_INSTALL_PREFIX}/share/locale"
+#else /* ! HAVE_GETTEXT */
+ #define _(s) (s)
+ #define N_(s1, s2, n) ((n) == 1 ? (s1) : (s2))
+#endif /* ! HAVE_GETTEXT */
+
+
+#ifndef HAVE_SANE___RESTRICT
+ #ifdef HAVE_RESTRICT
+ #define __restrict restrict
+ #else
+ #define __restrict
+ #endif
+#endif /* ! HAVE_SANE___RESTRICT */
+
+#ifndef HAVE_SNPRINTF
+ #ifdef HAVE_SPRINTF_S
+ #define snprintf sprintf_s
+ #endif
+#endif /* ! HAVE_SPRINTF */
+
+#ifdef HAVE__STRDUP
+ #define strdup _strdup
+#elif !defined(HAVE_STRDUP)
+static inline char *strdup (char *s)
+{
+ return strcpy(malloc(strlen(s) + 1), s);
+}
+#endif /* HAVE_STRDUP */
+
+#ifndef HAVE_STRTOK_R
+ #ifdef HAVE_STRTOK_S
+ #define strtok_r strtok_s
+ #elif defined(HAVE_THREADSAFE_STRTOK)
+ #define strtok_r(a, b, c) strtok(a, b)
+ #endif
+#endif /* ! HAVE_STRTOK_R */
+
+#endif /* CONFIGURE_H_INCLUDED */
+
diff --git a/po/logdiag.pot b/po/logdiag.pot
new file mode 100644
index 0000000..7f375e2
--- /dev/null
+++ b/po/logdiag.pot
@@ -0,0 +1,23 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Přemysl Janouch
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: logdiag \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-07-05 23:23+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../src/window-main.c:102
+#, c-format
+msgid "Building UI failed: %s"
+msgstr ""
diff --git a/po/make-template.sh b/po/make-template.sh
new file mode 100755
index 0000000..e688847
--- /dev/null
+++ b/po/make-template.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# This script makes a translation template
+# The reason for this not being inside CMakeLists.txt
+# is that the translator should not need to run
+# the whole configure process to get this single stupid file.
+
+# Get the package name from CMakeLists.txt
+PACKAGE=$(sed -n '/^[ \t]*[pP][rR][oO][jJ][eE][cC][tT][ \t]*([ \t]*\([^ \t)]\{1,\}\).*).*/{s//\1/p;q}' \
+ ../CMakeLists.txt)
+
+# Get the package version from CMakeLists.txt
+EXP_BEG='/^[ \t]*[sS][eE][tT][ \t]*([ \t]*'$PACKAGE'_VERSION_'
+EXP_END='[ \t]\{1,\}"\{0,1\}\([^)"]\{1,\}\)"\{0,1\}).*/{s//\1/p;q}'
+
+MAJOR=$(sed -n "${EXP_BEG}MAJOR${EXP_END}" ../CMakeLists.txt)
+MINOR=$(sed -n "${EXP_BEG}MINOR${EXP_END}" ../CMakeLists.txt)
+PATCH=$(sed -n "${EXP_BEG}PATCH${EXP_END}" ../CMakeLists.txt)
+
+if [ "$MAJOR" != "" ]; then
+ VERSION=$MAJOR
+ if [ "$MINOR" != "" ]; then
+ VERSION=$VERSION.$MINOR
+ if [ "$PATCH" != "" ]; then
+ VERSION=$VERSION.$PATCH
+ fi
+ fi
+fi
+
+# Finally make the template
+xgettext -LC -k_ -kN_:1,2 -kG_ ../src/*.c -o "$PACKAGE".pot \
+ --package-name="$PACKAGE" --package-version="$VERSION" \
+ --copyright-holder="Přemysl Janouch"
+
diff --git a/share/gui/window-main.ui b/share/gui/window-main.ui
new file mode 100644
index 0000000..bf36570
--- /dev/null
+++ b/share/gui/window-main.ui
@@ -0,0 +1,26 @@
+<ui>
+ <menubar name="MenuBar">
+ <menu name="FileMenu" action="FileMenu">
+ <menuitem action="New" />
+ <menuitem action="Open" />
+ <menuitem action="Save" />
+ <menuitem action="SaveAs" />
+ <separator />
+ <menuitem action="Export" />
+ <separator />
+ <menuitem action="Quit" />
+ </menu>
+ <menu name="EditMenu" action="EditMenu">
+ <menuitem action="Cut" />
+ <menuitem action="Copy" />
+ <menuitem action="Paste" />
+ <menuitem action="Delete" />
+ <separator />
+ <menuitem action="SelectAll" />
+ </menu>
+ <menu name="HelpMenu" action="HelpMenu">
+ <menuitem action="About" />
+ </menu>
+ </menubar>
+</ui>
+
diff --git a/share/logdiag.desktop b/share/logdiag.desktop
new file mode 100644
index 0000000..950df59
--- /dev/null
+++ b/share/logdiag.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Type=Application
+Name=logdiag %f
+GenericName=Electric diagrams designer
+GenericName[cs]=Návrhář elektrických diagramů
+Icon=logdiag
+Exec=logdiag
+Categories=Graphics;VectorGraphics;Electricity;Engineering;GTK
+
diff --git a/src/canvas.c b/src/canvas.c
new file mode 100644
index 0000000..7febdb3
--- /dev/null
+++ b/src/canvas.c
@@ -0,0 +1 @@
+/* http://www.gnomejournal.org/article/34/writing-a-widget-using-cairo-and-gtk28 */
diff --git a/src/canvas.h b/src/canvas.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/canvas.h
diff --git a/src/document.c b/src/document.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/document.c
diff --git a/src/document.h b/src/document.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/document.h
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..ed0dfb7
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,40 @@
+/*
+ * main.c -- logdiag main source file.
+ *
+ * This file is a part of logdiag.
+ * Copyright Přemysl Janouch 2010. All rights reserved.
+ *
+ * See the file LICENSE for licensing information.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <stdlib.h>
+
+#include "config.h"
+
+#include "window-main.h"
+
+
+int main (int argc, char *argv[])
+{
+ GtkWidget *wnd;
+
+#ifdef HAVE_GETTEXT
+ setlocale (LC_ALL, "");
+
+ bindtextdomain (GETTEXT_DOMAIN, GETTEXT_DIRNAME);
+ textdomain (GETTEXT_DOMAIN);
+#endif
+
+ /* For custom command line arguments, see:
+ * http://git.gnome.org/browse/glade3/tree/src/main.c
+ */
+
+ gtk_init (&argc, &argv);
+ wnd = logdiag_window_main_new ();
+ gtk_main ();
+
+ return 0;
+}
+
diff --git a/src/symbol-category.h b/src/symbol-category.h
new file mode 100644
index 0000000..bb0a6de
--- /dev/null
+++ b/src/symbol-category.h
@@ -0,0 +1,69 @@
+/*
+ * symbol-category.h
+ *
+ * This file is a part of logdiag.
+ * Copyright Přemysl Janouch 2010. All rights reserved.
+ *
+ * See the file LICENSE for licensing information.
+ *
+ */
+
+#ifndef __SYMBOL_CATEGORY_H__
+#define __SYMBOL_CATEGORY_H__
+
+G_BEGIN_DECLS
+
+
+#define LOGDIAG_TYPE_SYMBOL_CATEGORY (logdiag_symbol_category_get_type ())
+#define LOGDIAG_SYMBOL_CATEGORY(obj) (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), LOGDIAG_TYPE_SYMBOL_CATEGORY, LogdiagSymbolCategory))
+#define LOGDIAG_SYMBOL_CATEGORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST \
+ ((klass), LOGDIAG_TYPE_SYMBOL_CATEGORY, LogdiagSymbolCategoryClass))
+#define LOGDIAG_IS_SYMBOL_CATEGORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), LOGDIAG_TYPE_SYMBOL_CATEGORY))
+#define LOGDIAG_IS_SYMBOL_CATEGORY_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((klass), LOGDIAG_TYPE_SYMBOL_CATEGORY))
+#define LOGDIAG_SYMBOL_CATEGORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), LOGDIAG_SYMBOL_CATEGORY, LogdiagSymbolCategoryClass))
+
+typedef struct _LogdiagSymbolCategory LogdiagSymbolCategory;
+/*typedef struct _LogdiagSymbolCategoryPrivate LogdiagSymbolCategoryPrivate;*/
+typedef struct _LogdiagSymbolCategoryClass LogdiagSymbolCategoryClass;
+
+
+/**
+ * LogdiagSymbolCategory:
+ * @parent: The parent object, may be LogdiagSymbolLibrary
+ * or another LogdiagSymbolCategory.
+ * @name: The name of the category.
+ * @image_path: Path to the image of the category.
+ * @children: Children of this category.
+ */
+struct _LogdiagSymbolCategory
+{
+/*< private >*/
+ GObject parent_instance;
+
+/*< public >*/
+ gpointer parent;
+ char *name;
+ char *image_path;
+ GHashTable *children;
+};
+
+struct _LogdiagSymbolCategoryClass
+{
+ GtkObjectClass parent_class;
+};
+
+
+GType logdiag_symbol_category_get_type (void) G_GNUC_CONST;
+
+LogdiagSymbolCategory *
+logdiag_symbol_category_new (LogdiagSymbolLibrary *parent);
+
+
+G_END_DECLS
+
+#endif /* ! __SYMBOL_CATEGORY_H__ */
+
diff --git a/src/symbol-library.c b/src/symbol-library.c
new file mode 100644
index 0000000..3f4e078
--- /dev/null
+++ b/src/symbol-library.c
@@ -0,0 +1,307 @@
+/*
+ * symbol-library.c
+ *
+ * This file is a part of logdiag.
+ * Copyright Přemysl Janouch 2010. All rights reserved.
+ *
+ * See the file LICENSE for licensing information.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <lua.h>
+/* #include <lauxlib.h> */
+#include <stdlib.h>
+
+#include "config.h"
+
+#include "symbol-library.h"
+#include "symbol-category.h"
+#include "symbol.h"
+
+/* ===== Symbol library ==================================================== */
+
+/**
+ * SECTION:symbol-library
+ * @short_description: A symbol library.
+ * @see_also: #LogdiagSymbol, #LogdiagSymbolCategory
+ *
+ * #LogdiagSymbolLibrary is used for loading symbols from their files.
+ */
+
+/*
+ * LogdiagSymbolLibraryPrivate:
+ * @lua_state: Lua state.
+ */
+struct _LogdiagSymbolLibraryPrivate
+{
+ lua_State *lua_state;
+};
+
+G_DEFINE_TYPE (LogdiagSymbolLibrary, logdiag_symbol_library, G_TYPE_OBJECT);
+
+static void
+logdiag_symbol_library_finalize (GObject *gobject);
+
+
+static void
+logdiag_symbol_library_class_init (LogdiagSymbolLibraryClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = logdiag_symbol_library_finalize;
+
+/**
+ * LogdiagSymbolLibrary::changed:
+ * @library: The library object.
+ *
+ * Contents of the library have changed.
+ */
+ klass->changed_signal = g_signal_new
+ ("changed", G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ g_type_class_add_private (klass, sizeof (LogdiagSymbolLibraryPrivate));
+}
+
+static void
+logdiag_symbol_library_init (LogdiagSymbolLibrary *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE
+ (self, LOGDIAG_TYPE_SYMBOL_LIBRARY, LogdiagSymbolLibraryPrivate);
+
+ /* TODO: lua */
+ self->priv->lua_state = NULL;
+
+ /* TODO: use _new_full and specify destroy functions. */
+ self->categories = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+static void
+logdiag_symbol_library_finalize (GObject *gobject)
+{
+ LogdiagSymbolLibrary *self;
+
+ self = LOGDIAG_SYMBOL_LIBRARY (gobject);
+
+ g_hash_table_destroy (self->categories);
+
+ /* Chain up to the parent class. */
+ G_OBJECT_CLASS (logdiag_symbol_library_parent_class)->finalize (gobject);
+}
+
+/**
+ * logdiag_symbol_library_new:
+ *
+ * Create an instance.
+ */
+LogdiagSymbolLibrary *
+logdiag_symbol_library_new (void)
+{
+ return g_object_new (LOGDIAG_TYPE_SYMBOL_LIBRARY, NULL);
+}
+
+/*
+ * load_category:
+ * @self: A symbol library object.
+ * @path: The path to the category.
+ * @name: The default name of the category.
+ *
+ * Loads a category into the library.
+ */
+LogdiagSymbolCategory *
+load_category (LogdiagSymbolLibrary *self, const char *path, const char *name)
+{
+ LogdiagSymbolCategory *cat;
+ gchar *icon_file;
+
+ g_return_val_if_fail (LOGDIAG_IS_SYMBOL_LIBRARY (self), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ icon_file = g_build_filename (path, "icon.svg", NULL);
+ if (!g_file_test (icon_file, G_FILE_TEST_IS_REGULAR))
+ {
+ g_warning ("The category in %s has no icon.", path);
+ g_free (icon_file);
+ return NULL;
+ }
+
+ /* TODO: Search for category.json and read the category name from it. */
+ /* TODO: Search for xyz.lua and load the objects into the category. */
+
+ cat = logdiag_symbol_category_new (self);
+ cat->name = g_strdup (name);
+ cat->image_path = icon_file;
+ return cat;
+}
+
+/**
+ * logdiag_symbol_library_load:
+ * @self: A symbol library object.
+ * @directory: A directory to be loaded.
+ *
+ * Load the contents of a directory into the library.
+ */
+gboolean
+logdiag_symbol_library_load (LogdiagSymbolLibrary *self, const char *path)
+{
+ GDir *dir;
+ const gchar *item;
+
+ g_return_val_if_fail (LOGDIAG_IS_SYMBOL_LIBRARY (self), FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ dir = g_dir_open (path, 0, NULL);
+ if (!dir)
+ return FALSE;
+
+ while ((item = g_dir_read_name (dir)))
+ {
+ LogdiagSymbolCategory *cat;
+ gchar *categ_path;
+
+ categ_path = g_build_filename (path, item, NULL);
+ cat = load_category (self, categ_path, item);
+ if (cat)
+ g_hash_table_insert (self->categories, cat->name, cat);
+ g_free (categ_path);
+ }
+ g_dir_close (dir);
+ return TRUE;
+}
+
+/**
+ * logdiag_symbol_library_clear:
+ *
+ * Clears all the contents.
+ */
+void
+logdiag_symbol_library_clear (LogdiagSymbolLibrary *self)
+{
+ g_return_if_fail (LOGDIAG_IS_SYMBOL_LIBRARY (self));
+
+ g_hash_table_remove_all (self->categories);
+ return;
+}
+
+
+/* ===== Symbol category =================================================== */
+
+/**
+ * SECTION:symbol-category
+ * @short_description: A category of symbols.
+ * @see_also: #LogdiagSymbol, #LogdiagSymbolLibrary
+ *
+ * #LogdiagSymbolCategory represents a category of #LogdiagSymbol objects.
+ */
+
+G_DEFINE_TYPE (LogdiagSymbolCategory, logdiag_symbol_category, G_TYPE_OBJECT);
+
+static void
+logdiag_symbol_category_finalize (GObject *gobject);
+
+
+static void
+logdiag_symbol_category_class_init (LogdiagSymbolCategoryClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = logdiag_symbol_category_finalize;
+}
+
+static void
+logdiag_symbol_category_init (LogdiagSymbolCategory *self)
+{
+ /* TODO: use _new_full, correct equal and specify destroy functions. */
+ /* XXX: How's the situation with subcategory names and symbol names
+ * within the same hashtable?
+ */
+ self->children = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+static void
+logdiag_symbol_category_finalize (GObject *gobject)
+{
+ LogdiagSymbolCategory *self;
+
+ self = LOGDIAG_SYMBOL_CATEGORY (gobject);
+
+ if (self->name)
+ g_free (self->name);
+ if (self->image_path)
+ g_free (self->image_path);
+
+ g_object_unref (self->parent);
+ g_hash_table_destroy (self->children);
+
+ /* Chain up to the parent class. */
+ G_OBJECT_CLASS (logdiag_symbol_category_parent_class)->finalize (gobject);
+}
+
+/**
+ * logdiag_symbol_category_new:
+ *
+ * Create an instance.
+ */
+LogdiagSymbolCategory *
+logdiag_symbol_category_new (LogdiagSymbolLibrary *parent)
+{
+ LogdiagSymbolCategory *cat;
+
+ cat = g_object_new (LOGDIAG_TYPE_SYMBOL_CATEGORY, NULL);
+
+ cat->parent = parent;
+ g_object_ref (parent);
+
+ return cat;
+}
+
+
+/* ===== Symbol ============================================================ */
+
+/**
+ * SECTION:symbol
+ * @short_description: A symbol.
+ * @see_also: #LogdiagDocument, #LogdiagCanvas
+ *
+ * #LogdiagSymbol represents a symbol in the #LogdiagDocument that is in turn
+ * drawn onto the #LogdiagCanvas.
+ */
+
+/*
+ * LogdiagSymbolPrivate:
+ * @parent_library: The parent LogdiagSymbolLibrary.
+ * The library contains the real function for rendering.
+ */
+struct _LogdiagSymbolPrivate
+{
+ LogdiagSymbolLibrary *parent_library;
+};
+
+/**
+ * logdiag_symbol_build_identifier:
+ *
+ * Build an identifier for the symbol.
+ * The identifier is in the format "Category/Category/Symbol".
+ */
+char *
+logdiag_symbol_build_identifier (LogdiagSymbol *self)
+{
+ return NULL;
+}
+
+/**
+ * logdiag_symbol_draw:
+ *
+ * Draw the symbol onto a Cairo surface.
+ */
+void
+logdiag_symbol_draw (LogdiagSymbol *self, cairo_t *surface,
+ GHashTable *param, gint x, gint y, gdouble zoom)
+{
+ return;
+}
diff --git a/src/symbol-library.h b/src/symbol-library.h
new file mode 100644
index 0000000..5091453
--- /dev/null
+++ b/src/symbol-library.h
@@ -0,0 +1,69 @@
+/*
+ * symbol-library.h
+ *
+ * This file is a part of logdiag.
+ * Copyright Přemysl Janouch 2010. All rights reserved.
+ *
+ * See the file LICENSE for licensing information.
+ *
+ */
+
+#ifndef __SYMBOL_LIBRARY_H__
+#define __SYMBOL_LIBRARY_H__
+
+G_BEGIN_DECLS
+
+
+#define LOGDIAG_TYPE_SYMBOL_LIBRARY (logdiag_symbol_library_get_type ())
+#define LOGDIAG_SYMBOL_LIBRARY(obj) (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), LOGDIAG_TYPE_SYMBOL_LIBRARY, LogdiagSymbolLibrary))
+#define LOGDIAG_SYMBOL_LIBRARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST \
+ ((klass), LOGDIAG_TYPE_SYMBOL_LIBRARY, LogdiagSymbolLibraryClass))
+#define LOGDIAG_IS_SYMBOL_LIBRARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), LOGDIAG_TYPE_SYMBOL_LIBRARY))
+#define LOGDIAG_IS_SYMBOL_LIBRARY_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((klass), LOGDIAG_TYPE_SYMBOL_LIBRARY))
+#define LOGDIAG_SYMBOL_LIBRARY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), LOGDIAG_SYMBOL_LIBRARY, LogdiagSymbolLibraryClass))
+
+typedef struct _LogdiagSymbolLibrary LogdiagSymbolLibrary;
+typedef struct _LogdiagSymbolLibraryPrivate LogdiagSymbolLibraryPrivate;
+typedef struct _LogdiagSymbolLibraryClass LogdiagSymbolLibraryClass;
+
+
+/**
+ * LogdiagSymbolLibrary:
+ * @categories: Lists all the categories (#LogdiagSymbolCategory).
+ *
+ * Object structure.
+ */
+struct _LogdiagSymbolLibrary
+{
+/*< private >*/
+ GObject parent_instance;
+ LogdiagSymbolLibraryPrivate *priv;
+
+/*< public >*/
+ GHashTable *categories;
+};
+
+struct _LogdiagSymbolLibraryClass
+{
+/*< private >*/
+ GObjectClass parent_class;
+ guint changed_signal;
+};
+
+
+GType logdiag_symbol_library_get_type (void) G_GNUC_CONST;
+
+LogdiagSymbolLibrary *logdiag_symbol_library_new (void);
+gboolean logdiag_symbol_library_load (LogdiagSymbolLibrary *self,
+ const char *directory);
+void logdiag_symbol_library_clear (LogdiagSymbolLibrary *self);
+
+
+G_END_DECLS
+
+#endif /* ! __SYMBOL_LIBRARY_H__ */
+
diff --git a/src/symbol.h b/src/symbol.h
new file mode 100644
index 0000000..c8f851f
--- /dev/null
+++ b/src/symbol.h
@@ -0,0 +1,69 @@
+/*
+ * symbol.h
+ *
+ * This file is a part of logdiag.
+ * Copyright Přemysl Janouch 2010. All rights reserved.
+ *
+ * See the file LICENSE for licensing information.
+ *
+ */
+
+#ifndef __SYMBOL_H__
+#define __SYMBOL_H__
+
+G_BEGIN_DECLS
+
+
+#define LOGDIAG_TYPE_SYMBOL (logdiag_symbol_get_type ())
+#define LOGDIAG_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), LOGDIAG_TYPE_SYMBOL, LogdiagSymbol))
+#define LOGDIAG_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST \
+ ((klass), LOGDIAG_TYPE_SYMBOL, LogdiagSymbolClass))
+#define LOGDIAG_IS_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), LOGDIAG_TYPE_SYMBOL))
+#define LOGDIAG_IS_SYMBOL_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((klass), LOGDIAG_TYPE_SYMBOL))
+#define LOGDIAG_SYMBOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), LOGDIAG_SYMBOL, LogdiagSymbolClass))
+
+typedef struct _LogdiagSymbol LogdiagSymbol;
+/*typedef struct _LogdiagSymbolPrivate LogdiagSymbolPrivate;*/
+typedef struct _LogdiagSymbolClass LogdiagSymbolClass;
+
+
+/**
+ * LogdiagSymbol:
+ * @parent: The parent category.
+ * @name: The name of this symbol.
+ */
+struct _LogdiagSymbol
+{
+/*< private >*/
+ GObject parent_instance;
+/* LogdiagSymbolPrivate *priv;*/
+
+/*< public >*/
+ LogdiagSymbolCategory *parent;
+ char *name;
+};
+
+struct _LogdiagSymbolClass
+{
+ GtkObjectClass parent_class;
+};
+
+
+GType logdiag_symbol_get_type (void) G_GNUC_CONST;
+
+char *logdiag_symbol_build_identifier (LogdiagSymbol *self);
+void logdiag_symbol_draw (LogdiagSymbol *self, cairo_t *surface,
+ GHashTable *param, gint x, gint y, gdouble zoom);
+
+/* TODO: Funkce pro získání terminálů. */
+
+
+
+G_END_DECLS
+
+#endif /* ! __SYMBOL_H__ */
+
diff --git a/src/window-main.c b/src/window-main.c
new file mode 100644
index 0000000..a34d5ed
--- /dev/null
+++ b/src/window-main.c
@@ -0,0 +1,283 @@
+/*
+ * window-main.c
+ *
+ * This file is a part of logdiag.
+ * Copyright Přemysl Janouch 2010. All rights reserved.
+ *
+ * See the file LICENSE for licensing information.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "window-main.h"
+#include "symbol-library.h"
+
+
+/**
+ * SECTION:window-main
+ * @short_description: The main application window.
+ *
+ * #LogdiagWindowMain is the main window of the application.
+ */
+/* NOTE: The main window should not maybe be included in either
+ * the documentation or the static library.
+ */
+
+
+/* Private members of the window. */
+struct _LogdiagWindowMainPrivate
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *menu;
+ GtkWidget *toolbar;
+
+ LogdiagSymbolLibrary *library;
+
+ GtkWidget *statusbar;
+ guint statusbar_menu_context_id;
+};
+
+/* Define the type. */
+G_DEFINE_TYPE (LogdiagWindowMain, logdiag_window_main, GTK_TYPE_WINDOW);
+
+
+/*
+ * cb_ui_proxy_connected:
+ *
+ * An item was connected to the manager.
+ */
+static void
+cb_ui_proxy_connected (GtkUIManager *ui, GtkAction *action,
+ GtkWidget *proxy, LogdiagWindowMain *window);
+
+/*
+ * cb_ui_proxy_disconnected:
+ *
+ * An item was disconnected from the manager.
+ */
+static void
+cb_ui_proxy_disconnected (GtkUIManager *ui, GtkAction *action,
+ GtkWidget *proxy, LogdiagWindowMain *window);
+
+/* A menu item was selected. */
+static void
+cb_menu_item_selected (GtkWidget *item, LogdiagWindowMain *window);
+
+/* A menu item was deselected. */
+static void
+cb_menu_item_deselected (GtkItem *item, LogdiagWindowMain *window);
+
+/* Show the about dialog. */
+static void
+cb_show_about_dialog (GtkAction *action, LogdiagWindowMain *window);
+
+
+/* Actions for menus, toolbars, accelerators. */
+static GtkActionEntry mw_actionEntries[] =
+{
+ {"FileMenu", NULL, Q_("_File")},
+ {"New", GTK_STOCK_NEW, NULL, NULL,
+ Q_("Create a new document"), NULL},
+ {"Open", GTK_STOCK_OPEN, NULL, NULL,
+ Q_("Open a document"), NULL},
+ {"Save", GTK_STOCK_SAVE, NULL, NULL,
+ Q_("Save the current document"), NULL},
+ {"SaveAs", GTK_STOCK_SAVE_AS, NULL, NULL,
+ Q_("Save the current document with another name"), NULL},
+ {"Export", NULL, Q_("_Export"), NULL,
+ Q_("Export the document"), NULL},
+ {"Quit", GTK_STOCK_QUIT, NULL, NULL,
+ Q_("Quit the program"), NULL},
+
+ {"EditMenu", NULL, Q_("_Edit")},
+ {"Cut", GTK_STOCK_CUT, NULL, NULL, NULL, NULL},
+ {"Copy", GTK_STOCK_COPY, NULL, NULL, NULL, NULL},
+ {"Paste", GTK_STOCK_PASTE, NULL, NULL, NULL, NULL},
+ {"Delete", GTK_STOCK_DELETE, NULL, NULL, NULL, NULL},
+ {"SelectAll", GTK_STOCK_SELECT_ALL, NULL, NULL, NULL, NULL},
+
+ {"HelpMenu", NULL, Q_("_Help")},
+ {"About", GTK_STOCK_ABOUT, NULL, NULL, NULL,
+ G_CALLBACK(cb_show_about_dialog)}
+};
+
+
+
+/**
+ * logdiag_window_main_new:
+ *
+ * Create an instance.
+ */
+GtkWidget *
+logdiag_window_main_new (void)
+{
+ return g_object_new (LOGDIAG_TYPE_WINDOW_MAIN, NULL);
+}
+
+static void
+logdiag_window_main_class_init (LogdiagWindowMainClass *klass)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (LogdiagWindowMainPrivate));
+}
+
+static void
+logdiag_window_main_init (LogdiagWindowMain *self)
+{
+ LogdiagWindowMainPrivate *priv;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ GError *error;
+
+ self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE
+ (self, LOGDIAG_TYPE_WINDOW_MAIN, LogdiagWindowMainPrivate);
+
+ priv->vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (self), priv->vbox);
+
+
+ ui_manager = gtk_ui_manager_new ();
+
+ /* TODO: Show tooltips in the statusbar:
+ * http://git.gnome.org/browse/glade3/tree/src/glade-window.c : 2165
+ */
+ g_signal_connect (ui_manager, "connect-proxy",
+ G_CALLBACK (cb_ui_proxy_connected), self);
+ g_signal_connect (ui_manager, "disconnect-proxy",
+ G_CALLBACK (cb_ui_proxy_disconnected), self);
+
+ /* Prepare our actions. */
+ action_group = gtk_action_group_new ("MainActions");
+ gtk_action_group_add_actions (action_group,
+ mw_actionEntries, G_N_ELEMENTS (mw_actionEntries), self);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+
+ error = NULL;
+ gtk_ui_manager_add_ui_from_file
+ (ui_manager, PROJECT_SHARE_DIR "gui/window-main.ui", &error);
+ if (error)
+ {
+ g_message (_("Building UI failed: %s"), error->message);
+ g_error_free (error);
+ }
+
+ /* Load keyboard accelerators into the window. */
+ gtk_window_add_accel_group
+ (GTK_WINDOW (self), gtk_ui_manager_get_accel_group (ui_manager));
+
+ priv->menu = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
+ gtk_box_pack_start (GTK_BOX (priv->vbox), priv->menu, FALSE, FALSE, 0);
+
+
+ priv->hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->vbox), priv->hbox, TRUE, TRUE, 0);
+
+ priv->toolbar = gtk_toolbar_new ();
+ /* NOTE: For GTK 2.16+, s/toolbar/orientable/ */
+ gtk_toolbar_set_orientation
+ (GTK_TOOLBAR (priv->toolbar), GTK_ORIENTATION_VERTICAL);
+ gtk_toolbar_set_icon_size
+ (GTK_TOOLBAR (priv->toolbar), GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_toolbar_set_style
+ (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_ICONS);
+
+ /* Symbol library. */
+ priv->library = logdiag_symbol_library_new ();
+ logdiag_symbol_library_load (priv->library, PROJECT_SHARE_DIR "library/");
+
+ /* TODO: Show contents of the library in the toolbar. */
+ GtkToolItem *item;
+ item = gtk_tool_button_new (/* icon widget */ NULL, _("Blah"));
+ gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), "network");
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), item, 0);
+ /* http://library.gnome.org/devel/gdk-pixbuf/unstable/ */
+
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->toolbar, FALSE, FALSE, 0);
+
+ /* TODO: GtkHPaned */
+
+ priv->statusbar = gtk_statusbar_new ();
+ priv->statusbar_menu_context_id = gtk_statusbar_get_context_id
+ (GTK_STATUSBAR (priv->statusbar), "menu");
+ gtk_box_pack_end (GTK_BOX (priv->vbox), priv->statusbar, FALSE, FALSE, 0);
+
+
+ /* Do this on disposal. */
+ /* g_object_unref(ui_manager); */
+
+ /* Proceed to showing the window. */
+ g_signal_connect (self, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_window_set_default_size (GTK_WINDOW (self), 500, 400);
+ gtk_widget_show_all (GTK_WIDGET (self));
+}
+
+static void
+cb_ui_proxy_connected (GtkUIManager *ui, GtkAction *action,
+ GtkWidget *proxy, LogdiagWindowMain *window)
+{
+ if (GTK_IS_MENU_ITEM (proxy))
+ {
+ g_signal_connect (proxy, "select",
+ G_CALLBACK (cb_menu_item_selected), window);
+ g_signal_connect (proxy, "deselect",
+ G_CALLBACK (cb_menu_item_deselected), window);
+ }
+}
+
+static void
+cb_ui_proxy_disconnected (GtkUIManager *ui, GtkAction *action,
+ GtkWidget *proxy, LogdiagWindowMain *window)
+{
+ if (GTK_IS_MENU_ITEM (proxy))
+ {
+ g_signal_handlers_disconnect_by_func
+ (proxy, G_CALLBACK (cb_menu_item_selected), window);
+ g_signal_handlers_disconnect_by_func
+ (proxy, G_CALLBACK (cb_menu_item_deselected), window);
+ }
+}
+
+static void
+cb_menu_item_selected (GtkWidget *item, LogdiagWindowMain *window)
+{
+ GtkAction *action;
+ gchar *tooltip;
+
+ action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (item));
+ g_object_get (G_OBJECT (action), "tooltip", &tooltip, NULL);
+
+ if (tooltip != NULL)
+ gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar),
+ window->priv->statusbar_menu_context_id, tooltip);
+
+ g_free (tooltip);
+}
+
+static void
+cb_menu_item_deselected (GtkItem *item, LogdiagWindowMain *window)
+{
+ gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar),
+ window->priv->statusbar_menu_context_id);
+}
+
+static void
+cb_show_about_dialog (GtkAction *action, LogdiagWindowMain *window)
+{
+ gtk_show_about_dialog (GTK_WINDOW (window),
+ "program-name", PROJECT_NAME,
+ "version", PROJECT_VERSION,
+ "copyright", "Copyright Přemysl Janouch 2010",
+ NULL);
+}
+
diff --git a/src/window-main.h b/src/window-main.h
new file mode 100644
index 0000000..28b3024
--- /dev/null
+++ b/src/window-main.h
@@ -0,0 +1,60 @@
+/*
+ * window-main.h
+ *
+ * This file is a part of logdiag.
+ * Copyright Přemysl Janouch 2010. All rights reserved.
+ *
+ * See the file LICENSE for licensing information.
+ *
+ */
+
+#ifndef __WINDOW_MAIN_H__
+#define __WINDOW_MAIN_H__
+
+G_BEGIN_DECLS
+
+
+#define LOGDIAG_TYPE_WINDOW_MAIN (logdiag_window_main_get_type ())
+#define LOGDIAG_WINDOW_MAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), LOGDIAG_TYPE_WINDOW_MAIN, LogdiagWindowMain))
+#define LOGDIAG_WINDOW_MAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST \
+ ((klass), LOGDIAG_TYPE_WINDOW_MAIN, LogdiagWindowMainClass))
+#define LOGDIAG_IS_WINDOW_MAIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), LOGDIAG_TYPE_WINDOW_MAIN))
+#define LOGDIAG_IS_WINDOW_MAIN_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((klass), LOGDIAG_TYPE_WINDOW_MAIN))
+#define LOGDIAG_WINDOW_MAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), LOGDIAG_WINDOW_MAIN, LogdiagWindowMainClass))
+
+typedef struct _LogdiagWindowMain LogdiagWindowMain;
+typedef struct _LogdiagWindowMainPrivate LogdiagWindowMainPrivate;
+typedef struct _LogdiagWindowMainClass LogdiagWindowMainClass;
+
+
+/**
+ * LogdiagWindowMain:
+ *
+ * Object structure.
+ */
+struct _LogdiagWindowMain
+{
+/*< private >*/
+ GtkWindow parent_instance;
+ LogdiagWindowMainPrivate *priv;
+};
+
+struct _LogdiagWindowMainClass
+{
+ GtkWindowClass parent_class;
+};
+
+
+GType logdiag_window_main_get_type (void) G_GNUC_CONST;
+
+GtkWidget *logdiag_window_main_new (void);
+
+
+G_END_DECLS
+
+#endif /* ! __WINDOW_MAIN_H__ */
+