+++ /dev/null
-INCLUDE(${crea_USE_FILE})
-
+++ /dev/null
-# We have to find crea
-FIND_PACKAGE(crea REQUIRED)
\ No newline at end of file
+++ /dev/null
-#include <BlockScopeWxApp.h>
-#include <wx/wx.h>
-
-
-class DummyWxApp : public wxApp
-{
-public:
- bool OnInit( );
- int OnExit() { return true; }
-};
-
-IMPLEMENT_APP_NO_MAIN(DummyWxApp);
-
-
-bool DummyWxApp::OnInit( )
-{
-// std::cout << "OnInit()"<<std::endl;
- wxApp::OnInit();
-#ifdef __WXGTK__
- //See http://www.wxwindows.org/faqgtk.htm#locale
- setlocale(LC_NUMERIC, "C");
-#endif
- return true;
-}
-
-
-BlockScopeWxApp::BlockScopeWxApp()
-{
- mNeedToUninitialize = false;
- if (wxApp::GetInstance()==0)
- {
- wxApp::SetInstance(new DummyWxApp);
- wxInitialize();
- mNeedToUninitialize = true;
- }
-}
-
-BlockScopeWxApp::~BlockScopeWxApp()
-{
- if (mNeedToUninitialize) wxUninitialize();
-}
-
-
-
-
+++ /dev/null
-#ifndef __wxAppNoMain_h__
-#define __wxAppNoMain_h__
-
-
-class BlockScopeWxApp
-{
-public:
- BlockScopeWxApp();
- ~BlockScopeWxApp();
-private:
- bool mNeedToUninitialize;
-};
-
-
-#endif
+++ /dev/null
-SET(LIBRARY_NAME creaImageIO2)
-
-
-FILE(GLOB SOURCES_CREAIMAGEIO
- # SQLite
- CppSQLite3.cpp
- #
- creaImageIOGimmick.cpp
- creaImageIOSynchron.cpp
- creaImageIOPACSConnection.cpp
-
- # Abstract views
- creaImageIOTreeView.cpp
-
- # settings
- creaImageIOSettings.cpp
-
- BlockScopeWxApp.cpp
- creaImageIOGimmickReaderDialog.cpp
- creaImageIOExternalGimmick.cpp
- # Viewer
- creaImageIOWxViewer.cpp
- creaImageIOGimmickView.cpp
- creaImageIOListener.cpp
-)
-
-
-
- # Attributed tree data structure
-FILE(GLOB SOURCES_CREAIMAGEIO_TREE
- creaImageIOTree.cpp
- creaImageIOTreeAttributeDescriptor.cpp
- creaImageIOTreeDescriptor.cpp
- creaImageIOTreeNode.cpp
- creaImageIOTreeLevelDescriptor.cpp
- # Tree Handlers
- creaImageIOTreeHandler.cpp
- creaImageIOTreeHandlerImageAdder.cpp
- creaImageIOSQLiteTreeHandler.cpp
- )
-IF(USE_GDCM)
- FILE(GLOB SOURCES_CREAIMAGEIO_IMG_DICOM_READER
- creaImageIODicomImageReader.cpp)
-ENDIF(USE_GDCM)
-
-
-IF(USE_GDCM2)
- FILE(GLOB SOURCES_CREAIMAGEIO_IMG_DICOM_READER
- creaImageIODicomImageReader2.cpp)
-ENDIF(USE_GDCM2)
-
- # Image Readers
-FILE(GLOB SOURCES_CREAIMAGEIO_IMG_READER
- creaImageIOAbstractImageReader.cpp
- creaImageIOImageReader.cpp
- creaImageIOUltrasonixImageReader.cpp
- creaImageIOVtkImageReader.cpp
- creaImageIOMultiThreadImageReader.cpp
- ${SOURCES_CREAIMAGEIO_IMG_DICOM_READER}
- )
-
-
-# The wxWidgets-based components
-if (USE_WXWIDGETS)
-FILE(GLOB SOURCES_CREAIMAGEIO_WX
- creaImageIOWxAttributeSelectionPanel.cpp
- creaImageIOWxCustomizeConfigPanel.cpp
- creaImageIOWxDescriptorPanel.cpp
- creaImageIOWxEditFieldsPanel.cpp
- creaImageIOWxExportDlg.cpp
- creaImageIOWxDumpPanel.cpp
- creaImageIOWxGimmickView.cpp
- creaImageIOWxGimmickReaderDialog.cpp
- creaImageIOWxGimmickFrame.cpp
- creaImageIOWxGimmickPanel.cpp
- creaImageIOWxGimmickTools.cpp
- creaImageIOWxListenerPanel.cpp
- creaImageIOWxPACSConnectionPanel.cpp
- creaImageIOWxTreeView.cpp
- )
-endif()
-
-# Header Files
-FILE(GLOB HEADER_CREAIMAGEIO creaImageIOImagePointerHolder.h)
-FILE(GLOB SOURCES_CREAIMAGEIO_PACS PACS/*.cpp)
-FILE(GLOB HEADER_CREAIMAGEIO_PACS PACS/*.h)
-
-
-SOURCE_GROUP("Source Files" FILES ${SOURCES_CREAIMAGEIO})
-SOURCE_GROUP("Header Files" FILES ${HEADER_CREAIMAGEIO})
-SOURCE_GROUP("Source Files\\GUI" FILES ${SOURCES_CREAIMAGEIO_WX})
-if(BUILD_CREA_PACS)
- SOURCE_GROUP("Source Files\\PACS" FILES ${SOURCES_CREAIMAGEIO_PACS})
- SOURCE_GROUP("Header Files\\PACS" FILES ${HEADER_CREAIMAGEIO_PACS})
-endif(BUILD_CREA_PACS)
-SOURCE_GROUP("Source Files\\Readers" FILES ${SOURCES_CREAIMAGEIO_IMG_READER}
- ${SOURCES_CREAIMAGEIO_IMG_DICOM_READER})
-SOURCE_GROUP("Source Files\\Tree" FILES ${SOURCES_CREAIMAGEIO_TREE})
-
-
-SET( PRIMITIVE_SRCS
- ${SOURCES_CREAIMAGEIO}
- ${HEADER_CREAIMAGEIO}
- ${SOURCES_CREAIMAGEIO_IMG_READER}
- ${SOURCES_CREAIMAGEIO_IMG_DICOM_READER}
- ${SOURCES_CREAIMAGEIO_WX}
- ${SOURCES_CREAIMAGEIO_TREE}
-)
-
-if( BUILD_CREA_PACS)
- SET (SRCS
- ${PRIMITIVE_SRCS}
- ${SOURCES_CREAIMAGEIO_PACS}
- ${HEADER_CREAIMAGEIO_PACS}
- )
-else (BUILD_CREA_PACS)
- SET (SRCS
- ${PRIMITIVE_SRCS}
- )
-endif (BUILD_CREA_PACS)
-
-
-
-
-OPTION(${LIBRARY_NAME}_BUILD_SHARED
- "Build ${LIBRARY_NAME} as a shared library (dynamic) ?" ON)
-IF (${LIBRARY_NAME}_BUILD_SHARED)
- SET(CREAIMAGEIO_BUILD_SHARED SHARED)
- crea_DEFINE(CREAIMAGEIO_BUILD_SHARED)
-ENDIF(${LIBRARY_NAME}_BUILD_SHARED)
-
-crea_DEFINE(CREAIMAGEIO_EXPORT_SYMBOLS)
-
-ADD_LIBRARY(${LIBRARY_NAME} ${CREAIMAGEIO_BUILD_SHARED} ${SRCS})
-
-
-TARGET_LINK_LIBRARIES(${LIBRARY_NAME}
- ${crea_LIBRARIES}
- ${creaBruker_LIBRARIES}
- ${WXWIDGETS_LIBRARIES}
- ${VTK_LIBRARIES}
- ${GDCM_LIBRARIES}
- ${BOOST_LIBRARIES}
- sqlite3)
-
-#----------------------------------------------------------------------------
-# INSTALLS LIBRARY
-FILE(GLOB HEADERS "*.h" "*.txx")
-INSTALL(
- FILES ${HEADERS}
- DESTINATION include/${LIBRARY_NAME}
- )
-
-
-IF (WIN32)
- SET(CREAIMAGEIO_LIB_PATH bin)
-ELSE (WIN32)
- SET(CREAIMAGEIO_LIB_PATH lib)
-ENDIF(WIN32)
-
-INSTALL(
- TARGETS ${LIBRARY_NAME}
- DESTINATION ${CREAIMAGEIO_LIB_PATH})
-
- # Sets the settings for macro CREA_ADVANCED_INSTALL_LIBRARY_FOR_CMAKE
- SET(${LIBRARY_NAME}_INSTALL_FOLDER ${LIBRARY_NAME})
- SET(${LIBRARY_NAME}_LIBRARIES ${LIBRARY_NAME})
-
-# FILE(RELATIVE_PATH
-# ${LIBRARY_NAME}_BUILD_TREE_RELATIVE_INCLUDE_PATHS
-# ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
-# )
-SET(${LIBRARY_NAME}_BUILD_TREE_RELATIVE_INCLUDE_PATHS
- src2
- win32
-)
-
-
- IF ( ${PROJECT_BINARY_DIR} STREQUAL ${EXECUTABLE_OUTPUT_PATH} )
- SET(CILFC_EXECUTABLE_OUTPUT_REL_PATH ".")
- ELSE ( ${PROJECT_BINARY_DIR} STREQUAL ${EXECUTABLE_OUTPUT_PATH} )
- FILE(RELATIVE_PATH
- CILFC_EXECUTABLE_OUTPUT_REL_PATH
- ${PROJECT_BINARY_DIR} ${EXECUTABLE_OUTPUT_PATH})
- ENDIF ( ${PROJECT_BINARY_DIR} STREQUAL ${EXECUTABLE_OUTPUT_PATH} )
-
- IF(UNIX)
- SET(${LIBRARY_NAME}_BUILD_TREE_RELATIVE_LIBRARY_PATHS
- ${CILFC_EXECUTABLE_OUTPUT_REL_PATH})
- SET(${LIBRARY_NAME}_INSTALL_TREE_RELATIVE_LIBRARY_PATHS lib)
- ELSE(UNIX)
- SET(${LIBRARY_NAME}_BUILD_TREE_RELATIVE_LIBRARY_PATHS
- ${CILFC_EXECUTABLE_OUTPUT_REL_PATH})
- SET(${LIBRARY_NAME}_INSTALL_TREE_RELATIVE_LIBRARY_PATHS bin)
- ENDIF(UNIX)
- SET(${LIBRARY_NAME}_INSTALL_TREE_RELATIVE_INCLUDE_PATHS include/${LIBRARY_NAME})
-
- SET(${LIBRARY_NAME}_HAS_ADDITIONAL_CONFIG_FILE TRUE)
-SET(${LIBRARY_NAME}_ADDITIONAL_CONFIG_FILE
- ${PROJECT_SOURCE_DIR}/src2/Additional${LIBRARY_NAME}Config.cmake.in)
-SET(${LIBRARY_NAME}_ADDITIONAL_USE_FILE
- ${PROJECT_SOURCE_DIR}/src2/AdditionalUse${LIBRARY_NAME}.cmake.in)
-
- # Invoke the advanced macro
- CREA_ADVANCED_INSTALL_LIBRARY_FOR_CMAKE(${LIBRARY_NAME})
-IF (WIN32)
- SET(INPUT_DATA_DIR ${PROJECT_SOURCE_DIR}/src2/data)
- SET(OUTPUT_DATA_DIR ${PROJECT_BINARY_DIR}/bin/Shared/gimmick)
-ELSE (WIN32)
- SET(INPUT_DATA_DIR ${PROJECT_SOURCE_DIR}/src2/data)
- SET(OUTPUT_DATA_DIR ${PROJECT_BINARY_DIR}/share/gimmick)
-ENDIF (WIN32)
-CREA_CPDIR(${INPUT_DATA_DIR} ${OUTPUT_DATA_DIR})
-
-
-#CREA_INSTALL_LIBRARY_FOR_CMAKE(${LIBRARY_NAME})
-#-----------------------------------------------------------------------------
-
-OPTION( BUILD_DOXYGEN_DOC "Build doxygen doc ?" OFF)
-IF(BUILD_DOXYGEN_DOC)
- SUBDIRS(doxygen)
-ENDIF(BUILD_DOXYGEN_DOC)
-
-INCLUDE_DIRECTORIES(
-# ${PROJECT_BINARY_DIR}
- ${PROJECT_SOURCE_DIR}/src2
-# ${PROJECT_SOURCE_DIR}/src2/CppSQLite3
- )
+++ /dev/null
-////////////////////////////////////////////////////////////////////////////////
-
-// CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library.
-
-//
-
-// Copyright (c) 2004 Rob Groves. All Rights Reserved. rob.groves@btinternet.com
-
-//
-
-// Permission to use, copy, modify, and distribute this software and its
-
-// documentation for any purpose, without fee, and without a written
-
-// agreement, is hereby granted, provided that the above copyright notice,
-
-// this paragraph and the following two paragraphs appear in all copies,
-
-// modifications, and distributions.
-
-//
-
-// IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
-
-// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
-
-// PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
-
-// EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-//
-
-// THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-
-// PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
-
-// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
-
-// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-//
-
-// V3.0 03/08/2004 -Initial Version for sqlite3
-
-//
-
-// V3.1 16/09/2004 -Implemented getXXXXField using sqlite3 functions
-
-// -Added CppSQLiteDB3::tableExists()
-
-////////////////////////////////////////////////////////////////////////////////
-
-#include "CppSQLite3.h"
-
-#include <cstdlib>
-
-
-
-
-
-// Named constant for passing to CppSQLite3Exception when passing it a string
-
-// that cannot be deleted.
-
-static const bool DONT_DELETE_MSG=false;
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Prototypes for SQLite functions not included in SQLite DLL, but copied below
-
-// from SQLite encode.c
-
-////////////////////////////////////////////////////////////////////////////////
-
-int sqlite3_encode_binary(const unsigned char *in, int n, unsigned char *out);
-
-int sqlite3_decode_binary(const unsigned char *in, unsigned char *out);
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-CppSQLite3Exception::CppSQLite3Exception(const int nErrCode,
-
- const char* szErrMess,
-
- bool bDeleteMsg/*=true*/) :
-
- mnErrCode(nErrCode)
-
-{
-
- mpszErrMess = sqlite3_mprintf("%s[%d]: %s",
-
- errorCodeAsString(nErrCode),
-
- nErrCode,
-
- szErrMess ? szErrMess : "");
-
- /*
-
- if (bDeleteMsg && szErrMess)
-
- {
-
- sqlite3_free(szErrMess);
-
- }
-
- */
-
-}
-
-
-
-CppSQLite3Exception::CppSQLite3Exception(const int nErrCode,
-
- char* szErrMess,
-
- bool bDeleteMsg/*=true*/) :
-
- mnErrCode(nErrCode)
-
-{
-
- mpszErrMess = sqlite3_mprintf("%s[%d]: %s",
-
- errorCodeAsString(nErrCode),
-
- nErrCode,
-
- szErrMess ? szErrMess : "");
-
-
-
- if (bDeleteMsg && szErrMess)
-
- {
-
- sqlite3_free(szErrMess);
-
- }
-
-}
-
-
-
-CppSQLite3Exception::CppSQLite3Exception(const CppSQLite3Exception& e) :
-
- mnErrCode(e.mnErrCode)
-
-{
-
- mpszErrMess = 0;
-
- if (e.mpszErrMess)
-
- {
-
- mpszErrMess = sqlite3_mprintf("%s", e.mpszErrMess);
-
- }
-
-}
-
-
-
-
-
-const char* CppSQLite3Exception::errorCodeAsString(int nErrCode)
-
-{
-
- switch (nErrCode)
-
- {
-
- case SQLITE_OK : return "SQLITE_OK";
-
- case SQLITE_ERROR : return "SQLITE_ERROR";
-
- case SQLITE_INTERNAL : return "SQLITE_INTERNAL";
-
- case SQLITE_PERM : return "SQLITE_PERM";
-
- case SQLITE_ABORT : return "SQLITE_ABORT";
-
- case SQLITE_BUSY : return "SQLITE_BUSY";
-
- case SQLITE_LOCKED : return "SQLITE_LOCKED";
-
- case SQLITE_NOMEM : return "SQLITE_NOMEM";
-
- case SQLITE_READONLY : return "SQLITE_READONLY";
-
- case SQLITE_INTERRUPT : return "SQLITE_INTERRUPT";
-
- case SQLITE_IOERR : return "SQLITE_IOERR";
-
- case SQLITE_CORRUPT : return "SQLITE_CORRUPT";
-
- case SQLITE_NOTFOUND : return "SQLITE_NOTFOUND";
-
- case SQLITE_FULL : return "SQLITE_FULL";
-
- case SQLITE_CANTOPEN : return "SQLITE_CANTOPEN";
-
- case SQLITE_PROTOCOL : return "SQLITE_PROTOCOL";
-
- case SQLITE_EMPTY : return "SQLITE_EMPTY";
-
- case SQLITE_SCHEMA : return "SQLITE_SCHEMA";
-
- case SQLITE_TOOBIG : return "SQLITE_TOOBIG";
-
- case SQLITE_CONSTRAINT : return "SQLITE_CONSTRAINT";
-
- case SQLITE_MISMATCH : return "SQLITE_MISMATCH";
-
- case SQLITE_MISUSE : return "SQLITE_MISUSE";
-
- case SQLITE_NOLFS : return "SQLITE_NOLFS";
-
- case SQLITE_AUTH : return "SQLITE_AUTH";
-
- case SQLITE_FORMAT : return "SQLITE_FORMAT";
-
- case SQLITE_RANGE : return "SQLITE_RANGE";
-
- case SQLITE_ROW : return "SQLITE_ROW";
-
- case SQLITE_DONE : return "SQLITE_DONE";
-
- case CPPSQLITE_ERROR : return "CPPSQLITE_ERROR";
-
- default: return "UNKNOWN_ERROR";
-
- }
-
-}
-
-
-
-
-
-CppSQLite3Exception::~CppSQLite3Exception()
-
-{
-
- if (mpszErrMess)
-
- {
-
- sqlite3_free(mpszErrMess);
-
- mpszErrMess = 0;
-
- }
-
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-CppSQLite3Buffer::CppSQLite3Buffer()
-
-{
-
- mpBuf = 0;
-
-}
-
-
-
-
-
-CppSQLite3Buffer::~CppSQLite3Buffer()
-
-{
-
- clear();
-
-}
-
-
-
-
-
-void CppSQLite3Buffer::clear()
-
-{
-
- if (mpBuf)
-
- {
-
- sqlite3_free(mpBuf);
-
- mpBuf = 0;
-
- }
-
-
-
-}
-
-
-
-
-
-const char* CppSQLite3Buffer::format(const char* szFormat, ...)
-
-{
-
- clear();
-
- va_list va;
-
- va_start(va, szFormat);
-
- mpBuf = sqlite3_vmprintf(szFormat, va);
-
- va_end(va);
-
- return mpBuf;
-
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-CppSQLite3Binary::CppSQLite3Binary() :
-
- mpBuf(0),
-
- mnBinaryLen(0),
-
- mnBufferLen(0),
-
- mnEncodedLen(0),
-
- mbEncoded(false)
-
-{
-
-}
-
-
-
-
-
-CppSQLite3Binary::~CppSQLite3Binary()
-
-{
-
- clear();
-
-}
-
-
-
-
-
-void CppSQLite3Binary::setBinary(const unsigned char* pBuf, int nLen)
-
-{
-
- mpBuf = allocBuffer(nLen);
-
- memcpy(mpBuf, pBuf, nLen);
-
-}
-
-
-
-
-
-void CppSQLite3Binary::setEncoded(const unsigned char* pBuf)
-
-{
-
- clear();
-
-
-
- mnEncodedLen = strlen((const char*)pBuf);
-
- mnBufferLen = mnEncodedLen + 1; // Allow for NULL terminator
-
-
-
- mpBuf = (unsigned char*)malloc(mnBufferLen);
-
-
-
- if (!mpBuf)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Cannot allocate memory",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- memcpy(mpBuf, pBuf, mnBufferLen);
-
- mbEncoded = true;
-
-}
-
-
-
-
-
-const unsigned char* CppSQLite3Binary::getEncoded()
-
-{
-
- if (!mbEncoded)
-
- {
-
- unsigned char* ptmp = (unsigned char*)malloc(mnBinaryLen);
-
- memcpy(ptmp, mpBuf, mnBinaryLen);
-
- mnEncodedLen = sqlite3_encode_binary(ptmp, mnBinaryLen, mpBuf);
-
- free(ptmp);
-
- mbEncoded = true;
-
- }
-
-
-
- return mpBuf;
-
-}
-
-
-
-
-
-const unsigned char* CppSQLite3Binary::getBinary()
-
-{
-
- if (mbEncoded)
-
- {
-
- // in/out buffers can be the same
-
- mnBinaryLen = sqlite3_decode_binary(mpBuf, mpBuf);
-
-
-
- if (mnBinaryLen == -1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Cannot decode binary",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- mbEncoded = false;
-
- }
-
-
-
- return mpBuf;
-
-}
-
-
-
-
-
-int CppSQLite3Binary::getBinaryLength()
-
-{
-
- getBinary();
-
- return mnBinaryLen;
-
-}
-
-
-
-
-
-unsigned char* CppSQLite3Binary::allocBuffer(int nLen)
-
-{
-
- clear();
-
-
-
- // Allow extra space for encoded binary as per comments in
-
- // SQLite encode.c See bottom of this file for implementation
-
- // of SQLite functions use 3 instead of 2 just to be sure ;-)
-
- mnBinaryLen = nLen;
-
- mnBufferLen = 3 + (257*nLen)/254;
-
-
-
- mpBuf = (unsigned char*)malloc(mnBufferLen);
-
-
-
- if (!mpBuf)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Cannot allocate memory",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- mbEncoded = false;
-
-
-
- return mpBuf;
-
-}
-
-
-
-
-
-void CppSQLite3Binary::clear()
-
-{
-
- if (mpBuf)
-
- {
-
- mnBinaryLen = 0;
-
- mnBufferLen = 0;
-
- free(mpBuf);
-
- mpBuf = 0;
-
- }
-
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-CppSQLite3Query::CppSQLite3Query()
-
-{
-
- mpVM = 0;
-
- mbEof = true;
-
- mnCols = 0;
-
- mbOwnVM = false;
-
-}
-
-
-
-
-
-CppSQLite3Query::CppSQLite3Query(const CppSQLite3Query& rQuery)
-
-{
-
- mpVM = rQuery.mpVM;
-
- // Only one object can own the VM
-
- const_cast<CppSQLite3Query&>(rQuery).mpVM = 0;
-
- mbEof = rQuery.mbEof;
-
- mnCols = rQuery.mnCols;
-
- mbOwnVM = rQuery.mbOwnVM;
-
-}
-
-
-
-
-
-CppSQLite3Query::CppSQLite3Query(sqlite3* pDB,
-
- sqlite3_stmt* pVM,
-
- bool bEof,
-
- bool bOwnVM/*=true*/)
-
-{
-
- mpDB = pDB;
-
- mpVM = pVM;
-
- mbEof = bEof;
-
- mnCols = sqlite3_column_count(mpVM);
-
- mbOwnVM = bOwnVM;
-
-}
-
-
-
-
-
-CppSQLite3Query::~CppSQLite3Query()
-
-{
-
- try
-
- {
-
- finalize();
-
- }
-
- catch (...)
-
- {
-
- }
-
-}
-
-
-
-
-
-CppSQLite3Query& CppSQLite3Query::operator=(const CppSQLite3Query& rQuery)
-
-{
-
- try
-
- {
-
- finalize();
-
- }
-
- catch (...)
-
- {
-
- }
-
- mpVM = rQuery.mpVM;
-
- // Only one object can own the VM
-
- const_cast<CppSQLite3Query&>(rQuery).mpVM = 0;
-
- mbEof = rQuery.mbEof;
-
- mnCols = rQuery.mnCols;
-
- mbOwnVM = rQuery.mbOwnVM;
-
- return *this;
-
-}
-
-
-
-
-
-int CppSQLite3Query::numFields()
-
-{
-
- checkVM();
-
- return mnCols;
-
-}
-
-
-
-
-
-const char* CppSQLite3Query::fieldValue(int nField)
-
-{
-
- checkVM();
-
-
-
- if (nField < 0 || nField > mnCols-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- return (const char*)sqlite3_column_text(mpVM, nField);
-
-}
-
-
-
-
-
-const char* CppSQLite3Query::fieldValue(const char* szField)
-
-{
-
- int nField = fieldIndex(szField);
-
- return (const char*)sqlite3_column_text(mpVM, nField);
-
-}
-
-
-
-
-
-int CppSQLite3Query::getIntField(int nField, int nNullValue/*=0*/)
-
-{
-
- if (fieldDataType(nField) == SQLITE_NULL)
-
- {
-
- return nNullValue;
-
- }
-
- else
-
- {
-
- return sqlite3_column_int(mpVM, nField);
-
- }
-
-}
-
-
-
-
-
-int CppSQLite3Query::getIntField(const char* szField, int nNullValue/*=0*/)
-
-{
-
- int nField = fieldIndex(szField);
-
- return getIntField(nField, nNullValue);
-
-}
-
-
-
-
-
-double CppSQLite3Query::getFloatField(int nField, double fNullValue/*=0.0*/)
-
-{
-
- if (fieldDataType(nField) == SQLITE_NULL)
-
- {
-
- return fNullValue;
-
- }
-
- else
-
- {
-
- return sqlite3_column_double(mpVM, nField);
-
- }
-
-}
-
-
-
-
-
-double CppSQLite3Query::getFloatField(const char* szField, double fNullValue/*=0.0*/)
-
-{
-
- int nField = fieldIndex(szField);
-
- return getFloatField(nField, fNullValue);
-
-}
-
-
-
-
-
-const char* CppSQLite3Query::getStringField(int nField, const char* szNullValue/*=""*/)
-
-{
-
- if (fieldDataType(nField) == SQLITE_NULL)
-
- {
-
- return szNullValue;
-
- }
-
- else
-
- {
-
- return (const char*)sqlite3_column_text(mpVM, nField);
-
- }
-
-}
-
-
-
-
-
-const char* CppSQLite3Query::getStringField(const char* szField, const char* szNullValue/*=""*/)
-
-{
-
- int nField = fieldIndex(szField);
-
- return getStringField(nField, szNullValue);
-
-}
-
-
-
-
-
-const unsigned char* CppSQLite3Query::getBlobField(int nField, int& nLen)
-
-{
-
- checkVM();
-
-
-
- if (nField < 0 || nField > mnCols-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- nLen = sqlite3_column_bytes(mpVM, nField);
-
- return (const unsigned char*)sqlite3_column_blob(mpVM, nField);
-
-}
-
-
-
-
-
-const unsigned char* CppSQLite3Query::getBlobField(const char* szField, int& nLen)
-
-{
-
- int nField = fieldIndex(szField);
-
- return getBlobField(nField, nLen);
-
-}
-
-
-
-
-
-bool CppSQLite3Query::fieldIsNull(int nField)
-
-{
-
- return (fieldDataType(nField) == SQLITE_NULL);
-
-}
-
-
-
-
-
-bool CppSQLite3Query::fieldIsNull(const char* szField)
-
-{
-
- int nField = fieldIndex(szField);
-
- return (fieldDataType(nField) == SQLITE_NULL);
-
-}
-
-
-
-
-
-int CppSQLite3Query::fieldIndex(const char* szField)
-
-{
-
- checkVM();
-
-
-
- if (szField)
-
- {
-
- for (int nField = 0; nField < mnCols; nField++)
-
- {
-
- const char* szTemp = sqlite3_column_name(mpVM, nField);
-
-
-
- if (strcmp(szField, szTemp) == 0)
-
- {
-
- return nField;
-
- }
-
- }
-
- }
-
-
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field name requested",
-
- DONT_DELETE_MSG);
-
-}
-
-
-
-
-
-const char* CppSQLite3Query::fieldName(int nCol)
-
-{
-
- checkVM();
-
-
-
- if (nCol < 0 || nCol > mnCols-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- return sqlite3_column_name(mpVM, nCol);
-
-}
-
-
-
-
-
-const char* CppSQLite3Query::fieldDeclType(int nCol)
-
-{
-
- checkVM();
-
-
-
- if (nCol < 0 || nCol > mnCols-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- return sqlite3_column_decltype(mpVM, nCol);
-
-}
-
-
-
-
-
-int CppSQLite3Query::fieldDataType(int nCol)
-
-{
-
- checkVM();
-
-
-
- if (nCol < 0 || nCol > mnCols-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- return sqlite3_column_type(mpVM, nCol);
-
-}
-
-
-
-
-
-bool CppSQLite3Query::eof()
-
-{
-
- checkVM();
-
- return mbEof;
-
-}
-
-
-
-
-
-void CppSQLite3Query::nextRow()
-
-{
-
- checkVM();
-
-
-
- int nRet = sqlite3_step(mpVM);
-
-
-
- if (nRet == SQLITE_DONE)
-
- {
-
- // no rows
-
- mbEof = true;
-
- }
-
- else if (nRet == SQLITE_ROW)
-
- {
-
- // more rows, nothing to do
-
- }
-
- else
-
- {
-
- nRet = sqlite3_finalize(mpVM);
-
- mpVM = 0;
-
- const char* szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet,
-
- (char*)szError,
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Query::finalize()
-
-{
-
- if (mpVM && mbOwnVM)
-
- {
-
- int nRet = sqlite3_finalize(mpVM);
-
- mpVM = 0;
-
- if (nRet != SQLITE_OK)
-
- {
-
- const char* szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Query::checkVM()
-
-{
-
- if (mpVM == 0)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Null Virtual Machine pointer",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-CppSQLite3Table::CppSQLite3Table()
-
-{
-
- mpaszResults = 0;
-
- mnRows = 0;
-
- mnCols = 0;
-
- mnCurrentRow = 0;
-
-}
-
-
-
-
-
-CppSQLite3Table::CppSQLite3Table(const CppSQLite3Table& rTable)
-
-{
-
- mpaszResults = rTable.mpaszResults;
-
- // Only one object can own the results
-
- const_cast<CppSQLite3Table&>(rTable).mpaszResults = 0;
-
- mnRows = rTable.mnRows;
-
- mnCols = rTable.mnCols;
-
- mnCurrentRow = rTable.mnCurrentRow;
-
-}
-
-
-
-
-
-CppSQLite3Table::CppSQLite3Table(char** paszResults, int nRows, int nCols)
-
-{
-
- mpaszResults = paszResults;
-
- mnRows = nRows;
-
- mnCols = nCols;
-
- mnCurrentRow = 0;
-
-}
-
-
-
-
-
-CppSQLite3Table::~CppSQLite3Table()
-
-{
-
- try
-
- {
-
- finalize();
-
- }
-
- catch (...)
-
- {
-
- }
-
-}
-
-
-
-
-
-CppSQLite3Table& CppSQLite3Table::operator=(const CppSQLite3Table& rTable)
-
-{
-
- try
-
- {
-
- finalize();
-
- }
-
- catch (...)
-
- {
-
- }
-
- mpaszResults = rTable.mpaszResults;
-
- // Only one object can own the results
-
- const_cast<CppSQLite3Table&>(rTable).mpaszResults = 0;
-
- mnRows = rTable.mnRows;
-
- mnCols = rTable.mnCols;
-
- mnCurrentRow = rTable.mnCurrentRow;
-
- return *this;
-
-}
-
-
-
-
-
-void CppSQLite3Table::finalize()
-
-{
-
- if (mpaszResults)
-
- {
-
- sqlite3_free_table(mpaszResults);
-
- mpaszResults = 0;
-
- }
-
-}
-
-
-
-
-
-int CppSQLite3Table::numFields()
-
-{
-
- checkResults();
-
- return mnCols;
-
-}
-
-
-
-
-
-int CppSQLite3Table::numRows()
-
-{
-
- checkResults();
-
- return mnRows;
-
-}
-
-
-
-
-
-const char* CppSQLite3Table::fieldValue(int nField)
-
-{
-
- checkResults();
-
-
-
- if (nField < 0 || nField > mnCols-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- int nIndex = (mnCurrentRow*mnCols) + mnCols + nField;
-
- return mpaszResults[nIndex];
-
-}
-
-
-
-
-
-const char* CppSQLite3Table::fieldValue(const char* szField)
-
-{
-
- checkResults();
-
-
-
- if (szField)
-
- {
-
- for (int nField = 0; nField < mnCols; nField++)
-
- {
-
- if (strcmp(szField, mpaszResults[nField]) == 0)
-
- {
-
- int nIndex = (mnCurrentRow*mnCols) + mnCols + nField;
-
- return mpaszResults[nIndex];
-
- }
-
- }
-
- }
-
-
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field name requested",
-
- DONT_DELETE_MSG);
-
-}
-
-
-
-
-
-int CppSQLite3Table::getIntField(int nField, int nNullValue/*=0*/)
-
-{
-
- if (fieldIsNull(nField))
-
- {
-
- return nNullValue;
-
- }
-
- else
-
- {
-
- return atoi(fieldValue(nField));
-
- }
-
-}
-
-
-
-
-
-int CppSQLite3Table::getIntField(const char* szField, int nNullValue/*=0*/)
-
-{
-
- if (fieldIsNull(szField))
-
- {
-
- return nNullValue;
-
- }
-
- else
-
- {
-
- return atoi(fieldValue(szField));
-
- }
-
-}
-
-
-
-
-
-double CppSQLite3Table::getFloatField(int nField, double fNullValue/*=0.0*/)
-
-{
-
- if (fieldIsNull(nField))
-
- {
-
- return fNullValue;
-
- }
-
- else
-
- {
-
- return atof(fieldValue(nField));
-
- }
-
-}
-
-
-
-
-
-double CppSQLite3Table::getFloatField(const char* szField, double fNullValue/*=0.0*/)
-
-{
-
- if (fieldIsNull(szField))
-
- {
-
- return fNullValue;
-
- }
-
- else
-
- {
-
- return atof(fieldValue(szField));
-
- }
-
-}
-
-
-
-
-
-const char* CppSQLite3Table::getStringField(int nField, const char* szNullValue/*=""*/)
-
-{
-
- if (fieldIsNull(nField))
-
- {
-
- return szNullValue;
-
- }
-
- else
-
- {
-
- return fieldValue(nField);
-
- }
-
-}
-
-
-
-
-
-const char* CppSQLite3Table::getStringField(const char* szField, const char* szNullValue/*=""*/)
-
-{
-
- if (fieldIsNull(szField))
-
- {
-
- return szNullValue;
-
- }
-
- else
-
- {
-
- return fieldValue(szField);
-
- }
-
-}
-
-
-
-
-
-bool CppSQLite3Table::fieldIsNull(int nField)
-
-{
-
- checkResults();
-
- return (fieldValue(nField) == 0);
-
-}
-
-
-
-
-
-bool CppSQLite3Table::fieldIsNull(const char* szField)
-
-{
-
- checkResults();
-
- return (fieldValue(szField) == 0);
-
-}
-
-
-
-
-
-const char* CppSQLite3Table::fieldName(int nCol)
-
-{
-
- checkResults();
-
-
-
- if (nCol < 0 || nCol > mnCols-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid field index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- return mpaszResults[nCol];
-
-}
-
-
-
-
-
-void CppSQLite3Table::setRow(int nRow)
-
-{
-
- checkResults();
-
-
-
- if (nRow < 0 || nRow > mnRows-1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid row index requested",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- mnCurrentRow = nRow;
-
-}
-
-
-
-
-
-void CppSQLite3Table::checkResults()
-
-{
-
- if (mpaszResults == 0)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Null Results pointer",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-CppSQLite3Statement::CppSQLite3Statement()
-
-{
-
- mpDB = 0;
-
- mpVM = 0;
-
-}
-
-
-
-
-
-CppSQLite3Statement::CppSQLite3Statement(const CppSQLite3Statement& rStatement)
-
-{
-
- mpDB = rStatement.mpDB;
-
- mpVM = rStatement.mpVM;
-
- // Only one object can own VM
-
- const_cast<CppSQLite3Statement&>(rStatement).mpVM = 0;
-
-}
-
-
-
-
-
-CppSQLite3Statement::CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM)
-
-{
-
- mpDB = pDB;
-
- mpVM = pVM;
-
-}
-
-
-
-
-
-CppSQLite3Statement::~CppSQLite3Statement()
-
-{
-
- try
-
- {
-
- finalize();
-
- }
-
- catch (...)
-
- {
-
- }
-
-}
-
-
-
-
-
-CppSQLite3Statement& CppSQLite3Statement::operator=(const CppSQLite3Statement& rStatement)
-
-{
-
- mpDB = rStatement.mpDB;
-
- mpVM = rStatement.mpVM;
-
- // Only one object can own VM
-
- const_cast<CppSQLite3Statement&>(rStatement).mpVM = 0;
-
- return *this;
-
-}
-
-
-
-
-
-int CppSQLite3Statement::execDML()
-
-{
-
- checkDB();
-
- checkVM();
-
-
-
- const char* szError=0;
-
-
-
- int nRet = sqlite3_step(mpVM);
-
-
-
- if (nRet == SQLITE_DONE)
-
- {
-
- int nRowsChanged = sqlite3_changes(mpDB);
-
-
-
- nRet = sqlite3_reset(mpVM);
-
-
-
- if (nRet != SQLITE_OK)
-
- {
-
- szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
-
-
- return nRowsChanged;
-
- }
-
- else
-
- {
-
- nRet = sqlite3_reset(mpVM);
-
- szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-CppSQLite3Query CppSQLite3Statement::execQuery()
-
-{
-
- checkDB();
-
- checkVM();
-
-
-
- int nRet = sqlite3_step(mpVM);
-
-
-
- if (nRet == SQLITE_DONE)
-
- {
-
- // no rows
-
- return CppSQLite3Query(mpDB, mpVM, true/*eof*/, false);
-
- }
-
- else if (nRet == SQLITE_ROW)
-
- {
-
- // at least 1 row
-
- return CppSQLite3Query(mpDB, mpVM, false/*eof*/, false);
-
- }
-
- else
-
- {
-
- nRet = sqlite3_reset(mpVM);
-
- const char* szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::bind(int nParam, const char* szValue)
-
-{
-
- checkVM();
-
- int nRes = sqlite3_bind_text(mpVM, nParam, szValue, -1, SQLITE_TRANSIENT);
-
-
-
- if (nRes != SQLITE_OK)
-
- {
-
- throw CppSQLite3Exception(nRes,
-
- "Error binding string param",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::bind(int nParam, const int nValue)
-
-{
-
- checkVM();
-
- int nRes = sqlite3_bind_int(mpVM, nParam, nValue);
-
-
-
- if (nRes != SQLITE_OK)
-
- {
-
- throw CppSQLite3Exception(nRes,
-
- "Error binding int param",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::bind(int nParam, const double dValue)
-
-{
-
- checkVM();
-
- int nRes = sqlite3_bind_double(mpVM, nParam, dValue);
-
-
-
- if (nRes != SQLITE_OK)
-
- {
-
- throw CppSQLite3Exception(nRes,
-
- "Error binding double param",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::bind(int nParam, const unsigned char* blobValue, int nLen)
-
-{
-
- checkVM();
-
- int nRes = sqlite3_bind_blob(mpVM, nParam,
-
- (const void*)blobValue, nLen, SQLITE_TRANSIENT);
-
-
-
- if (nRes != SQLITE_OK)
-
- {
-
- throw CppSQLite3Exception(nRes,
-
- "Error binding blob param",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::bindNull(int nParam)
-
-{
-
- checkVM();
-
- int nRes = sqlite3_bind_null(mpVM, nParam);
-
-
-
- if (nRes != SQLITE_OK)
-
- {
-
- throw CppSQLite3Exception(nRes,
-
- "Error binding NULL param",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::reset()
-
-{
-
- if (mpVM)
-
- {
-
- int nRet = sqlite3_reset(mpVM);
-
-
-
- if (nRet != SQLITE_OK)
-
- {
-
- const char* szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::finalize()
-
-{
-
- if (mpVM)
-
- {
-
- int nRet = sqlite3_finalize(mpVM);
-
- mpVM = 0;
-
-
-
- if (nRet != SQLITE_OK)
-
- {
-
- const char* szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::checkDB()
-
-{
-
- if (mpDB == 0)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Database not open",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-void CppSQLite3Statement::checkVM()
-
-{
-
- if (mpVM == 0)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Null Virtual Machine pointer",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-CppSQLite3DB::CppSQLite3DB()
-
-{
-
- mpDB = 0;
-
- mnBusyTimeoutMs = 60000; // 60 seconds
-
-}
-
-
-
-
-
-CppSQLite3DB::CppSQLite3DB(const CppSQLite3DB& db)
-
-{
-
- mpDB = db.mpDB;
-
- mnBusyTimeoutMs = 60000; // 60 seconds
-
-}
-
-
-
-
-
-CppSQLite3DB::~CppSQLite3DB()
-
-{
-
- close();
-
-}
-
-
-
-
-
-CppSQLite3DB& CppSQLite3DB::operator=(const CppSQLite3DB& db)
-
-{
-
- mpDB = db.mpDB;
-
- mnBusyTimeoutMs = 60000; // 60 seconds
-
- return *this;
-
-}
-
-
-
-
-
-void CppSQLite3DB::open(const char* szFile)
-
-{
-
- int nRet = sqlite3_open(szFile, &mpDB);
-
-
-
- if (nRet != SQLITE_OK)
-
- {
-
- const char* szError = sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
-
-
- setBusyTimeout(mnBusyTimeoutMs);
-
-}
-
-
-
-
-
-void CppSQLite3DB::close()
-
-{
-
- if (mpDB)
-
- {
-
- sqlite3_close(mpDB);
-
- mpDB = 0;
-
- }
-
-}
-
-
-
-
-
-CppSQLite3Statement CppSQLite3DB::compileStatement(const char* szSQL)
-
-{
-
- checkDB();
-
-
-
- sqlite3_stmt* pVM = compile(szSQL);
-
- return CppSQLite3Statement(mpDB, pVM);
-
-}
-
-
-
-
-
-bool CppSQLite3DB::tableExists(const char* szTable)
-
-{
-
- char szSQL[128];
-
- sprintf(szSQL,
-
- "select count(*) from sqlite_master where type='table' and name='%s'",
-
- szTable);
-
- int nRet = execScalar(szSQL);
-
- return (nRet > 0);
-
-}
-
-
-
-
-
-int CppSQLite3DB::execDML(const char* szSQL)
-
-{
-
- checkDB();
-
-
-
- char* szError=0;
-
-
-
- int nRet = sqlite3_exec(mpDB, szSQL, 0, 0, &szError);
-
-
-
- if (nRet == SQLITE_OK)
-
- {
-
- return sqlite3_changes(mpDB);
-
- }
-
- else
-
- {
-
- throw CppSQLite3Exception(nRet, szError);
-
- }
-
-}
-
-
-
-
-
-CppSQLite3Query CppSQLite3DB::execQuery(const char* szSQL)
-
-{
-
- checkDB();
-
-
-
- sqlite3_stmt* pVM = compile(szSQL);
-
-
-
- int nRet = sqlite3_step(pVM);
-
-
-
- if (nRet == SQLITE_DONE)
-
- {
-
- // no rows
-
- return CppSQLite3Query(mpDB, pVM, true/*eof*/);
-
- }
-
- else if (nRet == SQLITE_ROW)
-
- {
-
- // at least 1 row
-
- return CppSQLite3Query(mpDB, pVM, false/*eof*/);
-
- }
-
- else
-
- {
-
- nRet = sqlite3_finalize(pVM);
-
- const char* szError= sqlite3_errmsg(mpDB);
-
- throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-int CppSQLite3DB::execScalar(const char* szSQL)
-
-{
-
- CppSQLite3Query q = execQuery(szSQL);
-
-
-
- if (q.eof() || q.numFields() < 1)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Invalid scalar query",
-
- DONT_DELETE_MSG);
-
- }
-
-
-
- return atoi(q.fieldValue(0));
-
-}
-
-
-
-
-
-CppSQLite3Table CppSQLite3DB::getTable(const char* szSQL)
-
-{
-
- checkDB();
-
-
-
- char* szError=0;
-
- char** paszResults=0;
-
- int nRet;
-
- int nRows(0);
-
- int nCols(0);
-
-
-
- nRet = sqlite3_get_table(mpDB, szSQL, &paszResults, &nRows, &nCols, &szError);
-
-
-
- if (nRet == SQLITE_OK)
-
- {
-
- return CppSQLite3Table(paszResults, nRows, nCols);
-
- }
-
- else
-
- {
-
- throw CppSQLite3Exception(nRet, szError);
-
- }
-
-}
-
-
-
-
-
-sqlite_int64 CppSQLite3DB::lastRowId()
-
-{
-
- return sqlite3_last_insert_rowid(mpDB);
-
-}
-
-
-
-
-
-void CppSQLite3DB::setBusyTimeout(int nMillisecs)
-
-{
-
- mnBusyTimeoutMs = nMillisecs;
-
- sqlite3_busy_timeout(mpDB, mnBusyTimeoutMs);
-
-}
-
-
-
-
-
-void CppSQLite3DB::checkDB()
-
-{
-
- if (!mpDB)
-
- {
-
- throw CppSQLite3Exception(CPPSQLITE_ERROR,
-
- "Database not open",
-
- DONT_DELETE_MSG);
-
- }
-
-}
-
-
-
-
-
-sqlite3_stmt* CppSQLite3DB::compile(const char* szSQL)
-
-{
-
- checkDB();
-
-
-
- char* szError=0;
-
- const char* szTail=0;
-
- sqlite3_stmt* pVM;
-
-
-
- int nRet = sqlite3_prepare(mpDB, szSQL, -1, &pVM, &szTail);
-
-
-
- if (nRet != SQLITE_OK)
-
- {
-
- throw CppSQLite3Exception(nRet, szError);
-
- }
-
-
-
- return pVM;
-
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-// SQLite encode.c reproduced here, containing implementation notes and source
-
-// for sqlite3_encode_binary() and sqlite3_decode_binary()
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-/*
-
-** 2002 April 25
-
-**
-
-** The author disclaims copyright to this source code. In place of
-
-** a legal notice, here is a blessing:
-
-**
-
-** May you do good and not evil.
-
-** May you find forgiveness for yourself and forgive others.
-
-** May you share freely, never taking more than you give.
-
-**
-
-*************************************************************************
-
-** This file contains helper routines used to translate binary data into
-
-** a null-terminated string (suitable for use in SQLite) and back again.
-
-** These are convenience routines for use by people who want to store binary
-
-** data in an SQLite database. The code in this file is not used by any other
-
-** part of the SQLite library.
-
-**
-
-** $Id: CppSQLite3.cpp,v 1.2 2009/08/27 11:47:02 cervenansky Exp $
-
-*/
-
-
-
-/*
-
-** How This Encoder Works
-
-**
-
-** The output is allowed to contain any character except 0x27 (') and
-
-** 0x00. This is accomplished by using an escape character to encode
-
-** 0x27 and 0x00 as a two-byte sequence. The escape character is always
-
-** 0x01. An 0x00 is encoded as the two byte sequence 0x01 0x01. The
-
-** 0x27 character is encoded as the two byte sequence 0x01 0x03. Finally,
-
-** the escape character itself is encoded as the two-character sequence
-
-** 0x01 0x02.
-
-**
-
-** To summarize, the encoder works by using an escape sequences as follows:
-
-**
-
-** 0x00 -> 0x01 0x01
-
-** 0x01 -> 0x01 0x02
-
-** 0x27 -> 0x01 0x03
-
-**
-
-** If that were all the encoder did, it would work, but in certain cases
-
-** it could double the size of the encoded string. For example, to
-
-** encode a string of 100 0x27 characters would require 100 instances of
-
-** the 0x01 0x03 escape sequence resulting in a 200-character output.
-
-** We would prefer to keep the size of the encoded string smaller than
-
-** this.
-
-**
-
-** To minimize the encoding size, we first add a fixed offset value to each
-
-** byte in the sequence. The addition is modulo 256. (That is to say, if
-
-** the sum of the original character value and the offset exceeds 256, then
-
-** the higher order bits are truncated.) The offset is chosen to minimize
-
-** the number of characters in the string that need to be escaped. For
-
-** example, in the case above where the string was composed of 100 0x27
-
-** characters, the offset might be 0x01. Each of the 0x27 characters would
-
-** then be converted into an 0x28 character which would not need to be
-
-** escaped at all and so the 100 character input string would be converted
-
-** into just 100 characters of output. Actually 101 characters of output -
-
-** we have to record the offset used as the first byte in the sequence so
-
-** that the string can be decoded. Since the offset value is stored as
-
-** part of the output string and the output string is not allowed to contain
-
-** characters 0x00 or 0x27, the offset cannot be 0x00 or 0x27.
-
-**
-
-** Here, then, are the encoding steps:
-
-**
-
-** (1) Choose an offset value and make it the first character of
-
-** output.
-
-**
-
-** (2) Copy each input character into the output buffer, one by
-
-** one, adding the offset value as you copy.
-
-**
-
-** (3) If the value of an input character plus offset is 0x00, replace
-
-** that one character by the two-character sequence 0x01 0x01.
-
-** If the sum is 0x01, replace it with 0x01 0x02. If the sum
-
-** is 0x27, replace it with 0x01 0x03.
-
-**
-
-** (4) Put a 0x00 terminator at the end of the output.
-
-**
-
-** Decoding is obvious:
-
-**
-
-** (5) Copy encoded characters except the first into the decode
-
-** buffer. Set the first encoded character aside for use as
-
-** the offset in step 7 below.
-
-**
-
-** (6) Convert each 0x01 0x01 sequence into a single character 0x00.
-
-** Convert 0x01 0x02 into 0x01. Convert 0x01 0x03 into 0x27.
-
-**
-
-** (7) Subtract the offset value that was the first character of
-
-** the encoded buffer from all characters in the output buffer.
-
-**
-
-** The only tricky part is step (1) - how to compute an offset value to
-
-** minimize the size of the output buffer. This is accomplished by testing
-
-** all offset values and picking the one that results in the fewest number
-
-** of escapes. To do that, we first scan the entire input and count the
-
-** number of occurances of each character value in the input. Suppose
-
-** the number of 0x00 characters is N(0), the number of occurances of 0x01
-
-** is N(1), and so forth up to the number of occurances of 0xff is N(255).
-
-** An offset of 0 is not allowed so we don't have to test it. The number
-
-** of escapes required for an offset of 1 is N(1)+N(2)+N(40). The number
-
-** of escapes required for an offset of 2 is N(2)+N(3)+N(41). And so forth.
-
-** In this way we find the offset that gives the minimum number of escapes,
-
-** and thus minimizes the length of the output string.
-
-*/
-
-
-
-/*
-
-** Encode a binary buffer "in" of size n bytes so that it contains
-
-** no instances of characters '\'' or '\000'. The output is
-
-** null-terminated and can be used as a string value in an INSERT
-
-** or UPDATE statement. Use sqlite3_decode_binary() to convert the
-
-** string back into its original binary.
-
-**
-
-** The result is written into a preallocated output buffer "out".
-
-** "out" must be able to hold at least 2 +(257*n)/254 bytes.
-
-** In other words, the output will be expanded by as much as 3
-
-** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
-
-** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
-
-**
-
-** The return value is the number of characters in the encoded
-
-** string, excluding the "\000" terminator.
-
-*/
-
-int sqlite3_encode_binary(const unsigned char *in, int n, unsigned char *out){
-
- int i, j, e, m;
-
- int cnt[256];
-
- if( n<=0 ){
-
- out[0] = 'x';
-
- out[1] = 0;
-
- return 1;
-
- }
-
- memset(cnt, 0, sizeof(cnt));
-
- for(i=n-1; i>=0; i--){ cnt[in[i]]++; }
-
- m = n;
-
- for(i=1; i<256; i++){
-
- int sum;
-
- if( i=='\'' ) continue;
-
- sum = cnt[i] + cnt[(i+1)&0xff] + cnt[(i+'\'')&0xff];
-
- if( sum<m ){
-
- m = sum;
-
- e = i;
-
- if( m==0 ) break;
-
- }
-
- }
-
- out[0] = e;
-
- j = 1;
-
- for(i=0; i<n; i++){
-
- int c = (in[i] - e)&0xff;
-
- if( c==0 ){
-
- out[j++] = 1;
-
- out[j++] = 1;
-
- }else if( c==1 ){
-
- out[j++] = 1;
-
- out[j++] = 2;
-
- }else if( c=='\'' ){
-
- out[j++] = 1;
-
- out[j++] = 3;
-
- }else{
-
- out[j++] = c;
-
- }
-
- }
-
- out[j] = 0;
-
- return j;
-
-}
-
-
-
-/*
-
-** Decode the string "in" into binary data and write it into "out".
-
-** This routine reverses the encoding created by sqlite3_encode_binary().
-
-** The output will always be a few bytes less than the input. The number
-
-** of bytes of output is returned. If the input is not a well-formed
-
-** encoding, -1 is returned.
-
-**
-
-** The "in" and "out" parameters may point to the same buffer in order
-
-** to decode a string in place.
-
-*/
-
-int sqlite3_decode_binary(const unsigned char *in, unsigned char *out){
-
- int i, c, e;
-
- e = *(in++);
-
- i = 0;
-
- while( (c = *(in++))!=0 ){
-
- if( c==1 ){
-
- c = *(in++);
-
- if( c==1 ){
-
- c = 0;
-
- }else if( c==2 ){
-
- c = 1;
-
- }else if( c==3 ){
-
- c = '\'';
-
- }else{
-
- return -1;
-
- }
-
- }
-
- out[i++] = (c + e)&0xff;
-
- }
-
- return i;
-
-}
-
+++ /dev/null
-////////////////////////////////////////////////////////////////////////////////
-
-// CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library.
-
-//
-
-// Copyright (c) 2004 Rob Groves. All Rights Reserved. rob.groves@btinternet.com
-
-//
-
-// Permission to use, copy, modify, and distribute this software and its
-
-// documentation for any purpose, without fee, and without a written
-
-// agreement, is hereby granted, provided that the above copyright notice,
-
-// this paragraph and the following two paragraphs appear in all copies,
-
-// modifications, and distributions.
-
-//
-
-// IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
-
-// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
-
-// PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
-
-// EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-//
-
-// THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-
-// PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
-
-// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
-
-// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-//
-
-// V3.0 03/08/2004 -Initial Version for sqlite3
-
-//
-
-// V3.1 16/09/2004 -Implemented getXXXXField using sqlite3 functions
-
-// -Added CppSQLiteDB3::tableExists()
-
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef _CppSQLite3_H_
-
-#define _CppSQLite3_H_
-
-
-
-#include "sqlite3.h"
-
-#include <cstdio>
-
-#include <cstring>
-
-
-
-#define CPPSQLITE_ERROR 1000
-
-
-
-class CppSQLite3Exception
-
-{
-
-public:
-
-
-
- CppSQLite3Exception(const int nErrCode,
-
- char* szErrMess,
-
- bool bDeleteMsg=true);
-
- CppSQLite3Exception(const int nErrCode,
-
- const char* szErrMess,
-
- bool bDeleteMsg=true);
-
-
-
- CppSQLite3Exception(const CppSQLite3Exception& e);
-
-
-
- virtual ~CppSQLite3Exception();
-
-
-
- const int errorCode() { return mnErrCode; }
-
-
-
- const char* errorMessage() { return mpszErrMess; }
-
-
-
- static const char* errorCodeAsString(int nErrCode);
-
-
-
-private:
-
-
-
- int mnErrCode;
-
- char* mpszErrMess;
-
-};
-
-
-
-
-
-class CppSQLite3Buffer
-
-{
-
-public:
-
-
-
- CppSQLite3Buffer();
-
-
-
- ~CppSQLite3Buffer();
-
-
-
- const char* format(const char* szFormat, ...);
-
-
-
- operator const char*() { return mpBuf; }
-
-
-
- void clear();
-
-
-
-private:
-
-
-
- char* mpBuf;
-
-};
-
-
-
-
-
-class CppSQLite3Binary
-
-{
-
-public:
-
-
-
- CppSQLite3Binary();
-
-
-
- ~CppSQLite3Binary();
-
-
-
- void setBinary(const unsigned char* pBuf, int nLen);
-
- void setEncoded(const unsigned char* pBuf);
-
-
-
- const unsigned char* getEncoded();
-
- const unsigned char* getBinary();
-
-
-
- int getBinaryLength();
-
-
-
- unsigned char* allocBuffer(int nLen);
-
-
-
- void clear();
-
-
-
-private:
-
-
-
- unsigned char* mpBuf;
-
- int mnBinaryLen;
-
- int mnBufferLen;
-
- int mnEncodedLen;
-
- bool mbEncoded;
-
-};
-
-
-
-
-
-class CppSQLite3Query
-
-{
-
-public:
-
-
-
- CppSQLite3Query();
-
-
-
- CppSQLite3Query(const CppSQLite3Query& rQuery);
-
-
-
- CppSQLite3Query(sqlite3* pDB,
-
- sqlite3_stmt* pVM,
-
- bool bEof,
-
- bool bOwnVM=true);
-
-
-
- CppSQLite3Query& operator=(const CppSQLite3Query& rQuery);
-
-
-
- virtual ~CppSQLite3Query();
-
-
-
- int numFields();
-
-
-
- int fieldIndex(const char* szField);
-
- const char* fieldName(int nCol);
-
-
-
- const char* fieldDeclType(int nCol);
-
- int fieldDataType(int nCol);
-
-
-
- const char* fieldValue(int nField);
-
- const char* fieldValue(const char* szField);
-
-
-
- int getIntField(int nField, int nNullValue=0);
-
- int getIntField(const char* szField, int nNullValue=0);
-
-
-
- double getFloatField(int nField, double fNullValue=0.0);
-
- double getFloatField(const char* szField, double fNullValue=0.0);
-
-
-
- const char* getStringField(int nField, const char* szNullValue="");
-
- const char* getStringField(const char* szField, const char* szNullValue="");
-
-
-
- const unsigned char* getBlobField(int nField, int& nLen);
-
- const unsigned char* getBlobField(const char* szField, int& nLen);
-
-
-
- bool fieldIsNull(int nField);
-
- bool fieldIsNull(const char* szField);
-
-
-
- bool eof();
-
-
-
- void nextRow();
-
-
-
- void finalize();
-
-
-
-private:
-
-
-
- void checkVM();
-
-
-
- sqlite3* mpDB;
-
- sqlite3_stmt* mpVM;
-
- bool mbEof;
-
- int mnCols;
-
- bool mbOwnVM;
-
-};
-
-
-
-
-
-class CppSQLite3Table
-
-{
-
-public:
-
-
-
- CppSQLite3Table();
-
-
-
- CppSQLite3Table(const CppSQLite3Table& rTable);
-
-
-
- CppSQLite3Table(char** paszResults, int nRows, int nCols);
-
-
-
- virtual ~CppSQLite3Table();
-
-
-
- CppSQLite3Table& operator=(const CppSQLite3Table& rTable);
-
-
-
- int numFields();
-
-
-
- int numRows();
-
-
-
- const char* fieldName(int nCol);
-
-
-
- const char* fieldValue(int nField);
-
- const char* fieldValue(const char* szField);
-
-
-
- int getIntField(int nField, int nNullValue=0);
-
- int getIntField(const char* szField, int nNullValue=0);
-
-
-
- double getFloatField(int nField, double fNullValue=0.0);
-
- double getFloatField(const char* szField, double fNullValue=0.0);
-
-
-
- const char* getStringField(int nField, const char* szNullValue="");
-
- const char* getStringField(const char* szField, const char* szNullValue="");
-
-
-
- bool fieldIsNull(int nField);
-
- bool fieldIsNull(const char* szField);
-
-
-
- void setRow(int nRow);
-
-
-
- void finalize();
-
-
-
-private:
-
-
-
- void checkResults();
-
-
-
- int mnCols;
-
- int mnRows;
-
- int mnCurrentRow;
-
- char** mpaszResults;
-
-};
-
-
-
-
-
-class CppSQLite3Statement
-
-{
-
-public:
-
-
-
- CppSQLite3Statement();
-
-
-
- CppSQLite3Statement(const CppSQLite3Statement& rStatement);
-
-
-
- CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM);
-
-
-
- virtual ~CppSQLite3Statement();
-
-
-
- CppSQLite3Statement& operator=(const CppSQLite3Statement& rStatement);
-
-
-
- int execDML();
-
-
-
- CppSQLite3Query execQuery();
-
-
-
- void bind(int nParam, const char* szValue);
-
- void bind(int nParam, const int nValue);
-
- void bind(int nParam, const double dwValue);
-
- void bind(int nParam, const unsigned char* blobValue, int nLen);
-
- void bindNull(int nParam);
-
-
-
- void reset();
-
-
-
- void finalize();
-
-
-
-private:
-
-
-
- void checkDB();
-
- void checkVM();
-
-
-
- sqlite3* mpDB;
-
- sqlite3_stmt* mpVM;
-
-};
-
-
-
-
-
-class CppSQLite3DB
-
-{
-
-public:
-
-
-
- CppSQLite3DB();
-
-
-
- virtual ~CppSQLite3DB();
-
-
-
- void open(const char* szFile);
-
-
-
- void close();
-
-
-
- bool tableExists(const char* szTable);
-
-
-
- int execDML(const char* szSQL);
-
-
-
- CppSQLite3Query execQuery(const char* szSQL);
-
-
-
- int execScalar(const char* szSQL);
-
-
-
- CppSQLite3Table getTable(const char* szSQL);
-
-
-
- CppSQLite3Statement compileStatement(const char* szSQL);
-
-
-
- sqlite_int64 lastRowId();
-
-
-
- void interrupt() { sqlite3_interrupt(mpDB); }
-
-
-
- void setBusyTimeout(int nMillisecs);
-
-
-
- static const char* SQLiteVersion() { return SQLITE_VERSION; }
-
-
-
-private:
-
-
-
- CppSQLite3DB(const CppSQLite3DB& db);
-
- CppSQLite3DB& operator=(const CppSQLite3DB& db);
-
-
-
- sqlite3_stmt* compile(const char* szSQL);
-
-
-
- void checkDB();
-
-
-
- sqlite3* mpDB;
-
- int mnBusyTimeoutMs;
-
-};
-
-
-
-#endif
-
+++ /dev/null
-namespace creaImageIO
-{
- /**
- * \ingroup View
- */
- //=====================================================================
-
- //=====================================================================
- ///Abstract class that handles views, attributes and previews (GUI) for Gimmick.
- class GimmickView
- {
- public:
- /// Ctor
- GimmickView();
- /// Virtual destructor
- virtual ~GimmickView();
-
- //====================================================================
- // General
- //====================================================================
-
- /// Returns the size of the current selection
- virtual int GetSelectionSize() { return 0; }
- /// Returns true if there is a valid selection
- virtual bool IsSelectionValid(){ return false; }
- /// Returns the vector of full filenames of selected images
- virtual void GetSelectedFiles(std::vector<std::string>&){ return; }
- /// Returns the vector of images corresponding to selection
- virtual void GetSelectedImages(std::vector<vtkImageData*>&){ return; }
- /// Returns the vector of DicomNode corresponding to selection
- virtual void GetSelectedDicomNodes(std::vector<DicomNode*>&){ return; }
- /// Returns the DicomNode corresponding to the tree item
- virtual DicomNode* GetDicomNodeOfItem(const TreeItemId& i);
-
-
- /// Type of list of DicomDatabase
- typedef std::vector<DicomDatabase*> DicomDatabaseListType;
- /// Returns the list of DicomDatabase open
- virtual DicomDatabaseListType& GetDicomDatabaseList()
- { return null; }
- /// Returns the list of DicomDatabase open (const)
- virtual const DicomDatabaseListType& GetDicomDatabaseList() const
- { return null; }
-
- protected:
- ///Opens an existing database, or else, creates a local database.
- virtual void OpenOrNewDatabase(bool open){ return; }
- ///Shows the help
- virtual void ShowHelp();
-
- private:
- ///Gets the extension of the database
- const std::string& GetDatabaseExtension() { return null; }
- ///Sets the extension of the database
- virtual void SetDatabaseExtension(const std::string& ext){ return; }
-
-
- //====================================================================
- // Preview Display Related
- //====================================================================
-
-
- ///Shows the image sent as a parameter
- private:
- virtual void ShowImage(vtkImageData* image){ return; }
-
- //====================================================================
- // Favorites Related
- //====================================================================
-
-
- public:
- ///Loads or creates a favorites database
- virtual void LoadOrCreateFavoritesDatabase(){ return; }
- private:
- ///Creates the user settings directory
- void CreateUserSettingsDirectory(){ return; }
- ///Obtains the user settings directory
- const std::string& GetUserSettingsDirectory(){ return null; }
-
- //====================================================================
- // Attribute Display Related
- //====================================================================
-
-
- ///Shows the Information regarding the node sent as a parameter
- private:
- virtual void ShowInformation(DicomNode*){ return; }
-
- //====================================================================
- // Tree Display Related
- //====================================================================
-
- protected:
- /// Completely rebuilds the view with
- /// current DicomDatabaseList
- virtual void RebuildView(){ return; }
- /// Recursively updates the part of the view corresponding
- /// to the DicomDatabase passed
- /// i.e. creates items for the DicomNode which do not have
- /// deletes obsolete items (whose DicomNode has been deleted)
- virtual void UpdateDicomDatabaseView(DicomDatabase*){ return; }
- /// Recursively updates the part of the view corresponding
- /// to the DicomNode provided.
- /// parent is its parent in the tree (where to insert / remove it)
- virtual void UpdateDicomNodeView(DicomNode* n, const TreeItemId& parent){ return; }
-
- private:
- ///Type definition of the data regarding the tree
- typedef WxGimmickTreeItemData TreeItemData;
- ///Gets the item data of the tree item passed as a parameter
- TreeItemData* GetItemData(const TreeItemId& id){ return null; }
- ///Type definition of the data insid a node of the tree
- typedef WxGimmickDicomNodeData NodeData;
-
-
- //====================================================================
- // Class Attributes
- //====================================================================
-
-
- int mSelectionType;
- int mSelectionMaxImageDimension;
- int mCurrentSelectionImageSize[4];
-
- ///Existent Database List
- DicomDatabaseListType mDicomDatabaseList;
- ///Favorites database
- DicomDatabase* mFavoriteDatabase;
-
- ///Path to the database list file
- std::string mDatabaseListFile;
- ///Extension of the database
- std::string mDatabaseExtension;
-
- bool mJustStarted;
-
- int mFirstDicomDatabaseIconIndex;
-
- // Previewer
- vtkImageViewer2* mViewer;
-
- int mx1,mx2,my1,my2,mz1,mz2;
- double mspx,mspy,mspz;
-
- // Image preview :
- // Multi-thread image reader
- MultiThreadImageReader mReader;
- // map of images name to node
- std::map<std::string,DicomNode*> mImageFileNameToNode;
-
- //Controller which manages the interaction with the model
- Gimmick* controller;
-
- };
- // EO class GimmickView
- //=====================================================================
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
\ No newline at end of file
+++ /dev/null
-New architecture created on 04/02/09 following a MVC approach
-
-Elements of the architecture:
-
-* Data structure: Attributed tree
---------------------------------------
-in namespace creaImageIO::tree
-Tree : Attributed tree structure
- inherits Node
- holds a vector of root TreeNode
-TreeData : Abstract class to store user data on a tree
-Node :
- belong to a Tree,
- holds a pointer on parent Node,
- holds a vector of children Node
-NodeData : Abstract class to store user data on a tree node
-Descriptor : Descriptor of the structure a tree (number of levels, descriptors of each level, ...)
-
- holds a vector of LevelDescriptor
-LevelDescriptor :
- holds a vector of TreeAttributeDescriptor
-AttributeDescriptor :
- stores name, dicom group/elem, flags
-Comparator: Abstract definition of a comparator of Node
- Comparison is done by operator()(Node* const &, Node* const &)
-ComparatorWithOrder : Abstract Comparator whose order can be reversed
- Concrete comparison is done by method compare(Node* const &, Node* const &)
-LexicographicalComparator : A Comparator which stores a vector of Comparators and which performs lexicographical comparison
-
-IntComparator : Compares the values of a given Attribute of the Nodes which is decoded as an int value
-FloatComparator : Compares the values of a given Attribute of the Nodes which is decoded as a float value
-StringComparator : Compares the values of a given Attribute of the Nodes which is decoded as a string value
-
-
-* Models : TreeHandler and descendants
---------------------------------------
-
-TreeHandler : Abstract class which 'handles' a Tree structure.
- Can:
- Load the children of a given Node
-
-SQLiteTreeHandler : Concrete TreeHandler which manages a tree stored in a sqlite database
-CppSQLite3.h / CppSQLite3.cpp : C++ interface to sqlite db
-...
-
-ImageFinder : Parses (recursively) a part of a filesystem to look for known images and load their attributes in order to add the images to a Tree (submission via a TreeHandler::AddBranch)
-
-
-* Image handling
-----------------
-
-creaImageIOImageReader.h/cpp :
-SpecificImageReader
-ImageReader
-
-creaImageIOMultiThreadImageReader.h/cpp
-creaImageIOIndexedHeap.h/cpp
-
-* Views :
----------
-TreeView
-WxTreeView
-WxGimmickView
-QTreeView
-QGimmickView
-...
-
-* Controller :
---------------
-Gimmick
-...
+++ /dev/null
-#ifndef __creaImageIOAbstractImageReader_h_INCLUDED__
-#define __creaImageIOAbstractImageReader_h_INCLUDED__
-
-
-#include <vtkImageData.h>
-#include <string>
-#include <map>
-#include <vector>
-#include "creaImageIOTreeAttributeMapType.h"
-
-namespace creaImageIO
-{
-
-
- /**
- * \ingroup IO
- */
-
- //=====================================================================
- /// Abstract image reader
- class AbstractImageReader
- {
- public:
- AbstractImageReader() {}
- virtual ~AbstractImageReader() {}
-
- /// Get the reader's name
- const std::string& GetName() const { return mName; }
-
- /// Add file extensions read by the reader
- virtual void PushBackExtensions(std::vector<std::string>&) {}
-
- /// Test if file is read by this reader
- virtual bool CanRead(const std::string& filename) { return false; }
-
- /// return for a file a 2D VTkImage
- virtual vtkImageData* ReadImage(const std::string& filename) { return 0; }
-
- /// Read the attributes for a file
- virtual void ReadAttributes(const std::string& filename,
- tree::AttributeMapType& attr) {}
-
- protected:
-
- /// Set the reader's name
- void SetName(const std::string& s) { mName = s; }
- private:
- std::string mName;
- };
- //=====================================================================
-
-
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIOAbstractImageReader_h_INCLUDED__
+++ /dev/null
-#include <creaImageIODicomImageReader.h>
-
-#include <vtkGdcmReader.h>
-
-
-
-#include <creaImageIOSystem.h>
-#include "boost/filesystem/path.hpp"
-
-#include <creaImageIOTreeAttributeDescriptor.h>
-#include <vtkStringArray.h>
-#include <creaImageIOGimmick.h>
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-namespace creaImageIO
-{
-
- //=====================================================================
- DicomImageReader::DicomImageReader()
- {
- mReader = vtkGdcmReader::New();
-//EED mReader->SetFlipY(false);
- SetName ( "Dicom" );
-
- };
- //=====================================================================
-
- //=====================================================================
- DicomImageReader::~DicomImageReader()
- {
- mReader->Delete();
- }
- //=====================================================================
-
- //=====================================================================
- bool DicomImageReader::CanRead(const std::string& filename)
- {
- GDCM_NAME_SPACE::Document*doc;
- GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
- file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
- file->SetFileName(filename.c_str());
- file->Load();
- bool ok = file->IsReadable();
- if(!ok)
- {
- doc = (GDCM_NAME_SPACE::Document*)file;
- ok = doc->IsReadable();
- }
- file->Delete();
- return ok;
- }
- //=====================================================================
-
- //=====================================================================
- vtkImageData* DicomImageReader::ReadImage(const std::string& filename)
- {
- vtkImageData* im = 0;
- try
- {
- mReader->SetFileName(filename.c_str());
- mReader->Update();
- im = vtkImageData::New();
- im->ShallowCopy(mReader->GetOutput());
- }
- catch (...)
- {
- if (im!=0) im->Delete();
- im = 0;
- }
- return im;
- }
-
- //=====================================================================
- void DicomImageReader::PushBackExtensions(std::vector<std::string>& v)
- {
- v.push_back("dcm");
- v.push_back("");
- }
- //=====================================================================
-
- //========================================================================
- std::string irclean(const std::string& str)
- {
- if(str.size() > 0)
- {
- if (str == "GDCM::Unfound")
- {
- return "";
- }
- if (str[str.size()-1]==' ')
- {
- return irclean(str.substr(0,str.size()-1));
- }
- if (str[str.size()-1]==0)
- {
- return irclean(str.substr(0,str.size()-1));
- }
- }
-
- return str;
- }
- //========================================================================
-
- //=====================================================================
- void DicomImageReader::ReadAttributes(const std::string& filename,
- std::map<std::string,std::string>& attr)
- {
- GimmickMessage(2,"Reading attributes from DICOM file '"
- <<filename<<"'"<<std::endl);
-
- //GDCM_NAME_SPACE::File* file = GDCM_NAME_SPACE::File::New();
- boost::shared_ptr<GDCM_NAME_SPACE::File> file(GDCM_NAME_SPACE::File::New(), DicomImageReader::deleter());
-
- GDCM_NAME_SPACE::Document *doc= GDCM_NAME_SPACE::File::New();
- doc->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
- doc->SetFileName(filename.c_str());
- doc->Load();
- file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL);
- file->SetFileName(filename.c_str());
- file->Load();
- if (file->IsReadable())// ||((GDCM_NAME_SPACE::Document*) file)->IsReadable())
- {
- std::map<std::string,std::string>::iterator i;
- for (i=attr.begin();i!=attr.end();++i)
- {
- if ( i->first == "D0004_1500" )
- {
- boost::filesystem::path full_path(filename);
- std::string f = full_path.leaf();
- i->second = f;
- }
- else if ( i->first == "FullFileName" )
- {
- i->second = filename;
- }
- else if ( i->first == "FullFileDirectory" )
- {
- std::string::size_type last_pos = filename.find_last_of("//");
- //find first separator
- i->second = filename.substr(0, last_pos);
- }
- else
- {
- uint16_t el;
- uint16_t gr;
-
- tree::AttributeDescriptor::GetDicomGroupElementFromKey(i->first,gr,el);
- if ( ( gr!=0 ) && ( el!=0 ) )
- {
- std::string val = file->GetEntryString(gr,el);
- i->second = irclean(val);
- }
- }
- }
- }
- }
-
- //=====================================================================
-
-} // namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIODicomImageReader_h_INCLUDED__
-#define __creaImageIODicomImageReader_h_INCLUDED__
-
-
-#include <creaImageIOAbstractImageReader.h>
-#include <gdcmFile.h>
-// forward decl
-class vtkGdcmReader;
-
-namespace creaImageIO
-{
-
-
- /**
- * \ingroup IO
- */
-
- //=====================================================================
- /// Concrete image reader for DICOM images
- class DicomImageReader : virtual public AbstractImageReader
- {
- public:
- DicomImageReader();
- virtual ~DicomImageReader();
-
- /// Add file extensions read by the reader
- virtual void PushBackExtensions(std::vector<std::string>&);
- /// Test if file is read by this reader
- virtual bool CanRead(const std::string& filename);
- /// return for a file a 2D VTkImage
- virtual vtkImageData* ReadImage(const std::string& filename);
- /// Read the attributes for a file
- virtual void ReadAttributes(const std::string& filename,
- tree::AttributeMapType& attr);
-
- private:
- vtkGdcmReader* mReader;
- struct deleter
- {
- void operator()(GDCM_NAME_SPACE::File* p)
- {
- p->Delete();
- }
- };
- friend struct deleter;
- };
- //=====================================================================
-
-
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIODicomImageReader_h_INCLUDED__
+++ /dev/null
-#include <creaImageIODicomImageReader2.h>
-
-
-
-#include <creaImageIOSystem.h>
-#include "boost/filesystem/path.hpp"
-
-#include <creaImageIOTreeAttributeDescriptor.h>
-#include <vtkStringArray.h>
-#include <creaImageIOGimmick.h>
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-namespace creaImageIO
-{
-
- //=====================================================================
- DicomImageReader::DicomImageReader()
- {
- mReader = vtkGDCMImageReader::New();
- SetName ( "Dicom" );
-
- };
- //=====================================================================
-
- //=====================================================================
- DicomImageReader::~DicomImageReader()
- {
- mReader->Delete();
- }
- //=====================================================================
-
- //=====================================================================
- bool DicomImageReader::CanRead(const std::string& filename)
- {
- gdcm::Reader reader;
- reader.SetFileName( filename.c_str() );
- return reader.Read();
-
- }
- //=====================================================================
-
- //=====================================================================
- vtkImageData* DicomImageReader::ReadImage(const std::string& filename)
- {
- vtkImageData* im = 0;
- try
- {
- mReader->SetFileName(filename.c_str());
- mReader->Update();
- im = vtkImageData::New();
- im->ShallowCopy(mReader->GetOutput());
- }
- catch (...)
- {
- if (im!=0) im->Delete();
- im = 0;
- }
- return im;
- }
-
- //=====================================================================
- void DicomImageReader::PushBackExtensions(std::vector<std::string>& v)
- {
- v.push_back("dcm");
- v.push_back("");
- }
- //=====================================================================
-
- //========================================================================
- std::string irclean(const std::string& str)
- {
- if(str.size() > 0)
- {
- if (str == "GDCM::Unfound")
- {
- return "";
- }
- if (str[str.size()-1]==' ')
- {
- return irclean(str.substr(0,str.size()-1));
- }
- if (str[str.size()-1]==0)
- {
- return irclean(str.substr(0,str.size()-1));
- }
- }
-
- return str;
- }
- //========================================================================
-
- //=====================================================================
- void DicomImageReader::ReadAttributes(const std::string& filename,
- std::map<std::string,std::string>& attr)
- {
- GimmickMessage(2,"Reading attributes from DICOM file '"
- <<filename<<"'"<<std::endl);
-
-
- gdcm::Reader reader;
- reader.SetFileName( filename.c_str() );
- if (reader.Read())
- {
- std::map<std::string,std::string>::iterator i;
- for (i=attr.begin();i!=attr.end();++i)
- {
- if ( i->first == "D0004_1500" )
- {
- boost::filesystem::path full_path(filename);
- std::string f = full_path.leaf();
- i->second = f;
- }
- else if ( i->first == "FullFileName" )
- {
- i->second = filename;
- }
- else if ( i->first == "FullFileDirectory" )
- {
- std::string::size_type last_pos = filename.find_last_of("//");
- //find first separator
- i->second = filename.substr(0, last_pos);
- }
- else
- {
- uint16_t el;
- uint16_t gr;
-
- tree::AttributeDescriptor::GetDicomGroupElementFromKey(i->first,gr,el);
- if ( ( gr!=0 ) && ( el!=0 ) )
- {
- gdcm::DataElement de( gdcm::Tag(gr,el) );
- std::string val = GetStringValueFromTag(reader.GetFile().GetDataSet().GetDataElement(gdcm::Tag(gr,el)));
- i->second = irclean(val);
- }
- }
- }
- }
- }
-
- const std::string DicomImageReader::GetStringValueFromTag(const gdcm::DataElement& de)
-{
- static std::string buffer;
- buffer = ""; // cleanup previous call
-
-
- const gdcm::ByteValue *bv = de.GetByteValue();
- if( bv ) // Can be Type 2
- {
- buffer = std::string( bv->GetPointer(), bv->GetLength() );
- // Will be padded with at least one \0
- }
-
-
- // Since return is a const char* the very first \0 will be considered
- return buffer.c_str();
-}
- //=====================================================================
-
-} // namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIODicomImageReader_h_INCLUDED__
-#define __creaImageIODicomImageReader_h_INCLUDED__
-
-
-#include <creaImageIOAbstractImageReader.h>
-#if defined(USE_GDCM2)
-#include <gdcmReader.h>
-#include <vtkGDCMImageReader.h>
-#endif
-
-class vtkGDCMImageReader;
-
-namespace creaImageIO
-{
-
-
- /**
- * \ingroup IO
- */
-
- //=====================================================================
- /// Concrete image reader for DICOM images
- class DicomImageReader : virtual public AbstractImageReader
- {
- public:
- DicomImageReader();
- virtual ~DicomImageReader();
-
- /// Add file extensions read by the reader
- virtual void PushBackExtensions(std::vector<std::string>&);
- /// Test if file is read by this reader
- virtual bool CanRead(const std::string& filename);
- /// return for a file a 2D VTkImage
- virtual vtkImageData* ReadImage(const std::string& filename);
- /// Read the attributes for a file
- virtual void ReadAttributes(const std::string& filename,
- tree::AttributeMapType& attr);
-
- private:
- const std::string GetStringValueFromTag( const gdcm::DataElement& ds);
- vtkGDCMImageReader *mReader;
- struct deleter
- {
- void operator()(gdcm::File* p)
- {
- delete p;
- }
- };
- friend struct deleter;
- };
- //=====================================================================
-
-
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIODicomImageReader_h_INCLUDED__
+++ /dev/null
-#include <creaImageIOExternalGimmick.h>
-
-
-vtkImageData* getImageDataDialog() {
- // wxApp::OnInit();
- #ifdef __WXGTK__
- //See http://www.wxwindows.org/faqgtk.htm#locale
- setlocale(LC_NUMERIC, "C");
- #endif
- wxInitAllImageHandlers();
-
- creaImageIO::SetGimmickMessageLevel(5);
- creaImageIO::SetGimmickDebugMessageLevel(0);
-
- int min_dim = GIMMICK_2D_IMAGE_SELECTION;
- int max_dim = GIMMICK_3D_IMAGE_SELECTION;
- int output_dim = NATIVE;
- int threads = 1;
-
- creaImageIO::WxGimmickReaderDialog w(
- 0,
- -1,
- "localdatabase_Descriptor.dscp",
- "Local Database",
- _T("Select image(s) - Gimmick! (c) CREATIS-LRMN 2008"),
- wxDefaultPosition,
- wxSize(1200,800),
- min_dim,
- max_dim,
- output_dim,
- threads);
- w.ShowModal();
-
- if (w.GetReturnCode() == wxID_OK)
- {
- std::cout << "$$$$ main : user clicked 'OK' $$$$"<<std::endl;
- std::cout << "$$$$ selected files : "<<std::endl;
- //Puts filenames
- std::vector<std::string> s;
- w.GetSelectedFiles(s);
- std::vector<std::string>::iterator i;
- for (i=s.begin();i!=s.end();++i)
- {
- std::cout << *i << std::endl;
- }
- std::cout << "$$$$ "<<std::endl;
-
- //Puts images
- std::vector<vtkImageData*> images;
- w.GetSelectedImages(images,output_dim);
- std::cout<<images.size()<<std::endl;
-
- w.OnExit();
- return images[0];
-
- //crea::VtkBasicSlicer(images.front());
- //images.front()->Delete();
-
-
- }
- else if (w.GetReturnCode() == wxID_CANCEL)
- {
- w.OnExit();
- std::cout << "$$$$ main : user clicked 'CANCEL' $$$$"<<std::endl;
- }
- else
- {
- w.OnExit();
- std::cout << "$$$$ main : dialog ended without return code ! $$$$"
- <<std::endl;
- }
-
- // std::cout << "$$$$ main : deleting dialog"<<std::endl;
- // delete w;
- std::cout << "$$$$$$$$$$$$$$$$$$$$ main ended "<<std::endl;
- return NULL;
- }
-
-
+++ /dev/null
-#ifndef __creaImageIOExternalGimmick_h_INCLUDED__
-#define __creaImageIOExternalGimmick_h_INCLUDED__
-
-#include "creaImageIOGimmickReaderDialog.h"
-#include <creaImageIOWxGimmickReaderDialog.h>
-
- extern "C"
- {
- CREAIMAGEIO_EXPORT vtkImageData* getImageDataDialog();
- }
-#endif
-
+++ /dev/null
-
-#include <creaImageIOGimmick.h>
-
-#include <creaImageIOSystem.h>
-#include <boost/filesystem.hpp>
-#include <boost/algorithm/string.hpp>
-//#include "io.h"
-#ifndef PATH_MAX // If not defined yet : do it
-# define PATH_MAX 2048
-#endif
-#include <creaImageIOGimmick.h>
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-
-
-namespace creaImageIO
-{
- //==============================================================
- Gimmick::Gimmick()
- : mImageAdder(0)
- {
- RegisterGimmickMessageTypes();
- mSettings=0;
- mSynchronizer=0;
- mLocalDescpName = "localdatabase_Descriptor.dscp";
- mLocalDBName = "Local database";
- }
- //==============================================================
-
-
- //==============================================================
- Gimmick::~Gimmick()
- {
-
- if(mSettings!=0)
- {
- mSettings->writeSettingsFile();
- delete mSettings;
- }
- if(mSynchronizer!=0)
- {
- delete mSynchronizer;
- }
- }
- //==============================================================
-
- //==============================================================
- void Gimmick::Initialize(const std::string i_namedescp, const std::string i_namedb)
- {
- mLocalDescpName = i_namedescp;
- mLocalDBName = i_namedb;
- Initialize();
- }
-
- //==============================================================
- void Gimmick::Initialize()
- {
- std::string i_nameDB = mLocalDBName;
- // Create the UserSettings dir if does not exist
- CreateUserSettingsDirectory();
- // Sets the current directory to the home dir
- mCurrentDirectory = GetHomeDirectory();
- mSynchronizer= new Synchronizer(GetUserSettingsDirectory()+"Shared/gimmick/");
-
- mSettings = new Settings(mCurrentDirectory);
-
- std::string dbpath = GetLocalDatabasePath();
-
- // Create or open local database
- std::string dpath= mCurrentDirectory + "/.gimmick/Shared/gimmick/" + mLocalDescpName;
-
- boost::algorithm::replace_all( dpath,
- INVALID_FILE_SEPARATOR ,
- VALID_FILE_SEPARATOR);
- mLocalDatabase = createDB(i_nameDB, dpath, dbpath);
- // Add it to the TreeHandlerMap
- mTreeHandlerMap[i_nameDB] = mLocalDatabase;
-
- //Add additional DB from user Settings
- addDBSettings();
- }
-
- ///////////////////////////////////////////////////////////////////////
- // add DB to TreeHandler Map //
- // @param i_name : DB name //
- // @param i_location : DB location //
- // return : - //
- ////////////////////////////////////////////////////////////////////////
- void Gimmick::addDB(const std::string &i_name,
- const std::string &i_location)
- {
- if(mTreeHandlerMap.find(i_name) == mTreeHandlerMap.end())
- {
- mTreeHandlerMap[i_name] = new SQLiteTreeHandler(i_location);
- mTreeHandlerMap[i_name]->Open(true);
- mSettings->addDB(i_location);
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // create a DB from a attributes descriptor file for medical images //
- // @param i_name : DB name //
- // @param i_locDesc : location of descriptor file //
- // @param i_locDB : location of DB //
- // return : the SQLiteTreeHandler object on DB //
- /////////////////////////////////////////////////////////////////////////
- SQLiteTreeHandler* Gimmick::createDB(const std::string &i_name,
- const std::string &i_locDesc,
- const std::string &i_locDB)
- {
- SQLiteTreeHandler* sqlTreeH( new SQLiteTreeHandler(i_locDB) );
- // Create or open local database
- if (! boost::filesystem::exists(i_locDB) )
- {
- std::string mess = "Local database '";
- mess += i_locDB;
- mess += "' does not exist : creating it";
- GimmickMessage(1,mess<<std::endl);
-
- // CREATING DB STRUCTURE
- sqlTreeH->GetTree().GetDescriptor().createDescriptorfromFile(i_locDesc);
- if ( ! sqlTreeH->Create(true) )
- {
- GimmickError("ERROR CREATING '"<<i_locDB<<"'");
- }
- sqlTreeH->SetAttribute(0,"Name",i_name);
- }
- else
- {
- /// Open and test it
-
- GimmickDebugMessage(1,"Opening local database '" <<i_locDB<< "' " << std::endl);
- if ( !sqlTreeH->Open(true) )
- {
- GimmickError("ERROR OPENING '"<<i_locDB<<"'");
- }
- }
- return sqlTreeH;
- }
-
- //==============================================================
- void Gimmick::Finalize()
- {
- if(mTreeHandlerMap.size() >0)
- {
- // delete SQLiteTreeHandler Object
- for( TreeHandlerMapType::const_iterator it = mTreeHandlerMap.begin();
- it!= mTreeHandlerMap.end();
- ++it)
- {
- delete it->second;
- }
- }
- }
- //==============================================================
-
- //================================================================
- // file separator
-#if defined(_WIN32)
-#define VALID_FILE_SEPARATOR "\\"
-#define INVALID_FILE_SEPARATOR "/"
-#else
-#define INVALID_FILE_SEPARATOR "\\"
-#define VALID_FILE_SEPARATOR "/"
-#endif
- //================================================================
-
- //================================================================
- const std::string& Gimmick::GetHomeDirectory()
- {
- if (mHomeDirectory.size()==0)
- {
-#if defined(__GNUC__)
- mHomeDirectory = getenv("HOME");
-#elif defined(_WIN32)
- mHomeDirectory = getenv("USERPROFILE");
-#endif
- }
- return mHomeDirectory;
- }
- //================================================================
- const std::string& Gimmick::GetUserSettingsDirectory()
- {
- if (mUserSettingsDirectory.size()==0)
- {
- mUserSettingsDirectory = GetHomeDirectory();
- mUserSettingsDirectory += "/.gimmick/";
- boost::algorithm::replace_all( mUserSettingsDirectory,
- INVALID_FILE_SEPARATOR ,
- VALID_FILE_SEPARATOR);
- }
- return mUserSettingsDirectory;
- }
- //================================================================
-
-
- //================================================================
- const std::string& Gimmick::GetLocalDatabasePath()
- {
- if (mLocalDatabasePath.size()==0)
- {
- mLocalDatabasePath = GetUserSettingsDirectory();
- mLocalDatabasePath += "Shared/gimmick/";
- mLocalDatabasePath += mLocalDBName;
- mLocalDatabasePath +=".sqlite3";
- boost::algorithm::replace_all( mLocalDatabasePath,
- INVALID_FILE_SEPARATOR ,
- VALID_FILE_SEPARATOR);
- }
- return mLocalDatabasePath;
- }
-
- //========================================================================
-
- //========================================================================
- void Gimmick::CreateUserSettingsDirectory()
- {
-
- // std::string st("C:/Documents and Settings/cervenansky/.gimmick/");
- // boost::algorithm::replace_all( st,
- // INVALID_FILE_SEPARATOR ,
- // VALID_FILE_SEPARATOR);
- //const boost::filesystem::path mpath(st);
-//C:\Documents and Settings\cervenansky\.gimmick");
- //if ( !boost::filesystem::exists( path ) ) return ;
- // boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
- // for ( boost::filesystem::directory_iterator itr( path ); itr != end_itr; ++itr )
- // {
- //// If is directory & recurse : do recurse
- // if ( boost::filesystem::is_directory(itr->status()) )
- // return;
- // }
-
- //JCP settings dir 02/10/2009
- const std::string settingsdirectory = GetUserSettingsDirectory();
- //boost::algorithm::replace_all( mUserSettingsDirectory,
- // INVALID_FILE_SEPARATOR ,
- // VALID_FILE_SEPARATOR);
-;//("E:\frederic");
- //("C:\\Documents and Settings\\cervenansky\\.gimmick\\"); // settingsdirectory );
- bool isdir = false;
- isdir = boost::filesystem::is_directory(settingsdirectory); // settingsdirectory );
- if (! isdir )
- {
- GimmickMessage(1,"Directory '"<<GetUserSettingsDirectory()<<"' "
- << "does not exist : creating it"<<std::endl);
-
- if ( ! boost::filesystem::create_directory( GetUserSettingsDirectory() ) )
- {
- GimmickError("ERROR CREATING '"<<GetUserSettingsDirectory()<<"'");
- }
- }
-
- std::string setDir=GetUserSettingsDirectory();
- boost::algorithm::replace_all( setDir,
- INVALID_FILE_SEPARATOR ,
- VALID_FILE_SEPARATOR);
- setDir+="Shared/";
- boost::filesystem::create_directory( setDir );
- setDir+="gimmick/";
- boost::filesystem::create_directory( setDir );
- setDir+=mLocalDescpName;
-
- if(!boost::filesystem::is_regular(setDir))
- {
- char name[PATH_MAX];
- crea::System::GetAppPath(name,PATH_MAX);
- std::cout<<name<<std::endl;
-
- std::string path=name;
- path=path.substr(0,path.size()-1);
- path=path.substr(0,path.find_last_of("/"));
- //Creating directories
-
-// The following stuff works on Linux, NOT CHECKED on Windows // JPR
-
-#if defined(_WIN32)
- path+="/bin/Shared/gimmick/";
-#endif
-
-#if defined (LINUX)
- path+="/../share/gimmick/";
-#endif
-#if defined(__APPLE__)
- path+="/../../../../share/gimmick/";
-#endif
-
-
-path+= mLocalDescpName;
-
- std::cout <<"From: " << path <<std::endl;
- std::cout <<"To: " << setDir <<std::endl;
- boost::algorithm::replace_all( path,
- INVALID_FILE_SEPARATOR ,
- VALID_FILE_SEPARATOR);
- boost::filesystem::copy_file(path,setDir);
- }
-
- }
- //========================================================================
-
-
- //========================================================================
- /// Sets message level
- void Gimmick::SetMessageLevel(int l)
- {
- SetGimmickMessageLevel(l);
- }
- //========================================================================
-
- //========================================================================
- /// Sets message level
- void Gimmick::SetDebugMessageLevel(int l)
- {
- SetGimmickDebugMessageLevel(l);
- }
- //========================================================================
-
- //========================================================================
- /// Returns the tree handler with the given name
- TreeHandler* Gimmick::GetTreeHandler(const std::string& name) const
- {
- TreeHandlerMapType::const_iterator i;
- i = GetTreeHandlerMap().find(name);
- if ( i == GetTreeHandlerMap().end() )
- {
- GimmickError("TreeHandler '"<<name<<"' does not exist");
- }
- return i->second;
- }
-
- //========================================================================
- /// Add the files to the tree handler
- void Gimmick::AddFiles(const std::string& d,
- const std::vector<std::string>& filenames)
- {
- GimmickMessage(2,"Adding files to '"<<d<<"'"<<std::endl);
-
- mImageAdder.SetCurrentDatabase(d);
- mImageAdder.SetTreeHandler(GetTreeHandler(d));
- mImageAdder.SetSynchronizer(mSynchronizer);
- mImageAdder.AddFiles(filenames);
- }
- //========================================================================
-
- //========================================================================
- /// Add a dir to the local database
- void Gimmick::AddDir(const std::string& d, const std::string& f,
- bool recurse)
- {
- GimmickMessage(2,"Adding dir '"<<f<<"' to '"<<d<<"' recurse:"
- <<recurse<<std::endl);
-
- TreeHandler * handler=GetTreeHandler(d);
- mImageAdder.SetCurrentDatabase(d);
- mImageAdder.SetTreeHandler(handler);
- mImageAdder.SetSynchronizer(mSynchronizer);
- mImageAdder.AddDirectory(f,recurse);
- }
-
- //========================================================================
-
- //========================================================================
- void Gimmick::RemoveFile(const std::string& d,
- tree::Node* node)
- {
- mImageAdder.SetCurrentDatabase(d);
- mImageAdder.SetSynchronizer(mSynchronizer);
- mImageAdder.RemoveFile(node);
- }
- //========================================================================
-
- //========================================================================
-
- void Gimmick::CopyFiles(const std::vector<std::string>& filenames, const std::string& d )
- {
- TreeHandler * handler=GetTreeHandler(d);
- mImageAdder.SetCurrentDatabase(d);
- mImageAdder.SetTreeHandler(handler);
- mImageAdder.SetSynchronizer(mSynchronizer);
- mImageAdder.CopyFiles(filenames, mSettings->getValue(SETTINGS_COPY_PATH));
- }
-
- //========================================================================
-
- std::string Gimmick::Synchronize(const std::string& d, bool repair, bool checkAttributes)
- {
- TreeHandler * handler=GetTreeHandler(d);
- mImageAdder.SetCurrentDatabase(d);
- mImageAdder.SetTreeHandler(handler);
- mImageAdder.SetSynchronizer(mSynchronizer);
- return mImageAdder.Synchronize(repair, checkAttributes);
- }
-
- //========================================================================
- ///
- void Gimmick::Print(const std::string& d)
- {
- GetTreeHandler(d)->GetTree().Print();
- }
- //========================================================================
-
- void Gimmick::GetSetting(const std::string& name, std::string& value)
- {
- value = mSettings->getValue(name);
- }
- //========================================================================
-
- //========================================================================
-
- void Gimmick::GetAttributes(const std::string& d,
- const std::string& filename,
- const std::vector<std::string>& params,
- std::vector<std::string>& results)
- {
- TreeHandler * handler=GetTreeHandler(d);
- mImageAdder.SetCurrentDatabase(d);
- mImageAdder.SetTreeHandler(handler);
- mImageAdder.SetSynchronizer(mSynchronizer);
- mImageAdder.GetAttributes(params, filename, results);
- }
- //========================================================================
-
- //========================================================================
-
- void Gimmick::UpdateSetting(const std::string& name, const std::string& value)
- {
- mSettings->updateSetting(name,value);
- mSettings->writeSettingsFile();
- }
- //========================================================================
-
- void Gimmick::DeleteDrive(const std::string& drive)
- {
- for( TreeHandlerMapType::const_iterator it = mTreeHandlerMap.begin();
- it!= mTreeHandlerMap.end();
- ++it)
- {
- mImageAdder.SetTreeHandler(it->second);
- mImageAdder.DeleteDriveFromMainDB(drive);
- }
- mImageAdder.SetSynchronizer(mSynchronizer);
- mImageAdder.DeleteDriveFromOtherDB(drive);
- }
-
- //========================================================================
- void Gimmick::EditField(tree::Node* node, const std::string& d, const std::string& name, const std::string& key, const std::string& val)
- {
- TreeHandler * handler=GetTreeHandler(d);
- mImageAdder.SetCurrentDatabase(d);
- mImageAdder.SetTreeHandler(handler);
- mImageAdder.EditField(node,name,key,val);
- }
- //========================================================================
-
- ////////////////////////////////////////////////////////////////////////
- // add DB from Settings file //
- // @param : - //
- // return : - //
- ////////////////////////////////////////////////////////////////////////
- void Gimmick::addDBSettings()
- {
-
- std::string pathSettings = mSettings->getValue(SETTINGS_DBPATH);
-
- // split to find all paths
- std::vector<std::string> paths;
- std::string separator = ";";
- std::string::size_type last_pos = pathSettings.find_first_not_of(separator);
- //find first separator
- std::string::size_type pos = pathSettings.find_first_of(separator, last_pos);
- while(std::string::npos != pos || std::string::npos != last_pos)
- {
- paths.push_back(pathSettings.substr(last_pos, pos - last_pos));
- last_pos = pathSettings.find_first_not_of(separator, pos);
- pos = pathSettings.find_first_of(separator, last_pos);
- }
-
- std::vector<std::string>::iterator it_path = paths.begin();
- for(; it_path != paths.end(); ++it_path)
- {
- pos = it_path->find_last_of("\\");
- last_pos = it_path->find_last_of(".");
- std::string name = it_path->substr(pos +1, last_pos -pos-1 );
- addDB(name, it_path->c_str());
- }
- }
-}
+++ /dev/null
-#ifndef __creaImageIOGimmick_h_INCLUDED__
-#define __creaImageIOGimmick_h_INCLUDED__
-
-#include <creaImageIOSQLiteTreeHandler.h>
-#include <creaImageIOTreeHandlerImageAdder.h>
-#include <creaImageIOSynchron.h>
-#include <creaImageIOSettings.h>
-
-
-
-#ifdef _DEBUG
-#include <crtdbg.h>
-#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
-#else
-#define DEBUG_NEW new
-#endif
-// Only when asked
-/*
-#ifdef TRACKING_MEMORY_LEAKS
-#ifdef WIN32
-#pragma warning(disable : 4291)
-#endif
-
-void * operator new( size_t size, int line, const char *file );
-void * operator new[]( size_t size, int line, const char *file );
-void operator delete( void *p );
-void operator delete[]( void *p );
-
-#ifdef OMISCID_NEW
-#undef OMISCID_NEW
-#endif
-
-#define OMISCID_NEW new( __LINE__, __FILE__ )
-
-#else // TRACKING_MEMORY_LEAKS is not defined
-
-#define OMISCID_NEW new
-
-#endif*/
-
-
-namespace creaImageIO
-{
- /**
- * \defgroup Controller Controller
- */
- /**
- * \defgroup View View
- */
- /**
- * \defgroup Model Model
- */
- /**
- * \defgroup GUI Top level graphical user interfaces
- */
- /**
- * \defgroup IO Image I/O classes
- */
- /**
- * \defgroup Tree Attributed tree management
- */
- /**
- * \defgroup Previewer Preview related
- */
-
- /**
- * \ingroup Controller
- */
-
- //=======================================================================
- /// Central controler of the gimmick application
- class CREAIMAGEIO_EXPORT Gimmick
- {
- public:
- /// Ctor
- Gimmick();
- /// Dtor
- ~Gimmick();
-
- ///
- typedef TreeHandlerImageAdder::Progress AddProgress;
- typedef TreeHandlerImageAdder::ProgressCallbackType AddProgressCallbackType;
-
- /// Adds the function f to the list of functions to call
- /// when addition operations progres.
- /// f is of type AddProgressCallbackType which is:
- /// void (*AddProgressCallbackType)(AddProgress&)
- /// To pass a member function 'f' of an instance 'c' of a class 'C'
- /// as callback you have to 'bind' it, i.e. call:
- /// ConnectAddProgressObserver ( boost::bind( &C::f , c, _1 ) );
- void ConnectAddProgressObserver( AddProgressCallbackType callback )
- { mImageAdder.ConnectProgressObserver(callback); }
-
- ///
- const AddProgress& GetAddProgress() const { return mImageAdder.GetProgress(); }
-
- /// Initializes with default values (read/creates databases, etc.)
- void Initialize();
-
- /// Initializes with the local database descriptor in the path given (read/creates databases, etc.)
- void Initialize(const std::string namedescp, const std::string namedb = "Local Database");
-
- /// Finalize (closes databases, etc.)
- void Finalize();
-
- /// Sets level for messages "Gimmick!"
- static void SetMessageLevel(int level);
- /// Sets level for debug messages "Gimmick! DEBUG"
- static void SetDebugMessageLevel(int level);
-
- /// Type of map from TreeHandler name to TreeHandler*
- typedef std::map<std::string, TreeHandler*> TreeHandlerMapType;
-
- typedef std::map<std::string, TreeHandler*>::const_iterator ItTreeHandlerMap;
-
- /// Returns the TreeHandlerMap (ref)
- TreeHandlerMapType& GetTreeHandlerMap() { return mTreeHandlerMap; }
-
- /// Returns the TreeHandlerMap (const ref)
- const TreeHandlerMapType& GetTreeHandlerMap() const
- { return mTreeHandlerMap; }
-
- /// Add the files to the given TreeHandler
- void AddFiles(const std::string& handler,
- const std::vector<std::string>& filenames);
-
- /// Add a dir to the given TreeHandler
- void AddDir(const std::string& handler, const std::string& path,
- bool recurse);
-
- /// Removes a file from the given TreeHandler
- void RemoveFile(const std::string& d,
- tree::Node* filename);
-
- ///Deletes the given drive name from the databases
- void DeleteDrive(const std::string& drive);
-
-
- /// Copies the files into the local directory
- void CopyFiles(const std::vector<std::string>& filenames, const std::string& d );
-
-
- ///Synchronizes the loaded data with the database d. If repair is true the database will be updated, otherwise
- ///only a warning sign will be issued
- std::string Synchronize(const std::string& d, bool repair, bool checkAttributes);
-
- /// Prints the tree handled by the handler
- void Print(const std::string& handler);
-
- ///create a DB from a given descriptor file and for a specific location
- SQLiteTreeHandler* createDB(const std::string &i_name,
- const std::string &i_locDesc,
- const std::string &i_locDB);
-
- /// add an existent DB
- void addDB(const std::string &i_nameDB, const std::string &i_locationDB);
-
- /// Returns the TreeHandler with a given name
- TreeHandler* GetTreeHandler(const std::string& name) const;
-
- ///
- SQLiteTreeHandler* GetLocalDatabase() { return mLocalDatabase; }
-
- const SQLiteTreeHandler* GetLocalDatabase() const { return mLocalDatabase; }
-
- ///Returns the given setting value for the given setting parameter
- void GetSetting(const std::string& name, std::string& value);
-
- ///Updates the settings file
- void UpdateSetting(const std::string& name, const std::string& value);
-
- /// add DB from Settings file
- void addDBSettings();
-
- ///Edits the field described by the name and key provided with the value given
- void EditField(tree::Node* node, const std::string& d, const std::string& name, const std::string& key, const std::string& val);
-
- /// Returns the attributes in results described in params
- void GetAttributes(const std::string& d,
- const std::string& filename,
- const std::vector<std::string>& params,
- std::vector<std::string>& results);
-
- ///
- const std::string& GetHomeDirectory();
- const std::string& GetUserSettingsDirectory();
- void CreateUserSettingsDirectory();
- const std::string& GetLocalDatabasePath();
-
-
-
- //=============================================
- private:
- SQLiteTreeHandler* mLocalDatabase;
- TreeHandlerMapType mTreeHandlerMap;
- Synchronizer* mSynchronizer;
-
- std::string mCurrentDirectory;
- std::string mHomeDirectory;
- std::string mUserSettingsDirectory;
- std::string mLocalDatabasePath;
- Settings *mSettings;
- TreeHandlerImageAdder mImageAdder;
- std::string mLocalDBName;
- std::string mLocalDescpName;
- };
- // EO class Gimmick
- //=======================================================================
-
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
-
-
+++ /dev/null
-#include <creaImageIOGimmickReaderDialog.h>
-#include <creaImageIOWxGimmickReaderDialog.h>
-
-namespace creaImageIO
-{
-
- bool GimmickReaderDialog(std::vector<vtkImageData*>& images,
- const std::string i_namedescp ,
- const std::string i_namedb ,
- const std::string& title,
- int posx,
- int posy,
- int sizex,
- int sizey,
- int image_min_type,
- int image_max_type,
- int image_out_dim,
- int nb_threads)
- {
-
-
- creaImageIO::WxGimmickReaderDialog w(0,
- -1,
- i_namedescp,
- i_namedb,
- crea::std2wx(title),
- wxPoint(posx,posy),
- wxSize(sizex,sizey),
- image_min_type,
- image_max_type,
- nb_threads);
- w.ShowModal();
-
- if (w.GetReturnCode() == wxID_OK)
- {
- w.GetSelectedImages(images,image_out_dim);
- return true;
- }
- else if (w.GetReturnCode() == wxID_CANCEL)
- {
- return false;
- }
- else
- {
- std::cout << "!! ERROR : GimmickReaderDialog : dialog ended without return code !"
- <<std::endl;
- return false;
- }
-
-
- }
-
-}
+++ /dev/null
-#ifndef __creaImageIOGimmickReaderDialog_h_INCLUDED__
-#define __creaImageIOGimmickReaderDialog_h_INCLUDED__
-
-#include "creaImageIOSystem.h"
-#include <vtkImageData.h>
-#include <vector>
-
- extern "C"
- {
- CREAIMAGEIO_EXPORT vtkImageData* getImageDataDialog();
- }
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- * \brief Pops up a WxGimmickReaderDialog
- * returns true if the user clicked 'Ok', false if 'Cancel'
- * and fills the vector of images
- */
- bool CREAIMAGEIO_EXPORT GimmickReaderDialog
- (std::vector<vtkImageData*>& images,
- const std::string i_namedescp ,
- const std::string i_namedb = "Local Database",
- const std::string& title = "Select images",
- int posx = 0, int posy = 0,
- int sizex = 1200, int sizey = 800,
- int image_min_type = 2,
- int image_max_type = 3,
- int image_out_dim = 2,
- int nb_threads = 1);
-
-}
-
-#endif
+++ /dev/null
-#include <creaImageIOGimmickView.h>
-#include <creaImageIOSystem.h>
-#include "boost/filesystem.hpp"
-
-#if defined(USE_GDCM)
-#include <gdcmGlobal.h>
-#include <gdcmSerieHelper.h>
-#include <vtkGdcmReader.h>
-#endif
-
-#if defined(USE_GDCM2)
-#include <vtkGDCMImageReader.h>
-#endif
-
-
-namespace fs = boost::filesystem;
-namespace creaImageIO
-{
-
- ///Class used to represent the actual state of the image selected and to perform comparisons on its values
- class ImageExtent
- {
- public:
- ImageExtent(const std::string& x, const std::string& y, const std::string& z, const std::string& t)
- {
- sscanf(x.c_str(),"%d",&mExtent[0]);
- sscanf(y.c_str(),"%d",&mExtent[1]);
- sscanf(z.c_str(),"%d",&mExtent[2]);
- sscanf(t.c_str(),"%d",&mExtent[3]);
- if(x==""){mExtent[0]=1;}
- if(y==""){mExtent[1]=1;}
- if(z==""){mExtent[2]=1;}
- if(t==""){mExtent[3]=1;}
-
- if (mExtent[3]>1) mDim=4;
- else if (mExtent[2]>1) mDim=3;
- else if (mExtent[1]>1) mDim=2;
- else if (mExtent[0]>1) mDim=1;
- else mDim=0;
- }
-
-
- ///Clears the extent
- void Clear() { mExtent[0] = mExtent[1] = mExtent[2] = mExtent[3] = 1; }
-
- ///Returns true if the two extents are compatible
- bool IsCompatible( const ImageExtent& );
-
- ///Adds the extent passed as a parameter to the current extent
- void Add ( const ImageExtent& );
-
- ///Returns the ieth position of the extent
- int Get(int i) { return mExtent[i]; }
-
- ///Returns the dimension of the current image
- void SetDimension(int dim) { mDim=dim; }
-
- ///Returns the dimension of the current image
- int GetDimension() { return mDim; }
-
- private:
- int mExtent[4];
- int mDim;
- };
-
- //======================================================================
-
- //======================================================================
- // CTor
- GimmickView::GimmickView(boost::shared_ptr<Gimmick> gimmick, int threads)
- : mGimmick(gimmick),
- mReader(threads)
- {
- GimmickDebugMessage(1,"GimmickView::GimmickView"
- <<std::endl);
- // Anciently started the threads ...
- // Threads now automatically start at first image request
- //mReader.Start();
-
- }
- //======================================================================
-
- //======================================================================
- /// Destructor
- GimmickView::~GimmickView()
- {
- GimmickDebugMessage(1,"GimmickView::~GimmickView"
- <<std::endl);
- }
- //======================================================================
-
- //======================================================================
- /// Initializes the view :
- /// Creates the TreeViews for all the TreeHandler of the Controller
- ///
- void GimmickView::Initialize()
- {
- mReaderStarted=false;
- }
- //======================================================================
-
- //======================================================================
- /// Finalize
- void GimmickView::Finalize()
- {
- }
-
- //======================================================================
-
- //======================================================================
- /// Create the tree views
- void GimmickView::CreateTreeViews()
- {
- GimmickMessage(2,"Creating the tree views"<<std::endl);
- Gimmick::TreeHandlerMapType::const_iterator i;
- for (i = mGimmick->GetTreeHandlerMap().begin();
- i!= mGimmick->GetTreeHandlerMap().end();
- ++i)
- {
- this->CreateTreeView(i->second);
- }
- }
-
- /// Create a tree view with a given name
- void GimmickView::CreateSingleTreeView(std::string &i_name)
- {
- this->CreateTreeView(mGimmick->GetTreeHandlerMap()[i_name]);
-
- }
-
-
- //======================================================================
-
- //======================================================================
- /// Updates the TreeView of given name from level l to bottom
- /// (calls the virtual method TreeView::Update())
- void GimmickView::UpdateTreeViewLevel(const std::string& t, int l)
- {
- TreeViewMapType::iterator i;
- i = GetTreeViewMap().find(t);
- if ( i == GetTreeViewMap().end() )
- {
- GimmickError("INTERNAL ERROR : GimmickView::UpdateTreeView : '"
- <<t<<"' is not in TreeViewMap");
- }
- i->second->UpdateLevel(l);
- }
-
- //======================================================================
- /// Clears the status and begins a new selection process
- void GimmickView::ResetExtent()
- {
- if(mImageExtent!=0)
- {
- mImageExtent.reset();
- }
- valid=true;
- }
-
- //======================================================================
-
- //======================================================================
- bool ImageExtent::IsCompatible(const ImageExtent& ie)
- {
- bool compatible=true;
- ImageExtent * extent= (ImageExtent*)&ie;
- if((*extent).Get(0)!=Get(0)
- || (*extent).Get(1)!=Get(1))
- {
- compatible=false;
- }
- return compatible;
- }
-
- //======================================================================
-
- //======================================================================
- void ImageExtent::Add(const ImageExtent& ie)
- {
- ImageExtent * extent= (ImageExtent*)&ie;
- mExtent[2]+=(*extent).Get(2);
- if(mExtent[2]>1)
- {
- SetDimension(3);
- }
- }
-
- //======================================================================
- /// No selected image
- bool GimmickView::NoValidateSelected ()
- {
- GimmickDebugMessage(2,"Validating selected"<<std::endl);
- std::string mMessage;
- mMessage="Cannot have 0 images selected!";
- valid=false;
- modifyValidationSignal(valid);
- SetMessage(mMessage);
- return valid;
- }
-
- //======================================================================
- ///Validates the dimension compliance of the images with the maximum and
- ///minimum given, and between their sizes
- bool GimmickView::ValidateSelected (tree::Node* sel, int min_dim, int max_dim)
- {
- GimmickDebugMessage(2,"Validating selected"<<std::endl);
- std::string mMessage;
-
- if(sel==0)
- {
- mMessage="Cannot have 0 images selected!";
- valid=false;
- }
- else
- {
- boost::shared_ptr<ImageExtent> ie=boost::shared_ptr<ImageExtent>(new ImageExtent((*sel).GetAttribute("D0028_0010"),
- (*sel).GetAttribute("D0028_0011"),
- (*sel).GetAttribute("D0028_0012"),
- ""));
- if(mImageExtent==0)
- {
- mImageExtent=ie;
- if((mImageExtent->Get(min_dim-1)<2)||(mImageExtent->Get(max_dim)>1))
- {
- valid=false;
- }
- else
- {
- std::stringstream out;
- out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected";
- mMessage = out.str();
- mImageExtent->SetDimension(2);
- valid=true;
- }
- }
- else
- {
- if(mImageExtent->IsCompatible(*ie))
- {
- if(mImageExtent->GetDimension()==max_dim && mImageExtent->Get(max_dim)>2)
- {
- std::stringstream out;
- out<<"Cannot add this image to selection : would result in a "<<mImageExtent->GetDimension()+1<<"D image!";
- mMessage=out.str();
- valid=false;
- }
- else if(max_dim<3)
- {
- std::stringstream out;
- out<<"Selecting "<<mImageExtent->GetDimension()<<"D images is not allowed !";
- mMessage=out.str();
- valid=false;
- }
- else if(min_dim==3 && (ie->Get(2)+mImageExtent->Get(2))<2)
- {
- std::stringstream out;
- out << "Cannot build the selection as it would result in a ";
- out << mImageExtent->GetDimension();
- out << "D image, and the minimum is ";
- out << min_dim;
- out << "D!";
- mMessage=out.str();
- valid=false;
- }
- else
- {
- mImageExtent->Add(*ie);
- std::stringstream out;
- out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected";
- mMessage = out.str();
- }
- }
- else
- {
- mMessage="The selected images are not compatible.";
- valid=false;
- }
- }
- }
-
- modifyValidationSignal(valid);
- SetMessage(mMessage);
- return valid;
- }
-
- //======================================================================
- void GimmickView::modifyValidationSignal(bool ivalid)
- {
- mValidationSignal(ivalid);
- }
-
- //======================================================================
- ///Reads Images (Non Threaded)
-void GimmickView::ReadImagesNotThreaded(std::vector<vtkImageData*>& s, std::vector<std::string> im, int dimension)
-{
- mReader.Stop();
-/* remember!
-
-#define GIMMICK_NO_IMAGE_SELECTION 0
-#define GIMMICK_2D_IMAGE_SELECTION 2
-#define GIMMICK_3D_IMAGE_SELECTION 3
-#define GIMMICK_4D_IMAGE_SELECTION 4
-
-#define NATIVE 0
-#define _2D 2
-#define _3D 3
-
-*/
- // Create the output data
- if (im.size()==1)
- {
- vtkImageData * out=vtkImageData::New();
- out->ShallowCopy(mReader.GetImage(im.front()));
- s.push_back(out);
- }
- else if (im.size()>1) // Test inutile ? JPR
- {
- vtkImageData* first = mReader.GetImage( im.front());
- if (dimension == 2)
- {
- // n3D
- std::vector<std::string>::iterator it;
- for (it=im.begin(); it!=im.end(); ++it)
- {
- vtkImageData* out = vtkImageData::New();
- out->ShallowCopy(mReader.GetImage(*it));
- s.push_back(out);
- }
- }
- else
- {
- // n*2D to 3D
- vtkImageData* out = vtkImageData::New();
-// out->CopyStructure(first);
- out->SetScalarType(first->GetScalarType());
- out->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents());
- int ext[6];
- //first->GetExtent(ext); // JPR
- first->GetWholeExtent(ext); // renvoie egalement 0,0 en Z // JPR
-
- if(ext[5] == 0)
- {
- ext[5] = im.size()-1;
- }
- else
- {
- ext[5] = ext[5] * im.size()-1; // to deal with multiframes - JPR
- }
- out->SetExtent(ext);
-
- // LG : TODO : Z Spacing ?
-
- int dim[3];
- first->GetDimensions(dim);
-
- out->SetDimensions(dim[0], dim[1], im.size() );
- out->AllocateScalars();
- out->Update();
-
- unsigned long imsize = dim[0] * dim[1];
- imsize = imsize * dim[2] ; // deal with multiframes // JPR
-
-
-//EED 03-11-2009
- // differents formats char , short, etc...
- // differents components 1..3 ex. jpg ->RGB 3
- imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents();
-
-
- // Order the file name vector
-
- double spc[3];
- first->GetSpacing(spc);
- spc[2]=OrderTheFileNameVector(im);
-
- out->SetSpacing(spc);
-
- int slice = 0;
- std::vector<std::string>::iterator it;
-
- for (it=im.begin(); it!=im.end(); ++it)
- {
- vtkImageData* cur = mReader.GetImage( (*it) );
- memcpy(out->GetScalarPointer(0,0,slice), cur->GetScalarPointer(0,0,0), imsize);
- slice++;
- }
- s.push_back(out);
-
- } // dimension == 3
-
- } // size >1
-
-}
- //======================================================================
-
-#if defined(USE_GDCM)
- double GimmickView::OrderTheFileNameVector(std::vector<std::string> &im)
-{
- double spacing=1;
- typedef std::vector<GDCM_NAME_SPACE::File* > FileList;
- FileList fileVector;
- //GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New();
- GDCM_NAME_SPACE::SerieHelper *sh = GDCM_NAME_SPACE::SerieHelper::New();
- std::vector<std::string> lstAux;
- std::vector<std::string>::iterator it;
- for (it=im.begin(); it!=im.end(); ++it)
- {
- ///\TODO liberer les GDCM_NAME_SPACE::File a la fin! // JPR
- GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New();
- f->SetFileName(*it);
- f->Load();
- if (f->IsReadable())
- {
- fileVector.push_back(f);
- } else {
- lstAux.push_back(*it);
- }
- } // for
-
-
- if ((fileVector.size()>1) && (sh->IsCoherent( &fileVector )))
- {
- sh->OrderFileList(&fileVector);
- spacing= sh->GetZSpacing();
- im.clear();
- int i;
- for (i=0; i<fileVector.size(); i++)
- {
- im.push_back( (fileVector[i])->GetFileName() );
- }
- for (i=0; i<lstAux.size(); i++)
- {
- im.push_back( lstAux[i] );
- }
- }else {
- std::sort( im.begin(), im.end() );
- }
-
- return spacing;
-}
-
-
-#endif
-
-#if defined(USE_GDCM2)
- // TO DO
- double GimmickView::OrderTheFileNameVector(std::vector<std::string> &im)
- {
- return 1;
- }
-#endif
-//======================================================================
-
-
-void GimmickView::ReadImagesNotThreadedInVector(std::vector<vtkImageData*>& s, std::vector<std::string> im, int dimension)
-{
- // Create the output data
- if (im.size()==1)
- {
- // Only one image : give it
- vtkImageData* out = vtkImageData::New();
- GimmickDebugMessage(3, "State Check: Full Filename: "
- <<im.front()
- <<std::endl);
- out->ShallowCopy(mReader.GetImage(im.front()));
- s.push_back( out );
- }
- else if (im.size()>1) // Test inutile ? JPR
- {
- vtkImageData* first = mReader.GetImage( im.front());
- if (dimension == 2)
- {
- // n3D
- std::vector<std::string>::iterator it;
- for (it=im.begin(); it!=im.end(); ++it)
- {
- vtkImageData* out = vtkImageData::New();
- out->ShallowCopy(mReader.GetImage(*it));
- s.push_back(out);
- }
- }
- else
- {
- // n2D to 3D // NO!
- // n *2D + T in a vector :
-
- std::vector<std::string>::iterator it;
- for (it=im.begin(); it!=im.end(); ++it)
- {
- vtkImageData* out = mReader.GetImage( (*it));
- s.push_back(out);
- }
- }
- }
-}
- //======================================================================
-
- //======================================================================
- ///Requests the reading of an image
- void GimmickView::RequestReading(tree::Node* n,
- int prio, int selection_index, boost::shared_ptr<ImagePointerHolder> p)
- {
- if(!mReaderStarted)
- {
- mReader.Start();
- mReaderStarted=true;
- }
- ImageEventType t(n,selection_index);
- t.pointerHolder = p;
- mImageEventMap[n->GetAttribute("FullFileName")] = t;
- mReader.Request(this,n->GetAttribute("FullFileName"),prio);
- }
- //======================================================================
-
- //======================================================================
- void GimmickView::
- OnMultiThreadImageReaderEvent(const std::string& filename,
- MultiThreadImageReaderUser::EventType e,
- vtkImageData* image)
- {
- GimmickDebugMessage(7,
- "MultiThreadImageReader event : "<<e<<std::endl);
- if (e==ImageLoaded)
- {
- if (filename.size()==0)
- {
- //What to do in this case?
- /*
- GimmickDebugMessage(5,
- "Pushing unknown image in queue"
- <<std::endl);
- mImageEventQueue.push_back(ImageEventType(image));*/
- return;
- }
- ImageEventTypeMap::iterator i;
-//JCP 22-06-2009, test mImageEventMap.size() > 0
- if(mImageEventMap.size()>0){
- i = mImageEventMap.find(filename);
- if (i!=mImageEventMap.end())
- {
- GimmickDebugMessage(5,
- "Putting image of file '"<<filename<<"' on pointer"
- <<std::endl);
- ImageEventType ie(i->second);
- ie.image = image;
- ie.pointerHolder->Set(ie.image);
- //mImageEventMap.erase(i);
- }
- }
- }
- else if (e==Error)
- {
- std::string mess="ERROR: MultiThreadImageReader: Cannot read image in file ";
- mess+=filename;
- mess+="\n";
- GimmickMessage(1,mess);
- ImageEventTypeMap::iterator i;
- i = mImageEventMap.find(filename);
- if (i!=mImageEventMap.end())
- {
- ImageEventType ie(i->second);
- ie.image = image;
- ie.pointerHolder->Set(GetDefaultImage());
- //mImageEventMap.erase(i);
- }
- }
-
- else if (e==ImageUnloaded)
- {
- std::string mess="Unloaded image in file ";
- mess+=filename;
- mess+="\n";
- GimmickMessage(1,mess);
- ImageEventTypeMap::iterator i;
- i = mImageEventMap.find(filename);
- if (i!=mImageEventMap.end())
- {
- ImageEventType ie(i->second);
- ie.image = image;
- ie.pointerHolder->Set(GetDefaultImage());
- //mImageEventMap.erase(i);
- }
- }
- }
-
- //====================================================================
-
- //====================================================================
- void GimmickView::ConnectValidationObserver(ValidationCallbackType callback)
- {
- mValidationSignal.connect(callback);
- }
-
-} // EO namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOGimmickView_h_INCLUDED__
-#define __creaImageIOGimmickView_h_INCLUDED__
-
-#include <creaImageIOGimmick.h>
-#include <creaImageIOTreeView.h>
-#include <creaImageIOSystem.h>
-#include <creaImageIOImagePointerHolder.h>
-
-//#include <map>
-#include <vtkImageData.h>
-#include <creaImageIOMultiThreadImageReader.h>
-
-// Signal/slot mechanism for progress events
-#include <boost/signal.hpp>
-#include <boost/bind.hpp>
-
-#define GIMMICK_NO_IMAGE_SELECTION 0
-#define GIMMICK_2D_IMAGE_SELECTION 2
-#define GIMMICK_3D_IMAGE_SELECTION 3
-#define GIMMICK_4D_IMAGE_SELECTION 4
-
-#define NATIVE 0
-#define _2D 2
-#define _3D 3
-
-namespace creaImageIO
-{
- /**
- * \ingroup View
- */
-
- class ImageExtent;
- //=====================================================================
-
- //=====================================================================
- ///Abstract class that handles views, attributes and previews (GUI) for Gimmick.
- class GimmickView: public MultiThreadImageReaderUser
- {
- public:
- /// Ctor
- GimmickView(boost::shared_ptr<Gimmick>, int number_of_threads = 0 );
- /// Virtual destructor
- virtual ~GimmickView();
- /// Initializes the view :
- /// Creates the TreeViews for all the TreeHandler of the Controller
- ///
- virtual void Initialize();
-
- /// Type of map from View name to TreeView*
- /// (This map is equivalent for Views of the TreeHandlerMap of Gimmick)
- typedef std::map<std::string, TreeView*> TreeViewMapType;
-
- /// Returns the TreeViewMap (ref)
- TreeViewMapType& GetTreeViewMap() { return mTreeViewMap; }
- /// Returns the TreeViewMap (const ref)
- const TreeViewMapType& GetTreeViewMap() const
- { return mTreeViewMap; }
-
- /// Finalize
- virtual void Finalize();
-
- ///Returns the maximal priority
- int GetMaximalPriority(){return mReader.GetMaximalPriority();}
-
- ///Adds the selected Images to the given vector
- virtual void GetSelectedImagesInVector(std::vector<vtkImageData*>& s, int dim)
- { GimmickError("INTERNAL ERROR : GetSelectedImagesInVector not implemented"); }
-
- ///Adds the selected Images to the given vector and validates to see if they comply with the given parameter (4D)
- virtual void GetSelectedImages(std::vector<vtkImageData*>& s, int dim)
- { GimmickError("INTERNAL ERROR : GetSelectedImages not implemented"); }
-
- virtual void GetSelectedFiles(std::vector<std::string>& s)
- { GimmickError("INTERNAL ERROR : GetSelectedFiles not implemented"); }
-
- virtual void GetImages(int dim, std::vector<std::string> files, std::vector<vtkImageData*>& s)
- { GimmickError("INTERNAL ERROR : GetImages not implemented"); }
-
- virtual void OnSelectionChange(const std::vector<tree::Node*>& s, bool isSelection, int selection, bool mProcess)
- { GimmickError("INTERNAL ERROR : OnSelectionChange not implemented"); }
-
- virtual void ClearSelection()
- { GimmickError("INTERNAL ERROR : ClearSelection not implemented"); }
-
- ///Adds a file to ignore
- virtual void AddIgnoreFile(tree::Node* toRemove)
- { GimmickError("INTERNAL ERROR : AddIgnoreFile not implemented"); }
-
- ///Copies selected files
- virtual void CopyFiles(const std::vector<std::string>& filenames)
- { GimmickError("INTERNAL ERROR : CopyFiles not implemented"); }
-
- ///Edits the fields of a given node
- virtual void CreateEditFieldsDialog(tree::Node* node, std::vector<std::string> names, std::vector<std::string> keys)
- { GimmickError("INTERNAL ERROR : EditFields not implemented"); }
-
- /// Display all Dicom Tags
- virtual void DumpTags(const std::string filename)
- {GimmickError("INTERNAL ERROR : DumpTags not implemented"); }
-
- ///Edits the fields of a given node
- virtual void ExportToStorage(const std::vector<std::string> keys)
- { GimmickError("INTERNAL ERROR : ExportToStorage not implemented"); }
-
- ///Copies selected files
- virtual void SaveAs(const std::vector<std::string>& filenames)
- { GimmickError("INTERNAL ERROR : SaveAs not implemented"); }
-
- /// No selected image
- bool NoValidateSelected();
-
- ///Validates the dimension compliance of the images with the maximum and minimum given, and between their sizes
- bool ValidateSelected (tree::Node* sel, int min_dim, int max_dim);
-
- ///Reads the vector of images, builds it in the dimension required and returns them in the supplied vector.
- void ReadImagesNotThreaded(std::vector<vtkImageData*>& s,std::vector<std::string> files, int dim);
-
- ///Reads the vector of images, builds it in the dimension required and returns them in the supplied vector.
- void ReadImagesNotThreadedInVector(std::vector<vtkImageData*>& s,std::vector<std::string> files, int dim);
-
-///Requests the reading of an image with priority and index in the
- /// current selection (-1 if not in selection)
- //void RequestReading(tree::Node* n, int prio, int selection_index , ImagePointerHolder *p);
- void RequestReading(tree::Node* n, int prio, int selection_index , boost::shared_ptr<ImagePointerHolder> p);
-
- ///Obtains the message of the state
- std::string GetMessage(){return mMess;}
-
- ///Obtains the message of the state
- void SetMessage(std::string mess){mMess=mess;}
-
- ///Resets the data of the extent and begins a new selection
- void ResetExtent();
-
- /// Create the tree views
- void CreateTreeViews();
-
- /// Create a tree view with a given name
- void CreateSingleTreeView(std::string &i_name);
-
- /// Create the tree view for TreeHandler provided
- virtual void CreateTreeView( TreeHandler* )
- { GimmickError("INTERNAL ERROR : CreateTreeView not implemented"); }
-
- /// Updates the TreeView of given name from level l to bottom
- /// (calls the virtual method TreeView::UpdateLevel(l))
- virtual void UpdateTreeViewLevel(const std::string&, int l);
-
- // Multi-thread image reader callback
- void OnMultiThreadImageReaderEvent(const std::string& filename,
- MultiThreadImageReaderUser::EventType t,
- vtkImageData* image);
-
- vtkImageData* GetDefaultImage() { return mReader.GetImage(""); }
-
- //=============================================
- typedef boost::signal<void (bool)> ValidationSignalType;
- typedef ValidationSignalType::slot_function_type ValidationCallbackType;
- //=============================================
-
- //==================================================================
- /// Adds the function f to the list of functions to call
- /// when the addition progresses.
- /// f is of type ProgressCallbackType which is:
- /// void (*ProgressCallbackType)(Progress&)
- /// To pass a member function 'f' of an instance 'c' of a class 'C'
- /// as callback you have to 'bind' it, i.e. call:
- /// ConnectValidationObserver ( boost::bind( &C::f , c, _1 ) );
- void ConnectValidationObserver(ValidationCallbackType callback);
- //==================================================================
-
- void modifyValidationSignal(bool ivalid);
-
- private:
-
- double OrderTheFileNameVector(std::vector<std::string> &im);
-
- /// Controller which manages the interaction with the model
- boost::shared_ptr< Gimmick> mGimmick;
-
- /// The views
- TreeViewMapType mTreeViewMap;
-
- /// The message that results from the validation
- std::string mMess;
-
- /// Multi-thread image reader
- MultiThreadImageReader mReader;
-
- /// Internal type of image reading event
- /// If the image pointer is non null then the image is available (loaded)
- /// else it has been unloaded
- struct ImageEventType
- {
- ImageEventType( tree::Node* no = 0,
- int sel_index = -1)
-// ImagePointerHolder* ph= 0)
- : node(no), index(sel_index){}//, pointerHolder(ph){}
- ImageEventType(vtkImageData* im )
- : image(im) {}
- tree::Node* node;
- vtkImageData* image;
- int index;
- boost::shared_ptr<ImagePointerHolder> pointerHolder;
- };
- typedef std::map<std::string,ImageEventType> ImageEventTypeMap;
- /// Map of images' names to ImageEventType
- /// Used to associated a filename to a the data of a request
- ImageEventTypeMap mImageEventMap;
-
- // queue of image event
- typedef std::deque<ImageEventType> ImageEventQueueType;
-
- //ImageEventQueueType mImageEventQueue;
-
- ///The current image extent
- boost::shared_ptr<ImageExtent> mImageExtent;
-
- ///The validation signal
- ValidationSignalType mValidationSignal;
-
- ///Boolean that determines if the selection is valid
- bool valid;
-
- ///Boolean that determines if the reader has been started
- bool mReaderStarted;
-
- };
- // EO class GimmickView
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
+++ /dev/null
-#ifndef __creaImageIOImagePointerHolder_INCLUDED__
-#define __creaImageIOImagePointerHolder_INCLUDED__
-
-#include <creaImageIOSystem.h>
-#include <vtkImageData.h>
-#include <boost/thread/mutex.hpp>
-
-
-namespace creaImageIO
-{
- // The class that holds the pointer to the images to show
- class ImagePointerHolder
- {
- public:
- ImagePointerHolder(vtkImageData* im):
- mImage(im)
- {}
- ImagePointerHolder();
- void Set(vtkImageData* im){boost::mutex::scoped_lock lock(mMutex);mImage=im;}
- vtkImageData* Get(){boost::mutex::scoped_lock lock(mMutex);return mImage;}
- private:
- vtkImageData* mImage;
- /// The mutex
- boost::mutex mMutex;
- };
-}
-#endif
-
-
+++ /dev/null
-#include <creaImageIOImageReader.h>
-#include <creaImageIOTreeAttributeDescriptor.h>
-#include <creaImageIOSystem.h>
-
-#include <creaImageIOVtkImageReader.h>
-#if defined (USE_GDCM)
- #include <creaImageIODicomImageReader.h>
-#endif
-#if defined(USE_GDCM2)
- #include <creaImageIODicomImageReader2.h>
-#endif
-#include <creaImageIOUltrasonixImageReader.h>
-#include <vtkPNGReader.h>
-#include <vtkTIFFReader.h>
-#include <vtkJPEGReader.h>
-#include <vtkBMPReader.h>
-#include <vtkSLCReader.h>
-#include <vtkMetaImageReader.h>
-//#include <vtkGESignalReader.h>
-
-
-#include "boost/filesystem/path.hpp"
-
-namespace creaImageIO
-{
-
-
-
-
-
- //=====================================================================
- ImageReader::ImageReader()
- :
- mUnreadableImage(0),
- mLastFilename("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
- {
- // std::cout << "#### ImageReader::ImageReader()"<<std::endl;
- if (mUnreadableImage!=0) return;
-
- Register( boost::shared_ptr<AbstractImageReader>(new VtkImageReader(vtkPNGReader::New(), "PNG", ".png")));
- Register(boost::shared_ptr<AbstractImageReader>(new VtkImageReader(vtkTIFFReader::New(), "JPEG", ".jpeg")));
- Register(boost::shared_ptr<AbstractImageReader>(new VtkImageReader(vtkJPEGReader::New())));
- Register(boost::shared_ptr<AbstractImageReader>(new VtkImageReader(vtkBMPReader::New())));
- Register(boost::shared_ptr<AbstractImageReader>(new VtkImageReader(vtkSLCReader::New())));
- Register(boost::shared_ptr<AbstractImageReader>(new VtkImageReader(vtkMetaImageReader::New(),"MHD",".mhd")));
- // Register(new VtkImageReader(vtkGESignalReader::New()));
- Register(boost::shared_ptr<AbstractImageReader>(new DicomImageReader));
- Register(boost::shared_ptr<AbstractImageReader>(new UltrasonixImageReader));
-
- UnRegister(".txt");
-
- mUnreadableImage = vtkImageData::New();
- int dim[3];
- dim[0] = dim[1] = 128;
- dim[2] = 1;
- mUnreadableImage->SetDimensions ( dim );
- mUnreadableImage->SetScalarTypeToUnsignedChar();
- mUnreadableImage->AllocateScalars();
- for (int i=0;i<dim[0];i++)
- for (int j=0;j<dim[1];j++)
- mUnreadableImage->SetScalarComponentFromFloat(i,j,0,0,0);
- for (int i=0;i<dim[0];i++)
- {
- mUnreadableImage->SetScalarComponentFromFloat(i,i,0,0,255);
- mUnreadableImage->SetScalarComponentFromFloat(dim[0]-1-i,i,0,0,255);
- }
-
-
-
- }
- //=====================================================================
-
- //=====================================================================
- ImageReader::~ImageReader()
- {
-
- // for (i=mReader.begin(); i!=mReader.end(); i++)
- // {
- //delete (*i);
- // }
-// mReader.clear();
- if (mUnreadableImage!=0)
- {
- mUnreadableImage->Delete();
- mUnreadableImage = 0;
- }
- }
- //=====================================================================
-
- //=====================================================================
- void ImageReader::Register(boost::shared_ptr<AbstractImageReader> r)
- {
- mReader.push_back(r);
-
- }
-
- void ImageReader::UnRegister(const std::string i_val)
- {
- mUnReader.push_back(i_val);
-
- }
- //=====================================================================
-
- //=====================================================================
- // Returns true iff the file is readable
- bool ImageReader::ShallNotRead( const std::string& filename )
- {
- bool ok = true;
- if(filename != "")
- {
- std::vector<std::string >::iterator i ;
- for (i=mUnReader.begin(); i!=mUnReader.end(); i++)
- {
-
- if ( (*i).c_str() == filename)
- {
- ok = false;
- break;
- }
- }
- }
- return ok;
-
- }
-
-
- //=====================================================================
- // Returns true iff the file is readable
- bool ImageReader::CanRead( const std::string& filename )
- {
- bool ok = false;
-
- if( !ShallNotRead(filename))
- {
- return ok;
- }
- if(filename != "")
- {
- std::vector<boost::shared_ptr<AbstractImageReader> >::iterator i;
- for (i=mReader.begin(); i!=mReader.end(); i++)
- {
- ok = (*i)->CanRead(filename);
- if (ok)
- {
- mLastFilename = filename;
- mLastReader = *i;
- break;
- }
- }
- }
- return ok;
-
- }
- //=====================================================================
-
- //=====================================================================
- // Reads the file (CanRead must be called before : no test here)
- vtkImageData* ImageReader::ReadImage( const std::string& filename)
- {
- if (mLastFilename!=filename)
- {
- if (!CanRead(filename))
- {
- vtkImageData* im = vtkImageData::New();
- im->ShallowCopy(mUnreadableImage);
- return im;
- }
- }
- vtkImageData* i = mLastReader->ReadImage(mLastFilename);
- if (i==0)
- {
- i = vtkImageData::New();
- i->ShallowCopy(mUnreadableImage);
- }
- return i;
- }
- //=====================================================================
-
-
- //=====================================================================
- void ImageReader::ReadAttributes(const std::string& filename,
- std::map<std::string,std::string>& attr)
- {
- if (mLastFilename!=filename)
- {
- if (!CanRead(filename))
- {
- return;
- }
- }
- mLastReader->ReadAttributes(mLastFilename,attr);
- }
- //=====================================================================
-
-
- //=====================================================================
- /// Pushes back all kwown extensions (without dot) in the vector given
- void ImageReader::PushBackExtensions(std::vector<std::string>& v)
- {
- std::vector<boost::shared_ptr<AbstractImageReader> >::iterator i;
- for (i=mReader.begin(); i!=mReader.end(); i++)
- {
- (*i)->PushBackExtensions(v);
- }
- }
- //=====================================================================
-
-} // namespace creaImageIO
+++ /dev/null
-#ifndef __creaImageIOImageReader_h_INCLUDED__
-#define __creaImageIOImageReader_h_INCLUDED__
-
-#include <creaImageIOSystem.h>
-#include <creaImageIOAbstractImageReader.h>
-
-namespace creaImageIO
-{
-
-
- /**
- * \ingroup IO
- * \brief Generic image reader which uses all the specific concrete image reader of the lib (tif, jpg, dicom, ...)
- */
- class CREAIMAGEIO_EXPORT ImageReader : virtual public AbstractImageReader
- {
- public:
- ImageReader();
- ~ImageReader();
-
- /// Pushes back all kwown extensions (without dot) in the vector given
- void PushBackExtensions(std::vector<std::string>&);
-
- /// Returns true iff the file is readable
- bool CanRead( const std::string& filename);
- /// Reads and returns the image data.
- /// Returns an "Unreadable image" picture if fails
- vtkImageData* ReadImage( const std::string& filename);
-
- /// Reads the attributes of the image.
- /// Requested attributes names are provided as keys
- /// in a string to string map
- /// On return, the values of the map are the values
- /// of the attributes (empty string if not available).
- void ReadAttributes(const std::string& filename,
- tree::AttributeMapType& attr);
-
- /// Exclude specific readers
- /// TO DO...
-
-
- protected:
-
- /// Register a reader
- void Register( boost::shared_ptr<AbstractImageReader> );
-
- std::vector<boost::shared_ptr<AbstractImageReader> > mReader;
- vtkImageData* mUnreadableImage;
-
- std::string mLastFilename;
- boost::shared_ptr<AbstractImageReader> mLastReader;
-
- bool ShallNotRead( const std::string& filename );
-
- void UnRegister(const std::string i_val);
-
- std::vector <std::string> mUnReader;
-
- private:
-
- }; // class ImageReader
- //=====================================================================
-
-
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIOImageReader_h_INCLUDED__
+++ /dev/null
-/*
-
-*/
-/*! \file
- \brief Indexed priority queues handled by binary trees.
-*/
-#ifndef __creaImageIOIndexedHeap_h_INCLUDED__
-#define __creaImageIOIndexedHeap_h_INCLUDED__
-
-#include <vector>
-
-namespace creaImageIO
-{
-
-
-
- template <class T,
- class Comparator/*=Less<T>*/,
- class Indexer/*=Index<T> */>
- class IndexedHeap ;
- template < class T,
- class C,
- class I>
- std::ostream& operator << (std::ostream&, const IndexedHeap<T,C,I>& );
-
-
- //template <class T, class Comparator=std::less<T>, class Index=IndexIndex<T> > class SlicedIndexedHeap;
-
-
- //========================================================================
- /// \brief Indexed priority queues handled by binary trees.
- ///
- /// Heap Allows :
- /// - log(n) insertion
- /// - constant time acces to the first element
- /// - log(n) removal of the first element
- /// - log(n) priority change of a random element
- /// Indexation Allows :
- /// - constant time access to a random element (for priority change)
- ///
- /// The Indexer is an unary_function<T,int&> whose operator()(T& t)
- /// returns a reference on an integer which
- /// is maintained by the IndexedHeap in order to provide at any time
- /// the position of the object t in the Heap
- /// (hence allowing constant time random access to an object).
- template <class T,
- class Comparator /*=Less<T>*/,
- class Indexer /*=Index<T>*/>
- class IndexedHeap
- {
- // friend class SlicedIndexedHeap<T,Comparator,Index>;
- public :
-
- //======================================================================
- /// Constructor
- IndexedHeap () {}
- /// Constructor
- IndexedHeap ( const Comparator& comp, const Indexer& ind ) ;
- /// Destructor
- ~IndexedHeap() { }
- /// Sets the comparator
- void set( const Comparator& comp );
- /// Sets the Index
- void set( const Indexer& ind );
- //======================================================================
-
- //======================================================================
- /// inserts an element in the Heap and returns its position
- int insert(T);
- /// return a reference on the first element of the Heap
- T& top();
- /// return a constant reference on the first element of the Heap
- const T& top() const;
- /// removes and returns the first element of the Heap
- T remove_top();
- /// removes and returns the nth element
- T remove(int n);
- /// returns the size of the Heap
- inline int size() const {return m_p.size(); }
- /// empties the Heap
- void clear();
- //======================================================================
-
- //======================================================================
- /// returns a constant on the stack of elements
- const std::vector<T> & stack() const {return m_p;}
- /// returns a reference to the ith element of the stack
- T& operator [] (int i) { return m_p[i];}
- /// returns a constant reference to the ith element of the stack
- const T& operator [] (int i) const { return m_p[i];}
- /// returns the index (position) of t
- inline int index(T& t) { return (*m_i)(t); }
- //======================================================================
-
- //======================================================================
- /// returns the position of the father of i
- inline int father( int i ) const;
- /// returns the position of the right son of i
- inline int rightson( int i ) const;
- /// returns the position of the leftson of i
- inline int leftson( int i ) const;
- //======================================================================
- /// swaps ith and jth elements
- inline void swap(int i, int j);
- /// remonte un element dans le tas tant qu'il n'est pas a sa place.
- /// renvoie la position finale
- inline int upsort(int);
- /// descend un element dans le tas tant qu'il n'est pas a sa place.
- /// renvoie la position finale
- inline int downsort(int);
- //======================================================================
-
- protected :
- /// binary tree handled by a vector
- std::vector<T> m_p;
- /// comparator pointer
- const Comparator* m_c;
- /// Index pointer
- const Indexer* m_i;
- };
- //========================================================================
- // EO class IndexedHeap
- //========================================================================
-
-
-#include "creaImageIOIndexedHeap.txx"
-
-
-};
-//===========================================================================
-// EO namespace creaImageIO
-//===========================================================================
-
-
-
-//===========================================================================
-// EOF
-//===========================================================================
-#endif
+++ /dev/null
-/*
-
-*/
-/*! \file
- \brief Code of IndexedHeap
-*/
-//============================================================================
-template <class T, class CT, class IT>
-std::ostream& operator << (std::ostream& s, const IndexedHeap<T,CT,IT>& t)
-{
- s << "[";
- for (int i=0; i<t.size(); i++) s << t[i] << " " ;
- s << "]";
- return s;
-}
-//============================================================================
-
-
-//===========================================================
-template <class T, class CT, class IT>
-IndexedHeap<T,CT,IT>::IndexedHeap ( const CT& comp, const IT& index )
- : m_c(&comp), m_i(&index)
-{}
-//===========================================================
-
-
-//===========================================================
-template <class T, class CT, class IT>
-void IndexedHeap<T,CT,IT>::set( const CT& comp )
-{
- m_c = ∁
-}
-//===========================================================
-
-//===========================================================
-template <class T, class CT, class IT>
-void IndexedHeap<T,CT,IT>::set ( const IT& index )
-{
- m_i = &index;
-}
-//===========================================================
-
-
-//===========================================================
-template <class T, class CT, class IT>
-int IndexedHeap<T,CT,IT>::insert(T t)
-{
- m_p.push_back(t);
- (*m_i)(t) = size()-1;
- return upsort(size()-1);
-}
-//===========================================================
-
-//===========================================================
-template <class T, class CT, class IT>
-T& IndexedHeap<T,CT,IT>::top()
-{
- // lglASSERT( size() > 0)
- return m_p.front();
-}
-//===========================================================
-
-
-//===========================================================
-template <class T, class CT, class IT>
-const T& IndexedHeap<T,CT,IT>::top() const
-{
- // lglASSERT( size() > 0)
- return m_p.front();
-}
-//===========================================================
-
-//===========================================================
-template <class T, class CT, class IT>
-T IndexedHeap<T,CT,IT>::remove_top()
-{
- // lglASSERT( size() > 0 )
- T f(m_p[0]);
- (*m_i)(f) = -1;
- T last = m_p.back();
- m_p.pop_back();
- if (m_p.size()>0)
- {
- m_p[0] = last;
- (*m_i)(last) = 0;
- downsort(0);
- }
- return f;
-}
-//============================================================================
-
-
-
-//============================================================================
-template <class T, class CT, class IT>
-T IndexedHeap<T,CT,IT>::remove(int n)
-{
- // lglASSERT ( (n>=0)&&(n<size()) )
- T f(m_p[n]);
- (*m_i)(f) = -1;
- T last = m_p.back();
- m_p.pop_back();
- if (m_p.size()>0)
- {
- m_p[n] = last;
- (*m_i)(last) = n;
- downsort(n);
- }
- return f;
-}
-//============================================================================
-
-
-//============================================================================
-template <class T, class CT, class IT>
-void IndexedHeap<T,CT,IT>::clear()
-{
- for (typename std::vector<T>::iterator i=m_p.begin(); i!=m_p.end(); ++i)
- {
- (*m_i)(*i)=-1;
- }
- m_p.clear();
-}
-//============================================================================
-
-
-//============================================================================
-template <class T, class CT, class IT>
-int IndexedHeap<T,CT,IT>::father( int i) const
-{
- return ((i-1)/2);
-}
-//============================================================================
-
-//============================================================================
-template <class T, class CT, class IT>
-int IndexedHeap<T,CT,IT>::rightson( int i) const
-{
- return (i*2+2);
-}
-//============================================================================
-
-//============================================================================
-template <class T, class CT, class IT>
-int IndexedHeap<T,CT,IT>::leftson( int i) const
-{
- return (i*2+1);
-}
-//============================================================================
-
-//============================================================================
-template <class T, class CT, class IT>
-void IndexedHeap<T,CT,IT>::swap(int i, int j)
-{
- T tmp = m_p[i];
- m_p[i] = m_p[j];
- m_p[j] = tmp;
- // update indices
- (*m_i)(m_p[i]) = i;
- (*m_i)(m_p[j]) = j;
-}
-//============================================================================
-
-
-
-//============================================================================
-template <class T, class CT, class IT>
-int IndexedHeap<T,CT,IT>::upsort(int i)
-{
- //if (i==0) return i;
- int j = father(i);
- while ((i>0)&&(*m_c)(m_p[i],m_p[j]))
- {
- swap(i,j);
- i = j;
- j = father(j);
- }
- return i;
-}
-//============================================================================
-
-
-//============================================================================
-template <class T, class CT, class IT>
-int IndexedHeap<T,CT,IT>::downsort(int i)
-{
- do
- {
-
- unsigned int ls = leftson(i);
- if (ls<m_p.size())
- {
- bool lc = ((*m_c)(m_p[i],m_p[ls]));
- unsigned int rs = ls + 1;
- bool rc = true;
- if (rs<m_p.size()) rc = ((*m_c)(m_p[i],m_p[rs]));
- if ( !lc )
- {
- if ( !rc )
- {
- if ((*m_c)(m_p[ls],m_p[rs]))
- {
- swap(i,ls);
- i = ls;
- }
- else
- {
- swap(i,rs);
- i = rs;
- }
- }
- else
- {
- swap(i,ls);
- i = ls;
- }
- }
- else if ( !rc )
- {
- swap(i,rs);
- i = rs;
- }
- else return i;
- }
- else return i;
- }
- while (true);
- return i;
-}
-//============================================================================
-
-
-//============================================================================
-// EOF
-//============================================================================
+++ /dev/null
-#include <creaImageIOListener.h>
-#include <creaImageIOSystem.h>
-#include "boost/filesystem.hpp"
-#include <boost/filesystem/operations.hpp>
-#include <boost/utility.hpp>
-
-namespace fs = boost::filesystem;
-using boost::filesystem::path;
-
-using namespace crea;
-
-namespace creaImageIO
-{
- //=====================================================================
- // CTor
- Listener::Listener()
- {
-
- boost::mutex::scoped_lock lock(mMutex);
- GimmickDebugMessage(6,"Listener::Listener"
- <<std::endl);
- mDrive="E:";
- mMounted=false;
- mAddFiles=false;
- mRemoveFiles=true;
-
- }
- //=====================================================================
-
- //=====================================================================
- /// Destructor
- Listener::~Listener()
- {
- boost::mutex::scoped_lock lock(mMutex);
- GimmickDebugMessage(6,"Listener::~Listener"
- <<std::endl);
- }
- //=====================================================================
-
- void* Listener::Entry()
- {
- GimmickDebugMessage(6,"Listener::Entry()"<<std::endl);
- while(!TestDestroy())
- {
- try
- {
- fs::exists( mDrive );
- if(!mMounted && mAddFiles)
- {
- mMounted=true;
- SendSignal(mMounted);
- }
- else if(!mMounted)
- {
- mMounted=true;
- }
-
- }
- catch (...)
- {
- if(mMounted && mRemoveFiles)
- {
- mMounted=false;
- SendSignal(mMounted);
- }
- else if(mMounted)
- {
- mMounted=false;
- }
- }
-
- clock_t endwait;
- endwait = clock () + 0.001 * CLOCKS_PER_SEC ;
- while (clock() < endwait ) {}
-
- }
- return 0;
- }
-
- //=====================================================================
-
- //=====================================================================
- void Listener::OnExit()
- {
- GimmickDebugMessage(6,"Listener::OnExit() "<<std::endl);
- }
-
- //====================================================================
- void Listener::ConnectObserver(MountingCallbackType callback)
- {
- mMountingSignal.connect(callback);
- }
-
- //======================================================================
- void Listener::SendSignal(bool mount)
- {
- mMountingSignal(mount);
- }
-
-
-
-
-} // EO namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOListener_h_INCLUDED__
-#define __creaImageIOListener_h_INCLUDED__
-
-#include <creaImageIOSystem.h>
-#include <stdio.h>
-#include <time.h>
-#include <wx/thread.h>
-// Signal/slot mechanism
-#include <boost/signal.hpp>
-#include <boost/bind.hpp>
-#include <boost/thread/mutex.hpp>
-
-namespace creaImageIO
-{
-
- class Listener : public wxThread
- {
- public:
- /// Ctors
- Listener();
- /// Dtor
- virtual ~Listener();
- ///Thread method that is executed once create is called
- void* Entry();
- ///Thread method called upon exiting
- void OnExit();
- ///Sets the new state of adding files
- void SetAddFilesState(bool addFiles){boost::mutex::scoped_lock lock(mMutex);mAddFiles=addFiles;}
- ///Sets the new state of removing files
- void SetRemoveFilesState(bool removeFiles){boost::mutex::scoped_lock lock(mMutex);mRemoveFiles=removeFiles;}
- ///Sets the new monitored drive
- void SetMonitoredDrive(const std::string& dr){boost::mutex::scoped_lock lock(mMutex);mDrive=dr;}
- ///Puts the name of the monitored drive in the given string
- void GetMonitoredDrive(std::string& drive){drive=mDrive;}
-
- ///Related with signals
- //=============================================
- typedef boost::signal<void (bool)> MountingSignalType;
- typedef MountingSignalType::slot_function_type MountingCallbackType;
- //=============================================
-
- //==================================================================
- void ConnectObserver(MountingCallbackType callback);
- //==================================================================
-
- ///Sends a boost::signal to alert that the drive has changed its state (mounted/unmounted)
- void SendSignal(bool ivalid);
-
-
- private:
- /// The mutex
- boost::mutex mMutex;
- /// Boolean that declares if the files that are read on CD mount should be added
- bool mAddFiles;
- /// Boolean that declares if, on CD unmount, the files that were in the drive should be removed
- bool mRemoveFiles;
- ///Boolean that declares if a unit has been mounted
- bool mMounted;
- ///The monitored drive
- std::string mDrive;
- ///The validation signal
- MountingSignalType mMountingSignal;
- };
-
-}
-
-#endif
+++ /dev/null
-#include <creaImageIOMultiThreadImageReader.h>
-#include <creaImageIOImageReader.h>
-#include <wx/utils.h>
-#include <creaImageIOSystem.h>
-
-#include <creaImageIOGimmick.h>
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-namespace creaImageIO
-{
-
- //=====================================================================
- void MultiThreadImageReaderUser::MultiThreadImageReaderSendEvent
- ( const std::string& filename,
- EventType type,
- vtkImageData* image)
- {
- wxMutexLocker lock(mMultiThreadImageReaderUserMutex);
-
- this->OnMultiThreadImageReaderEvent(filename,type,image);
- }
- //=====================================================================
-
- //=====================================================================
- class ThreadedImageReader: public wxThread
- {
- public:
- ThreadedImageReader(MultiThreadImageReader* tir) :
- mMultiThreadImageReader(tir)
- {}
-
- void* Entry();
- void OnExit();
-
- vtkImageData* Read(const std::string& filename);
-
- struct deleter
- {
- void operator()(ThreadedImageReader* p)
- {
- p->Delete();
- }
- };
- friend struct deleter;
-
-
- private:
- ImageReader mReader;
- MultiThreadImageReader* mMultiThreadImageReader;
-
- };
-
- //=====================================================================
-
-
- //=====================================================================
- MultiThreadImageReader::MultiThreadImageReader(int number_of_threads)
- : //mDoNotSignal(false),
- mReader(0),
- mTotalMem(0),
- mTotalMemMax(1000000)
- {
- // std::cout << "#### MultiThreadImageReader::MultiThreadImageReader("
- // << " #threads= " << number_of_threads <<" )"<<std::endl;
-
- mDone = false;
- // Create the threads
- for (int i=0; i<number_of_threads; i++)
- {
- //ThreadedImageReader* t = new ThreadedImageReader(this);
- boost::shared_ptr<ThreadedImageReader> t(new ThreadedImageReader(this), ThreadedImageReader::deleter());
- mThreadedImageReaderList.push_back(t);
- std::cout << " ===> Thread "<<i
- <<" successfully added"<< std::endl;
- }
- mNumberOfThreadedReadersRunning = 0;
- // Init the queue
- mQueue.set(mComparator);
- mQueue.set(mIndexer);
- //
- // no thread : alloc self reader
-// if (number_of_threads==0)
-// {
- mReader = new ImageReader();
-// }
- }
- //=====================================================================
-
-
- //=====================================================================
- bool MultiThreadImageReader::Start()
- {
-
- // std::cout << "#### MultiThreadImageReader::Start()"
- // <<std::endl;
- if (mNumberOfThreadedReadersRunning > 0) return true;
-
- ThreadedImageReaderListType::iterator i;
- for (i =mThreadedImageReaderList.begin();
- i!=mThreadedImageReaderList.end();
- i++)
- {
- (*i)->Create();
- if ( (*i)->Run() != wxTHREAD_NO_ERROR )
- {
- std::cout << "ERROR starting a thread"<< std::endl;
- return false;
- }
- else
- {
- std::cout << " ===> Thread "<<(*i)->GetCurrentId()
- <<" successfully created"<< std::endl;
-
- }
- }
- wxMutexLocker locker(GetMultiThreadImageReaderUserMutex());
- // std::cout << "EO Start : #Threads running = "
- // << mNumberOfThreadedReadersRunning<<std::endl;
-
- return true;
- }
- //=====================================================================
-
- //=====================================================================
- void MultiThreadImageReader::Stop()
- {
-// std::cout << "#### MultiThreadImageReader::Stop()"
-// <<std::endl;
- // std::cout << "Sending stop order to the threads..."<<std::endl;
- if (mDone) return;
-
- ThreadedImageReaderListType::iterator i;
- for (i =mThreadedImageReaderList.begin();
- i!=mThreadedImageReaderList.end();
- i++)
- { std::cout << " ===> Thread "<<(*i)->GetCurrentId()
- <<" successfully stopped"<< std::endl;
- if((*i)->IsAlive())
- {(*i)->Pause();
- (*i).reset();
- // (*i)->Delete();
- }
- }
- mThreadedImageReaderList.clear();
- // Wait a little to be sure that all threads have stopped
- // A better way to do this ?
- // wxMilliSleep(1000);
- // New method : the threads generate a stop event when they have finished
- // We wait until all threads have stopped
-// std::cout << "Waiting for stop signals..."<<std::endl;
- do
- {
- // Sleep a little
- wxMilliSleep(10);
- // Lock
- {
- wxMutexLocker locker(GetMultiThreadImageReaderUserMutex());
-// std::cout << "#Threads running = "
-// << mNumberOfThreadedReadersRunning<<std::endl;
- // Break if all readers have stopped
- if (mNumberOfThreadedReadersRunning <= 0)
- {
- break;
- }
- }
- }
- while (true);
-// std::cout << "All threads stopped : OK "<<std::endl;
-
- ImageMapType::iterator j;
- for (j =mImages.begin();
- j!=mImages.end();
- ++j)
-
- {
- delete j->first;
- }
- mImages.clear();
- mDone = true;
- }
- //=====================================================================
-
- //=====================================================================
- MultiThreadImageReader::~MultiThreadImageReader()
- {
- // std::cout << "#### MultiThreadImageReader::~MultiThreadImageReader()"
- // <<std::endl;
- Stop();
- if (mReader) delete mReader;
- mThreadedImageReaderList.clear();
- }
- //=====================================================================
-
- //=====================================================================
- void MultiThreadImageReader::UpdateUnloadPriority(ImageToLoadPtr p,
- int priority)
- {
- // not in unload queue : ciao
- if (p->UnloadIndex()<0) return;
- int old_prio = p->GetPriority();
- if (priority > old_prio)
- {
- p->SetPriority(priority);
- mUnloadQueue.downsort(p->UnloadIndex());
- }
- else if ( old_prio > priority )
- {
- p->SetPriority(priority);
- mUnloadQueue.upsort(p->UnloadIndex());
- }
- }
- //=====================================================================
-
- //=====================================================================
- void MultiThreadImageReader::Request( MultiThreadImageReaderUser* user,
- const std::string& filename,
- int priority )
- {
- wxMutexLocker lock(GetMultiThreadImageReaderUserMutex()); //mMutex);
-
- if (mNumberOfThreadedReadersRunning==0)
-// if (mThreadedImageReaderList.size()==0)
- {
- // no detached reader : use self reader
- ImageToLoad itl(user,filename);
- ImageMapType::iterator i = mImages.find(&itl);
- if (i!=mImages.end())
- {
- ImageToLoadPtr pitl = const_cast<ImageToLoadPtr>(i->first);
- // Already inserted
- if (pitl->GetImage() != 0)
- {
- // Already read
- pitl->SetUser(user);
- UpdateUnloadPriority(pitl,priority);
- SignalImageRead(pitl,false);
- return; // pitl->GetImage();
- }
- }
- ImageToLoadPtr pitl = new ImageToLoad(user,filename,0);
- mImages[pitl] = 0;
- pitl->SetImage(mReader->ReadImage(filename));
- UpdateUnloadPriority(pitl,priority);
- SignalImageRead(pitl,true);
- // return pitl->GetImage();
- return;
- }
-
- ImageToLoad itl(user,filename);
- ImageMapType::iterator i = mImages.find(&itl);
- if (i!=mImages.end())
- {
- // Already inserted
- if (i->first->GetImage() != 0)
- {
- // Already read : ok :signal the user
- UpdateUnloadPriority(i->first,priority);
- SignalImageRead(i->first,false);
- return;
- }
- /// Already requested : change the priority
- ImageToLoadPtr pitl = const_cast<ImageToLoadPtr>(i->first);
- pitl->SetPriority(priority);
- // Already in queue
- if (pitl->Index()>=0)
- {
- // Re-sort the queue
- mQueue.upsort(pitl->Index());
- }
- // Not read but not in queue = being read = ok
- else
- {
-
- }
- }
- else
- {
- // Never requested before or unloaded
- ImageToLoadPtr pitl = new ImageToLoad(user,filename,priority);
- mImages[pitl] = 0;
- mQueue.insert(pitl);
- }
- }
- //=====================================================================
-
- //=====================================================================
- void MultiThreadImageReader::OnMultiThreadImageReaderEvent
- (const std::string& filename,
- MultiThreadImageReaderUser::EventType e,
- vtkImageData* image)
- {
- if ((e==MultiThreadImageReaderUser::ImageLoaded) &&
- (filename == mRequestedFilename))
- {
- mRequestedImage = image;
- }
- else if (e==MultiThreadImageReaderUser::ThreadedReaderStarted)
- {
- mNumberOfThreadedReadersRunning++;
- // std::cout << "#TR=" << mNumberOfThreadedReadersRunning << std::endl;
- }
- else if (e==MultiThreadImageReaderUser::ThreadedReaderStopped)
- {
-
- mNumberOfThreadedReadersRunning--;
- // std::cout << "#TR=" << mNumberOfThreadedReadersRunning << std::endl;
- }
- }
- //=====================================================================
-
- //=====================================================================
- vtkImageData* MultiThreadImageReader::GetImage(const std::string& filename)
- {
- // Start();
- // std::cout << "** MultiThreadImageReader::GetImage('"<<filename<<"')"
- // <<std::endl;
-
- do
- {
- // wxMutexLocker lock(GetMultiThreadImageReaderUserMutex()); //mMutex);
-
- // std::cout << "** MultiThreadImageReader::GetImage('"<<filename
- // <<"') lock ok"
- // <<std::endl;
-
- // if (mNumberOfThreadedReadersRunning==0)
- // if (mThreadedImageReaderList.size()==0)
- if (true)
- {
- ImageToLoad itl(this,filename);
- ImageMapType::iterator i = mImages.find(&itl);
- if (i!=mImages.end())
- {
- ImageToLoadPtr pitl = const_cast<ImageToLoadPtr>(i->first);
- // Already inserted
- if (pitl->GetImage() != 0)
- {
- // Already read
- UpdateUnloadPriority(pitl,
- GetMaximalPriorityWithoutLocking()+1);
- return pitl->GetImage();
- }
- }
- ImageToLoadPtr pitl = new ImageToLoad(this,filename,0);
- mImages[pitl] = 0;
- pitl->SetImage(mReader->ReadImage(filename));
- UpdateUnloadPriority(pitl,
- GetMaximalPriorityWithoutLocking()+1);
- return pitl->GetImage();
- }
-
- /*
- mRequestedFilename = filename;
- mRequestedImage = 0;
- ImageToLoad itl(this,filename);
- ImageMapType::iterator i = mImages.find(&itl);
- if (i!=mImages.end())
- {
- // Already inserted in queue
- if (i->first->GetImage() != 0)
- {
- // Already read : ok : return it
- return i->first->GetImage();
- }
- /// Already requested : change the priority
- ImageToLoadPtr pitl = const_cast<ImageToLoadPtr>(i->first);
- pitl->SetPriority( GetMaximalPriorityWithoutLocking() + 1 );
- pitl->SetUser( this );
- // Already in queue
- if (pitl->Index()>=0)
- {
- // Re-sort the queue
- mQueue.upsort(pitl->Index());
- }
- // Not read but not in queue = being read = ok
- else
- {
- pitl->SetUser( this );
- }
- }
- else
- {
-
- // Never requested before or unloaded
- ImageToLoadPtr pitl =
- new ImageToLoad(this,filename,
- GetMaximalPriorityWithoutLocking() + 1);
- mImages[pitl] = 0;
- mQueue.insert(pitl);
- }
- */
- }
- while (0);
-
- // std::cout << "Waiting..."<<std::endl;
-
- /*
- // Waiting that it is read
- int n = 0;
- do
- {
- // std::cout << n++ << std::endl;
- wxMilliSleep(10);
- do
- {
- // wxMutexLocker lock(mMutex);
- wxMutexLocker lock(GetMultiThreadImageReaderUserMutex());
- if (mRequestedImage!=0)
- {
- return mRequestedImage;
- }
- }
- while (0);
- }
- while (true);
- //
- */
- }
- //=====================================================================
-
- //=====================================================================
- void MultiThreadImageReader::SignalImageRead(ImageToLoadPtr p,
- bool purge)
- {
-
-// std::cout << "MultiThreadImageReader::SignalImageRead" <<std::endl;
- // std::cout << "this="<<this <<std::endl;
- // std::cout << "user="<<p->GetUser() <<std::endl;
-
- if ( p->GetUser() == this )
- GetMultiThreadImageReaderUserMutex().Unlock();
-
- p->GetUser()->MultiThreadImageReaderSendEvent
- (p->GetFilename(),
- MultiThreadImageReaderUser::ImageLoaded,
- p->GetImage());
-
- /*
- AN ATTEMPT TO UNLOAD OLDEST IMAGE IF EXCEEDED A CERTAIN MEMORY QUOTA
- BUGGY : TO FIX
- */
- if (!purge) return;
- GimmickMessage(5,"Image '"<<p->GetFilename()<<"' read"<<std::endl);
-
- // wxMutexLocker lock(GetMultiThreadImageReaderUserMutex());
-
- mUnloadQueue.insert(p);
- p->GetImage()->UpdateInformation();
- p->GetImage()->PropagateUpdateExtent();
- long ImMem = p->GetImage()->GetEstimatedMemorySize();
- mTotalMem += ImMem;
-
- GimmickMessage(5,"==> Image in memory = "<<mUnloadQueue.size()<<std::endl);
- GimmickMessage(5,"==> Total mem = "<<mTotalMem<<" Ko"<<std::endl);
-
- // return;
-
- while (mTotalMem > mTotalMemMax)
- {
- GimmickMessage(5,
- " ! Exceeded max of "
- << mTotalMemMax << " Ko : unloading oldest image ... "
- << std::endl);
- if ( mUnloadQueue.size() <= 1 )
- {
- GimmickMessage(5,
- " Only one image : cannot load AND unload it !!"
- <<std::endl);
- break;
-
- }
- ImageToLoadPtr unload = mUnloadQueue.remove_top();
- MultiThreadImageReaderUser* user = unload->GetUser();
-
- /*
- if ((user!=0)&&(user!=this))
- {
- user->GetMultiThreadImageReaderUserMutex().Lock();
- }
- */
-
- std::string filename = unload->GetFilename();
-
- GimmickMessage(5,"'" << filename << "'" << std::endl);
- mTotalMem -= unload->GetImage()->GetEstimatedMemorySize();
-
- GimmickMessage(5," ==> Total mem = "<<mTotalMem<<" Ko "<<std::endl);
-
- if (user!=0)
- {
- // std::cout << "unlock..."<<std::endl;
- // user->GetMultiThreadImageReaderUserMutex().Unlock();
- // std::cout << "event"<<std::endl;
- user->MultiThreadImageReaderSendEvent
- (filename,
- MultiThreadImageReaderUser::ImageUnloaded,
- 0);
- // std::cout << "event ok"<<std::endl;
- }
-
- if (unload->Index()>=0)
- {
- // GimmickMessage(5,"still in queue"<<std::endl);
- }
- unload->Index() = -1;
-
-
- ImageMapType::iterator it = mImages.find(unload);
- if (it!=mImages.end())
- {
- mImages.erase(it);
- }
- // std::cout << "delete..."<<std::endl;
- delete unload;
- // std::cout << "delete ok."<<std::endl;
-
- }
- }
- //=====================================================================
-
- //=====================================================================
- int MultiThreadImageReader::GetMaximalPriority()
- {
- wxMutexLocker lock(GetMultiThreadImageReaderUserMutex()); //mMutex);
- return GetMaximalPriorityWithoutLocking();
- }
- //=====================================================================
-
-
- //=====================================================================
- int MultiThreadImageReader::GetMaximalPriorityWithoutLocking()
- {
- long max = 0;
- if (mQueue.size()>0)
- {
- max = mQueue.top()->GetPriority();
- }
- if (mUnloadQueue.size()>0)
- {
- int max2 = mUnloadQueue.top()->GetPriority();
- if (max2>max) max=max2;
- }
- return max;
- }
- //=====================================================================
-
-
- //=====================================================================
- //=====================================================================
- //=====================================================================
- //=====================================================================
-
- //=====================================================================
- void* ThreadedImageReader::Entry()
- {
- // std::cout << "### Thread "<<GetCurrentId()<<"::Entry()"
- // << std::endl;
-
- mMultiThreadImageReader->MultiThreadImageReaderSendEvent
- ("",
- MultiThreadImageReaderUser::ThreadedReaderStarted,
- 0);
-
- // While was not deleted
- while (!TestDestroy())
- {
- //std::cout << "### Thread "<<GetCurrentId()<<" still alive" << std::endl;
-
- // Lock the mutex
- mMultiThreadImageReader->MultiThreadImageReaderEventLock();
- //mMutex.Lock();
- // If image in queue
- if (mMultiThreadImageReader->mQueue.size()>0)
- {
- MultiThreadImageReader::ImageToLoadPtr i =
- mMultiThreadImageReader->mQueue.remove_top();
-
- mMultiThreadImageReader->MultiThreadImageReaderEventUnlock();
- //mMutex.Unlock();
-
-
- // std::cout << "### Thread "<<GetCurrentId()<<" : reading '"
- // << i->GetFilename() << "'" << std::endl;
-
- // Do the job
- vtkImageData* im = Read(i->GetFilename());
-
- // Store it in the map
- mMultiThreadImageReader->MultiThreadImageReaderEventLock();
- //mMutex.Lock();
- MultiThreadImageReader::ImageToLoad itl(0,i->GetFilename());
- MultiThreadImageReader::ImageMapType::iterator it =
- mMultiThreadImageReader->mImages.find(&itl);
- MultiThreadImageReader::ImageToLoadPtr
- pitl = const_cast<MultiThreadImageReader::ImageToLoadPtr>
- (it->first);
- pitl->SetImage(im);
- mMultiThreadImageReader->SignalImageRead(pitl,true);//i->GetFilename());
- mMultiThreadImageReader->MultiThreadImageReaderEventUnlock(); //mMutex.Unlock();
-
- // std::cout << "### Thread "<<GetCurrentId()<<" : reading '"
- // << i->GetFilename() << "' : DONE" << std::endl;
-
- }
- else
- {
- mMultiThreadImageReader->MultiThreadImageReaderEventUnlock();
- //mMutex.Unlock();
- // Wait a little to avoid blocking
- Sleep(10);
- }
- };
- // std::cout << "### Thread "<<GetCurrentId()<<" stopping"
- // << std::endl;
-
- return 0;
- }
- //=====================================================================
-
- //=====================================================================
- void ThreadedImageReader::OnExit()
- {
- mMultiThreadImageReader->MultiThreadImageReaderSendEvent
- ("",
- MultiThreadImageReaderUser::ThreadedReaderStopped,
- 0);
- }
- //=====================================================================
-
- //=====================================================================
- vtkImageData* ThreadedImageReader::Read(const std::string& filename)
- {
- return mReader.ReadImage(filename);
- }
- //=====================================================================
-
-} // namespace creaImageIO
+++ /dev/null
-#ifndef __creaImageIOThreadedImageReader_h_INCLUDED__
-#define __creaImageIOThreadedImageReader_h_INCLUDED__
-
-#include <creaImageIOSystem.h>
-#include <creaImageIOImageReader.h>
-#include <creaImageIOIndexedHeap.h>
-#include <map>
-#include <deque>
-#include <wx/thread.h>
-#include <queue>
-
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup IO
- */
- //=====================================================================
- class ThreadedImageReader;
- class MultiThreadImageReader;
- //=====================================================================
-
- //=====================================================================
- class CREAIMAGEIO_EXPORT MultiThreadImageReaderUser
- {
- public:
- friend class ThreadedImageReader;
- friend class MultiThreadImageReader;
-
- MultiThreadImageReaderUser() {}
- virtual ~MultiThreadImageReaderUser() {}
-
- typedef enum
- {
- ThreadedReaderStarted,
- ThreadedReaderStopped,
- ImageLoaded,
- ImageUnloaded,
- Error
- }
- EventType;
- /// The virtual method to overload by MultiThreadImageReader users
- /// It is called when an image has been loaded or unloaded
- /// Provides :
- /// * The image file name which was requested
- /// * The type of event
- /// * If type==ImageLoaded the image pointer, else NULL pointer
- virtual void OnMultiThreadImageReaderEvent( const std::string& filename,
- EventType type,
- vtkImageData* image)
- {}
- inline void MultiThreadImageReaderEventLock()
- { mMultiThreadImageReaderUserMutex.Lock(); }
- inline void MultiThreadImageReaderEventUnlock()
- { mMultiThreadImageReaderUserMutex.Unlock(); }
- inline wxMutex& GetMultiThreadImageReaderUserMutex()
- { return mMultiThreadImageReaderUserMutex; }
- private:
- ///
- void MultiThreadImageReaderSendEvent( const std::string& filename,
- EventType type,
- vtkImageData* image);
- wxMutex mMultiThreadImageReaderUserMutex;
- };
- //=====================================================================
-
- //=====================================================================
- ///
- /// TAKE CARE : For the moment it only supports a **SINGLE USER**
-
- ///Class that allows parallel lectures of several images
- class MultiThreadImageReader : public MultiThreadImageReaderUser
- {
- public:
- friend class ThreadedImageReader;
-
- /// Ctor with the number of threads to use
- MultiThreadImageReader(int number_of_threads = 1);
- /// Dtor
- ~MultiThreadImageReader();
-
- /// Starts the reader = create the threads which start to check
- /// periodically the queue of requested images to read
- bool Start();
- /// Stops the reader = stops the threads and delete the images loaded
- void Stop();
-
- /// Request the image "filename" with a given priority
- /// When the image is ready (or an error occurred)
- /// The observer's callback is invoked
- void Request( MultiThreadImageReaderUser* user,
- const std::string& filename,
- int priority );
-
- /// Request the image "filename" immediately
- /// Blocks until image loaded
- /// (no user callback but image returned)
- vtkImageData* GetImage(const std::string& filename);
-
- ///
- int GetMaximalPriority();
-
- ///
- void OnMultiThreadImageReaderEvent( const std::string& filename,
- EventType type,
- vtkImageData* image);
-
- protected:
- bool mDone;
- int GetMaximalPriorityWithoutLocking();
- ///Class that represents an image to be loaded
- class ImageToLoad
- {
- public:
- ImageToLoad( MultiThreadImageReaderUser* user,
- const std::string& filename,
- int prio=0)
- : mUser(user),
- mFilename(filename),
- mPriority(prio),
- mIndex(-1),
- mUnloadIndex(-1),
- mImage(0)
- {}
- ~ImageToLoad()
- {
- if (mImage>0)
- {
- // std::cout << "Refs = "<<mImage->GetReferenceCount()<<std::endl;
- mImage->Delete();
- }
- }
- MultiThreadImageReaderUser* GetUser() const { return mUser; }
- void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; }
- const std::string& GetFilename() const { return mFilename; }
- int GetPriority() const { return mPriority; }
- void SetPriority(int p) { mPriority=p; }
- int& Index() { return mIndex; }
- int& UnloadIndex() { return mUnloadIndex; }
- vtkImageData* GetImage() const { return mImage; }
- void SetImage( vtkImageData* i ) { mImage=i; }
- private:
- MultiThreadImageReaderUser* mUser;
- std::string mFilename;
- int mPriority;
- int mIndex;
- int mUnloadIndex;
- vtkImageData* mImage;
- };
- //
-
- /// Type of pointer on an ImageToLoad struct
- typedef ImageToLoad* ImageToLoadPtr;
-
- /// ImageToLoadPtr comparator on priority (for image queue)
- struct ImageToLoadPtrPriorityComparator
- {
- bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
- const
- {
- return ( a->GetPriority() > b->GetPriority() );
- }
- };
- /// ImageToLoadPtr comparator on inverse priority (for image to unload queue)
- struct ImageToLoadPtrInversePriorityComparator
- {
- bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
- const
- {
- return ( a->GetPriority() < b->GetPriority() );
- }
- };
-
-
- /// ImageToLoadPtr comparator on filename (for image map)
- struct ImageToLoadPtrFilenameComparator
- {
- bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
- const
- {
- return ( a->GetFilename() < b->GetFilename() );
- }
- };
-
- /// ImageToLoadPtr indexer for image queue
- struct ImageToLoadPtrIndexer
- {
- int& operator()(ImageToLoadPtr & t) const { return t->Index(); }
- };
- /// ImageToLoadPtr indexer for to unload image queue
- struct ImageToUnloadPtrIndexer
- {
- int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); }
- };
-
- /// The callback from threaded readers when an image is read
- void SignalImageRead(ImageToLoadPtr p, bool purge);
-
- /// The type of map of images
- typedef std::map<ImageToLoadPtr,vtkImageData*,
- ImageToLoadPtrFilenameComparator> ImageMapType;
- /// The map of images
- ImageMapType mImages;
- /// Comparator for the image to load queue
- ImageToLoadPtrPriorityComparator mComparator;
- /// Indexer for the image to load queue
- ImageToLoadPtrIndexer mIndexer;
- /// The image to load priority queue
- IndexedHeap<ImageToLoadPtr,
- ImageToLoadPtrPriorityComparator,
- ImageToLoadPtrIndexer> mQueue;
-
- /// The type of list of threaded readers
- typedef std::vector<boost::shared_ptr<ThreadedImageReader> > ThreadedImageReaderListType;
- //typedef std::vector<ThreadedImageReader* > ThreadedImageReaderListType;
- ThreadedImageReaderListType mThreadedImageReaderList;
- /// The number of currently running threaded readers
- int mNumberOfThreadedReadersRunning;
- /// The mutex used to access safely internal data from any thread
- /// LG : Removed ! We now use the embedded mutex in User from which
- /// we inherit...
- // wxMutex mMutex;
-
- /// For GetImage : the filename requested
- std::string mRequestedFilename;
- /// For GetImage : the image requested
- vtkImageData* mRequestedImage;
-
- /// If number of threads == 0 then uses an internal non-threaded reader
- ImageReader* mReader;
-
- /// The type of list of images loaded
- /// used to unload oldest image when memory limit exceeded
- /// The image to unload priority queue
- IndexedHeap<ImageToLoadPtr,
- ImageToLoadPtrInversePriorityComparator,
- ImageToUnloadPtrIndexer> mUnloadQueue;
-
- void UpdateUnloadPriority(ImageToLoadPtr p, int priority);
- long mTotalMem;
- long mTotalMemMax;
-
-
- }; // class MultiThreadImageReader
- //=====================================================================
-
-
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__
+++ /dev/null
-
-#include <creaImageIOPACSConnection.h>
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-//#include <boost/asio.hpp>
-
-//using boost::asio::ip::tcp;
-
-enum { max_length = 3086 };
-using namespace std;
-namespace creaImageIO
-{
- PACSConnection::PACSConnection(std::string command)
- {
- /*
- try
- {
-
- boost::asio::io_service io_service;
-
- tcp::resolver resolver(io_service);
- tcp::resolver::query query(tcp::v4(), "localhost", "3306");
- tcp::resolver::iterator iterator = resolver.resolve(query);
-
- tcp::socket s(io_service);
- s.connect(*iterator);
-
- size_t request_length = strlen(command.c_str());
- boost::asio::write(s, boost::asio::buffer(command.c_str(), request_length));
-
- char reply[max_length];
- size_t reply_length = boost::asio::read(s,
- boost::asio::buffer(reply, request_length));
- std::cout << "Reply is: ";
- std::cout.write(reply, reply_length);
- std::cout << "\n";
- }
- catch (std::exception& e)
- {
- std::cerr << "Exception: " << e.what() << "\n";
- }
- */
- }
-
-}
-
-
-
+++ /dev/null
-#ifndef __creaImageIOPACSConnection_h_INCLUDED__
-#define __creaImageIOPACSConnection_h_INCLUDED__
-#include <string>
-
-namespace creaImageIO
-{
-class PACSConnection
- {
- public:
- /// Ctor
- PACSConnection(std::string command);
- };// EO PACSConnection
-} // EO namespace creaImageIO
-
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOSQLiteTreeHandler.h>
-#include <creaImageIOSystem.h>
-#include <creaImageIOGimmick.h>
-#include <creaImageIOTree.h>
-
-#include "CppSQLite3.h"
-
-#include <sys/stat.h>
-
-#include <deque>
-
-#include <creaWx.h>
-#include <boost/algorithm/string.hpp>
-using namespace crea;
-
-
-
-namespace creaImageIO
-{
- using namespace tree;
-
-
- //=============================================================
- SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename)
- : mFileName(filename)
- {
- mDB = new CppSQLite3DB;
- mIsAdding=false;
- //GimmickMessage(1,"SQLite version : " <<std::string(mDB->SQLiteVersion())<< std::endl);
- }
- //=============================================================
-
- //=============================================================
- SQLiteTreeHandler::~SQLiteTreeHandler()
- {
- delete mDB;
- }
- //=============================================================
-
-
- //=====================================================================
-
-
- //=====================================================================
- bool SQLiteTreeHandler::Open(bool writable)
- {
- // std::cout << "***> SQLiteTreeHandler::Open('"<<GetFileName()<<"')"<<std::endl;
- SetWritable(writable);
- return DBOpen();
- }
-
- //=====================================================================
- bool SQLiteTreeHandler::Create(bool writable)
- {
- // std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
- SetWritable(writable);
- return DBCreate();
- }
- //=====================================================================
-
-
- //=====================================================================
- bool SQLiteTreeHandler::Close()
- {
- return true;
- }
- //=====================================================================
-
-
- //=====================================================================
- bool SQLiteTreeHandler::Destroy()
- {
- return false;
- }
-
- //=====================================================================
-
- //=====================================================================
- int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
- {
- if (parent==0) parent = GetTree().GetTree();
- return DBLoadChildren(parent,maxlevel);
- }
- //=====================================================================
-
-
-
-
- //=====================================================================
- void SQLiteTreeHandler::UnLoad(tree::Node* n)
- {
- }
- //=====================================================================
-
- //=====================================================================
- int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
- {
- tree::Node* parent = DBGetParent(attr);
- DBGraftToParent(parent,attr);
- return (parent->GetLevel()+1);
-
- }
- //=====================================================================
-
-
- //=====================================================================
- bool SQLiteTreeHandler::Remove(tree::Node* node)
- {
- DBRecursiveRemoveNode(node);
-
- // std::cout << "DELETE"<<std::endl;
- bool remove=false;
- tree::Node* parent=node->GetParent();
- if (parent)
- {
- int nC = parent->RemoveChildrenFromList(node);
- if(nC>0 && parent->GetLevel()>0)
- {
- std::stringstream out;
- out <<nC;
- SetAttribute(parent,"NumberOfChildren",out.str());
- }
- else
- {
- remove=true;
- }
-
- }
- delete node;
- if(remove&&parent->GetLevel()>0)
- {
- Remove(parent);
- }
- // std::cout << "DELETE OK"<<std::endl;
- return true;
- }
-
- //=====================================================================
-
- //=====================================================================
- /// Sets an attribute of a Node
- bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
- const std::string& key,
- const std::string& value)
- {
- if (n==0) n=GetTree().GetTree();
- return DBSetAttribute(n,key,value);
- }
- //=====================================================================
- //=====================================================================
- /// Sets an attribute
- void SQLiteTreeHandler::SetAttribute(const std::string& levelDescriptor,
- const std::string& key,
- const std::string& value,
- const std::string& searchParam,
- const std::string& searchVal)
- {
- DBSetAttribute(levelDescriptor,key,value,searchParam, searchVal);
- }
- //=====================================================================
- /// Deletes a tuple
- void SQLiteTreeHandler::DeleteTuple(std::string levelDescriptor,
- std::string key, std::string value)
- {
- DBDelete(levelDescriptor,key,value);
- }
- //=====================================================================
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=====================================================================
- // SQLite DB specific methods
- //=====================================================================
-
-
-
-
- //=====================================================================
- char* format_sql(const std::string& s)
- {
- return sqlite3_mprintf("%q",s.c_str());
- }
- //=====================================================================
-
-
- //=====================================================================
-#define QUERYDB(QUER,RES) \
- try \
- { \
- GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
- RES = mDB->execQuery(QUER.c_str()); \
- } \
- catch (CppSQLite3Exception& e) \
- { \
- GimmickError("SQLite query '"<<QUER<<"' : " \
- << e.errorCode() << ":" \
- << e.errorMessage() ); \
- } \
-
- //=====================================================================
-
- //=====================================================================
-#define UPDATEDB(UP) \
- try \
- { \
- GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
- mDB->execDML(UP.c_str()); \
- } \
- catch (CppSQLite3Exception& e) \
- { \
- GimmickError("SQLite update '"<<UP<<"' Error : " \
- << e.errorCode() << ":" \
- << e.errorMessage() ); \
- }
- //=====================================================================
-
-
- //=====================================================================
- bool SQLiteTreeHandler::DBOpen()
- {
- GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
- <<"' ... "<<std::endl);
- // OPENING FILE
- if (!boost::filesystem::exists(GetFileName()))
- {
- return false;
- }
-
- try
- {
- mDB->open(GetFileName().c_str());
- }
- catch (CppSQLite3Exception& e)
- {
- GimmickError("Opening '"<<GetFileName()<<"' : "
- << e.errorCode() << ":"
- << e.errorMessage());
- return false;
- }
- // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
- if (!DBImportTreeDescription())
- {
- return false;
- }
-
- GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
- <<"' ... OK"<<std::endl);
- return true;
- }
- //=====================================================================
-
- //=====================================================================
- bool SQLiteTreeHandler::DBCreate()
- {
- GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
- <<"' ... "<<std::endl);
-
- if (boost::filesystem::exists(GetFileName()))
- {
- GimmickError(GetFileName()<<"' : "
- << "file already exists");
- return false;
- }
-
- // OPENING
- try
- {
- mDB->open(GetFileName().c_str());
- }
- catch (CppSQLite3Exception& e)
- {
- GimmickError(e.errorCode() << ":"
- << e.errorMessage() <<std::endl);
- return false;
- }
-
-
- // CREATING TABLES
-
- std::string command;
- // Create LEVELS table
- command = "create table LEVELS\n";
- command += "( Name text )\n";
- UPDATEDB(command);
- int l;
- // Iterate the Levels
- for (l=0; l<GetTree().GetNumberOfLevels(); l++)
- {
- command = "INSERT INTO LEVELS (Name) VALUES ('";
- command += GetTree().GetLevelDescriptor(l).GetName();
- command += "')";
- UPDATEDB(command);
-
- // Create table of level (for level>0, i.e. not Root)
- if (l>=0)
- {
- command = "CREATE TABLE ";
- command += GetTree().GetLevelDescriptor(l).GetName();
- command += "\n(\nID INTEGER PRIMARY KEY";
- if (l>1)
- {
- command += ",\nPARENT_ID int not null";
- }
- SQLAppendAttributesDefinition(l,command);
- if (l>1)
- {
- command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
- command += GetTree().GetLevelDescriptor(l-1).GetName();
- command += "(ID) on delete restrict on update restrict";
- }
- command += "\n)";
- UPDATEDB(command);
-
-
- // Add Attribute 'ID' to Description
- GetTree().GetDescriptor().Add
- (AttributeDescriptor( "ID",
- "Database Identifier",
- 0,0,
- AttributeDescriptor::PRIVATE
- ),l);
-
- if (l>1)
- {
- // Add Attribute 'PARENT_ID' to Description
- GetTree().GetDescriptor().Add
- (AttributeDescriptor( "PARENT_ID",
- "Database Parent Identifier",
- 0,0,
- AttributeDescriptor::PRIVATE
- ),l);
- }
-
- }
-
- // Create table *_ATTRIBUTES
-
- command = "CREATE TABLE ";
- command += GetTree().GetLevelDescriptor(l).GetName();
- command += "_Attributes\n(\n";
- command += "Key text,\n";
- command += "Name text,\n";
- command += "DicomGroup int,\n";
- command += "DicomElement int,\n";
- command += "Flags int\n";
- command += "\n)";
- UPDATEDB(command);
-
- // Fill the table *_ATTRIBUTES
- LevelDescriptor::AttributeDescriptorListType::const_iterator i;
- for (i = GetTree().GetAttributeDescriptorList(l).begin();
- i != GetTree().GetAttributeDescriptorList(l).end();
- ++i)
- {
-
- std::stringstream insert;
- insert << "INSERT INTO "
- << GetTree().GetLevelDescriptor(l).GetName()
- << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
- << "VALUES ('"
- << i->GetKey() << "','"
- << i->GetName() << "',"
- << i->GetGroup() << ","
- << i->GetElement() << ","
- << i->GetFlags() << ");";
- UPDATEDB(insert.str());
- }
-
- } // For l=0...
-
- // Initialize the root attributes
- GetTree().InitializeAttributeMap();
- // Insert the root in the level 0 table
- DBInsert(GetTree().GetTree());
-
-
- GetTree().SetChildrenLoaded(true);
- GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
- <<"' ... OK"<<std::endl);
- return true;
- }
- //=====================================================================
-
- //=====================================================================
- void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
- std::string& s)
- {
- LevelDescriptor::AttributeDescriptorListType::const_iterator i;
- for (i = GetTree().GetAttributeDescriptorList(level).begin();
- i != GetTree().GetAttributeDescriptorList(level).end();
- ++i)
- {
- // if (i->second.flags==1) continue;
- s += ",\n";
- s += i->GetKey();
- s += " text";
- }
- }
- //=====================================================================
-
-
- //=====================================================================
- bool SQLiteTreeHandler::DBImportTreeDescription()
- {
- GimmickMessage(1,"Importing tree description for database ..."
- <<std::endl);
-
- // Test table 'LEVELS' existence
- if ( ! mDB->tableExists("LEVELS") )
- {
- GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
- <<std::endl);
- return false;
- }
-
- tree::Descriptor& desc = GetTree().GetDescriptor();
- // clears the existing one
- desc.Clear();
-
- int nblevel = 0;
- std::string query = "SELECT * FROM LEVELS";
- CppSQLite3Query q;
- QUERYDB(query,q);
-
- while (!q.eof())
- {
- std::string name = q.getStringField(0);
- GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
- desc.Add(LevelDescriptor(name));
- nblevel++;
- q.nextRow();
- }
-
- for (int level = 0; level < nblevel; ++level )
- {
- std::string table = GetTree().GetLevelDescriptor(level).GetName();
- table += "_Attributes";
- // Test table 'LEVELS' existence
- if ( ! mDB->tableExists(table.c_str()) )
- {
- GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
- <<std::endl);
- return false;
- }
-
- std::string query = "SELECT * FROM ";
- query += table;
- CppSQLite3Query q;
- QUERYDB(query,q);
-
- GimmickMessage(2," * Level '"
- <<GetTree().GetLevelDescriptor(level).GetName()
- <<"'"<<std::endl);
-
- // Test that ID and PARENT_ID mandatory attributes exist
- bool ID_found = false;
- bool PARENT_ID_found = false;
- if (level==0) ID_found = true;
- if (level<=1) PARENT_ID_found = true;
-
- while (!q.eof())
- {
- std::string key(q.getStringField(0));
- std::string name(q.getStringField(1));
- GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
- <<"'"<<std::endl);
- desc.Add
- (AttributeDescriptor( key, // Key
- name, // Name
- q.getIntField(2), // Group
- q.getIntField(3), // Element
- q.getIntField(4) // Flags
- ),level);
- if ( key == "ID" )
- {
- ID_found = true;
- }
- if ( key == "PARENT_ID" )
- {
- PARENT_ID_found = true;
- }
- q.nextRow();
- }
-
- if ( ! (ID_found || PARENT_ID_found ) )
- {
- GimmickMessage(1,"!! ERROR : Table '"<<table
- <<"' does not contain mandatory attribute ID or PARENT_ID"
- <<std::endl);
- return false;
-
- }
- }
-
-
- // Create the attributes table for Root (i.e. Tree)
- LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = GetTree().GetAttributeDescriptorList(0).begin();
- a!= GetTree().GetAttributeDescriptorList(0).end();
- ++a)
- {
-
- GetTree().UnsafeSetAttribute( a->GetKey(), "" );
- }
-
- // Reading Root attributes
- // Query DB
- query = "SELECT * FROM ";
- query += GetTree().GetLevelDescriptor(0).GetName();
- QUERYDB(query,q);
-
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- GetTree().UnsafeSetAttribute(q.fieldName(fld),
- q.getStringField(fld));
- }
-
- GimmickMessage(1,"Importing tree description from database ... OK"
- <<std::endl);
- return true;
- }
- //=====================================================================
-
- //========================================================================
- ///
- void SQLformat(std::string i_str, std::string &o_str)
- {
- // quote must be doubled
- boost::algorithm::replace_all(i_str,"'","''");
- // Found strange strings which contained NULL char INSIDE string
- int i,size=i_str.size();
- for (i=0;i<size;++i)
- {
- if (i_str[i]==0)
- {
- i_str = i_str.substr(0,i);
- break;
- }
- }
- o_str = i_str;
- }
- //========================================================================
-
- //=====================================================================
- void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
- std::string& str)
- {
- GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
- std::string atts="";
- std::string values="";
- std::string out ="";
- tree::Node::AttributeMapType::iterator i;
- for (i = n->GetAttributeMap().begin();
- i != n->GetAttributeMap().end();
- i++)
- {
- if (i->first=="ID")
- {
- continue;
- }
-
- atts += "'" + i->first + "'";
- SQLformat(i->second, out);
- values += "'" + out + "'";
- atts += ",";
- values += ",";
- GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
- }
- atts[atts.size()-1]=' ';
- values[values.size()-1]=' ';
-
- str = "("+atts+") VALUES ("+values+")";
- GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
- }
- //=====================================================================
-
- //=====================================================================
- tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
- {
- Node* parent = GetTree().GetTree();
- bool go_down;
- do
- {
- go_down = false;
- // Load the children of the current parent
- DBLoadChildren(parent);
- // Iterate the children
- tree::Node::ChildrenListType::const_iterator i;
- for (i = parent->GetChildrenList().begin();
- i!= parent->GetChildrenList().end();
- ++i)
- {
- if ( (*i)->Matches( attr ) )
- {
- go_down = true;
- parent = *i;
- break;
- }
- }
- }
- while (go_down);
- return parent;
- }
- //=====================================================================
-
- //=====================================================================
- int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
- int numberoflevels)
- {
- if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
- return 0;
-
- GimmickMessage(2,"Loading children of '"<<node->GetLabel()
- <<"'"<<std::endl);
-
- int nbloaded = 0;
- // If children loaded we do not have to do it but we need to recurse
- // in order to load the children's children if necessary, and so on...
- if (node->GetChildrenLoaded())
- {
- // Iterate the children
-
- tree::Node::ChildrenListType::iterator i;
- for (i = node->GetChildrenList().begin();
- i!= node->GetChildrenList().end();
- ++i)
- {
- nbloaded += DBLoadChildren(*i,numberoflevels-1);
- }
- node->SetChildrenLoaded(true);
- return nbloaded;
-
- }
- else
- {
- /// If children not loaded : do it and recurse
-
- // Query DB
- int level = node->GetLevel();
- std::string query = "SELECT * FROM ";
-
- query += GetTree().GetLevelDescriptor(level+1).GetName();
- if (level>0)
- {
- query += " WHERE PARENT_ID='" + node->GetAttribute("ID")
- + "'";
- }
-GimmickDebugMessage(1, "query : '" <<query <<std::endl);
- CppSQLite3Query q;
- QUERYDB(query,q);
-
- int p=0;
- while (!q.eof())
- {
-
- // std::cout << "DBLoadCh : creating node level "<<level+1<<std::endl;
-
- nbloaded++;
- Node* n = new Node(node);
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
- }
-
- // recurse
- if ( numberoflevels != 1 )
- {
- // msw[2].Pause();
- nbloaded += DBLoadChildren(n, numberoflevels-1);
- // msw[2].Resume();
- }
- // next entry in db
- q.nextRow();
- }
-
- node->SetChildrenLoaded(true);
-
-
- // msw[2].Pause();
- return nbloaded;
- }
- }
- //=====================================================================
-
- //======================================================================
- void SQLiteTreeHandler::DBInsert(tree::Node* n)
- {
- GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
- <<"'"<<std::endl);
- std::string val;
- SQLAppendAttributesValues(n,val);
- std::string insert("INSERT INTO ");
- insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
- insert += " " + val + ";";
-
- UPDATEDB(insert);
-
- // Store DB id of newly created node;
- long lastrow = mDB->lastRowId();
- std::stringstream ri;
- ri << mDB->lastRowId();
- n->SetAttribute("ID",ri.str());
- }
- //======================================================================
-
- //======================================================================
- /// Graft the branch defined by the attributes to the parent
- void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
- const AttributeMapType& attr)
- {
- // std::cout <<"Grafting to parent '"<<parent->GetLabel()
- // <<"'"<<std::endl;
-
- for (int level = parent->GetLevel()+1;
- level < GetTree().GetNumberOfLevels();
- level++)
- {
- // Create Node
- tree::Node* child = new tree::Node(parent,attr);
- child->SetChildrenLoaded(true);
- if (level>1)
- {
- int nc = GetNumberOfChildren(parent)+1;
-
- // std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
- std::stringstream out;
- out << nc;
- SetAttribute(parent,"NumberOfChildren",out.str());
- }
-
- // Set PARENT_ID if necessary
- if ( parent->GetLevel()>0 )
- child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
-
- // Insert in DB
- DBInsert(child);
-
- // Down one level
- parent = child;
- }
- }
- //======================================================================
-
-
- //=====================================================================
- /// Sets an attribute of a Node
- bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
- const std::string& key,
- const std::string& value)
- {
- GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
- "' "<<key<<"='"<<value<<"'"<<std::endl);
-
- n->SetAttribute(key,value);
- std::string sql = "UPDATE ";
- sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
- sql += " SET ";
- sql += key;
- sql += " = '";
- sql += value;
- sql += "' WHERE ID = '";
- sql += n->GetAttribute("ID");
- sql +="'";
- // sql += " LIMIT 1";
- UPDATEDB(sql);
- return true;
- }
-
- //=====================================================================
- /// Sets an attribute of a Node
- void SQLiteTreeHandler::DBSetAttribute(const std::string& levelDescriptor,
- const std::string& key,
- const std::string& value,
- const std::string& searchParam,
- const std::string& searchVal)
- {
-
- std::string sql = "UPDATE ";
- sql += levelDescriptor;
- sql += " SET ";
- sql += key;
- sql += " = '";
- sql += value;
- sql += "' WHERE ";
- sql += searchParam;
- sql += " = '";
- sql += searchVal;
- sql += "'";
- std::cout<<sql<<std::endl;
- UPDATEDB(sql);
- }
- //=====================================================================
- void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
- {
-
- std::string query = "DELETE FROM ";
-
-
- query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
-
- query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
-
- UPDATEDB(query);
- GimmickDebugMessage(2,
- " Deleting '"
- <<node->GetLabel()<<"' with ID '"
- <<node->GetAttribute("ID")
- <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
- <<std::endl);
-
-
- if(node->GetNumberOfChildren()!=0)
- {
- Node::ChildrenListType::iterator i;
- for (i = node->GetChildrenList().begin();
- i != node->GetChildrenList().end();
- i++)
- {
- DBRecursiveRemoveNode((*i));
- }
- }
- else if(node->GetLevel()<GetTree().GetNumberOfLevels()-1)
- {
- DBRecursiveRemoveNode(node->GetLevel()+1,node->GetAttribute("ID"));
- }
- }
-
- //=====================================================================
- void SQLiteTreeHandler::DBRecursiveRemoveNode(int level, std::string parentId)
- {
- std::stringstream out;
- std::stringstream result;
- out<<"SELECT ID FROM "<<GetTree().GetLevelDescriptor(level).GetName()<<" WHERE PARENT_ID='"<<parentId<<"'";
-
- CppSQLite3Query q;
- QUERYDB(out.str(),q);
-
- while (!q.eof())
- {
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- result<<q.getStringField(fld)<<"#";
- }
- q.nextRow();
- }
- std::string res=result.str();
- size_t ini=0;
- size_t fin=0;
- while(fin<res.size()-1)
- {
- fin=res.find('#',ini);
- DBDelete(GetTree().GetLevelDescriptor(level).GetName(),"ID",res.substr(ini,fin-ini));
- if(level<GetTree().GetNumberOfLevels()-1)
- {
- DBRecursiveRemoveNode(level+1,res.substr(ini,fin-ini));
- }
- ini=fin+1;
- }
-
-
- }
-
- //=====================================================================
- void SQLiteTreeHandler::DBDelete(std::string levelDescriptor, std::string key, std::string value)
- {
-
- std::stringstream query;
- query<<"DELETE FROM "<<levelDescriptor<<" WHERE "<<key<<"='"<<value<<"';";
-
- UPDATEDB(query.str());
- GimmickDebugMessage(2," Deleting: Query: "<<query.str()<<std::endl);
- }
-
-
- //=====================================================================
- void SQLiteTreeHandler::GetAttribute(std::string levelDescriptor,
- std::string searchParam,
- std::string searchVal,
- std::string key,
- std::string& result)
- {
- std::stringstream out;
- std::stringstream results;
- out<<"SELECT "<<key<<" FROM "<<levelDescriptor;
- if(searchParam!="")
- {
- out<<" WHERE "<<searchParam<<"='"<<searchVal<<"'";
- }
-
- CppSQLite3Query q;
- QUERYDB(out.str(),q);
-
-
- while (!q.eof())
- {
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- results<<q.getStringField(fld);
- if(searchParam=="")
- {
- results<<"#";
- }
- }
- q.nextRow();
- }
- result=results.str();
-
- }
- //=====================================================================
- unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
- {
- // Query DB
- int nb=0;
- int level = n->GetLevel();
-
- if(level<GetTree().GetNumberOfLevels()&& level>0)
- {
- std::string query = "SELECT NumberOfChildren FROM ";
- query += GetTree().GetLevelDescriptor(level).GetName();
- if (level>0)
- {
- query += " WHERE ID='" + n->GetAttribute("ID")
- + "'";
- }
- CppSQLite3Query q;
- QUERYDB(query,q);
-
-
- while (!q.eof())
- {
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- nb=q.getIntField(fld);
- }
- q.nextRow();
- }
- }
- /*
- if(nb==0)
- {
- nb=1;
- }
- */
- return nb;
- }
-
- //=====================================================================
- void SQLiteTreeHandler::GetTopLevelNodeId(const std::string& searchParam, const std::string& searchValue, std::string& parent_id)
- {
- int level=GetTree().GetNumberOfLevels()-1;
- std::string sp=searchParam.c_str();
- std::string sv=searchValue.c_str();
-
- while(level>1)
- {
- std::stringstream out;
- std::stringstream results;
- out<<"SELECT PARENT_ID FROM "<<GetTree().GetLevelDescriptor(level).GetName();
- out<<" WHERE "<<sp<<"='"<<sv<<"'";
- CppSQLite3Query q;
- QUERYDB(out.str(),q);
-
-
- while (!q.eof())
- {
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- results<<q.getStringField(fld);
- }
- q.nextRow();
- }
- level=level-1;
- sp="ID";
- sv=results.str();
- }
- parent_id=sv;
-
- }
-
- //=====================================================================
- void SQLiteTreeHandler::RemoveEntries(const std::string i_table,
- const std::string i_attribute,
- const std::string i_operand,
- const std::string i_val)
- {
- std::stringstream query;
- query<<"DELETE FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
- UPDATEDB(query.str());
- }
-
- //=====================================================================
- void SQLiteTreeHandler::BeginTransaction()
- {
- std::stringstream out;
- out<<"begin transaction;";
- UPDATEDB(out.str());
- }
-
- //=====================================================================
- void SQLiteTreeHandler::EndTransaction()
- {
- std::stringstream out;
- out<<"commit transaction;";
- UPDATEDB(out.str());
- }
-
-} // namespace creaImageIO
+++ /dev/null
-#ifndef __creaImageIOSQLiteTreeHandler_h_INCLUDED__
-#define __creaImageIOSQLiteTreeHandler_h_INCLUDED__
-
-#include <creaImageIOTreeHandler.h>
-
-class CppSQLite3DB;
-
-namespace creaImageIO
-{
-
-
- /**
- * \ingroup Model
- */
- //=======================================================================
- /// Concrete TreeHandler which manages a Tree stored in a sqlite database
- class SQLiteTreeHandler : virtual public TreeHandler
- {
- public:
- //====================================================================
- /// Ctor with database file name
- SQLiteTreeHandler(const std::string& filename);
- /// Dtor
- virtual ~SQLiteTreeHandler();
- //====================================================================
-
- //====================================================================
- /// Returns the sqlite db file name
- const std::string& GetFileName() const { return mFileName; }
- //====================================================================
-
- //====================================================================
- // QUERY METHODS
- /// Is the 'source' readable ?
- virtual bool IsReadable() { return true; }
- /// Is the 'source' writable ?
- virtual bool IsWritable() { return true; }
- //====================================================================
-
-
- //====================================================================
- // INITIALIZATION / FINALIZATION
- //====================================================================
-
- //====================================================================
- /// Opens an existing 'source'
- // Default mode is read only
- // If IsWritable and writable==true then opens in read/write mode
- virtual bool Open(bool writable = false);
- /// Closes the 'source'
- virtual bool Close();
- /// Creates a new 'source'
- // Default mode is read only
- // If IsWritable and writable==true then opens in read/write mode
- virtual bool Create(bool writable = false);
- /// Destroys the 'source'
- virtual bool Destroy();
- /// Begins a transaction
- virtual void BeginTransaction();
- ///Commits results and ends transaction
- virtual void EndTransaction();
- //====================================================================
-
-
- //====================================================================
- // READ METHODS
- //====================================================================
-
-
- //====================================================================
- /// Returns the number of children of the Node *WITHOUT LOADING THEM*
- // REM : The Tree itself is a Node and asking for its number of
- // children returns the number of children of level 1.
- virtual unsigned int GetNumberOfChildren(tree::Node* n);
- //====================================================================
-
- //====================================================================
- /// Returns the attribute requested. Useful for synchronization.
- virtual void GetAttribute(std::string levelDescriptor,
- std::string searchParam,
- std::string searchVal,
- std::string key,
- std::string& result);
- //====================================================================
-
-
- //====================================================================
- /// Recursively loads the children of node 'parent' until maxlevel
- // is reached.
- // If parent == NULL or parent == tree then starts with the 'children' of
- // the tree itself.
- // Returns the total number of children loaded.
- virtual int LoadChildren(tree::Node* parent, int maxlevel);
- //====================================================================
-
- //====================================================================
- /// Unloads the Node and its descendants
- // WITHOUT altering the source, e.g. the database
- virtual void UnLoad(tree::Node* n);
- ///====================================================================
-
- //====================================================================
- /// Returns the top level node id for the given search param and search value
- virtual void GetTopLevelNodeId(const std::string& searchParam,
- const std::string& searchValue,
- std::string& parent_id);
- ///====================================================================
-
- //====================================================================
- // WRITE METHODS : WORK ONLY IN WRITE MODE
- //====================================================================
- /// Adds a branch in the tree with the attributes provided
- // returns the Level in the tree where the branch was connected
- // (-1 for error, 0 for top level, etc. )
- // Of course the branch is loaded on exit
- virtual int AddBranch( const AttributeMapType& attr );
- // Removes the node and its descendants
- virtual bool Remove(tree::Node*);
- // Sets an attribute of a Node
- virtual bool SetAttribute(tree::Node*,
- const std::string& key,
- const std::string& value);
- // Sets an attribute
- virtual void SetAttribute(const std::string& levelDescriptor,
- const std::string& key,
- const std::string& value,
- const std::string& searchParam,
- const std::string& searchVal);
- //Deletes the tuple that matches the parameters given
- virtual void DeleteTuple(std::string levelDescriptor, std::string key, std::string value);
- //Deletes the entries that match the parameters given
- virtual void RemoveEntries(const std::string i_table,
- const std::string i_attribute,
- const std::string i_operand,
- const std::string i_val);
-
- //====================================================================
-
-
-
- protected:
- //======================================================================
- /// Open the database
- bool DBOpen();
- /// Import the Tree::Description from database (verifies the structure)
- bool DBImportTreeDescription();
- //======================================================================
- //======================================================================
- // Creation
- /// Creates a new database on disk and the tables
- bool DBCreate();
- /// Appends to string s the SQL command to create the attributes of a given level
- void SQLAppendAttributesDefinition(int level, std::string& s);
- //======================================================================
-
- //======================================================================
-
- /// Returns the parent to which the branch defined by the attributes
- // provided must be grafted
- tree::Node* DBGetParent( const AttributeMapType& attr);
- //======================================================================
-
- //======================================================================
-
- /// Loads the children of Node parent
- // Can recurse to numberoflevels levels
- // \return The total number of Node loaded (may be at different levels)
- int DBLoadChildren( tree::Node* parent, int numberoflevels = 1);
- //======================================================================
-
- //======================================================================
-
- /// Appends to string s the SQL command to set the attributes values
- // of node n
- void SQLAppendAttributesValues(tree::Node* n, std::string& s);
- //======================================================================
-
- //======================================================================
-
- /// Graft the branch defined by the attributes to the parent
- void DBGraftToParent( tree::Node* parent, const AttributeMapType& attr);
- //======================================================================
- //======================================================================
-
- /// Sets an attribute of a Node and updates the database
- bool DBSetAttribute(tree::Node*,
- const std::string& key,
- const std::string& value);
- //======================================================================
- //======================================================================
- /// Sets an attribute and updates the database
- void DBSetAttribute(const std::string& levelDescriptor,
- const std::string& key,
- const std::string& value,
- const std::string& searchParam,
- const std::string& searchVal);
- //======================================================================
- //======================================================================
-
- /// Inserts the Node in the database
- void DBInsert(tree::Node* n);
- //======================================================================
-
-
- //======================================================================
-
- /// Deletes the tuple that matches the value specified in the given key and that belongs to the given level
- void DBDelete(std::string levelDescriptor, std::string key, std::string value);
- //======================================================================
-
- //======================================================================
-
- /// Recursively Removes the nodes whose parent is given as a parameter
- void DBRecursiveRemoveNode(tree::Node* node);
- /// Recursively Removes the nodes found in the given level with the given parent id
- void DBRecursiveRemoveNode(int level, std::string parentId);
-
- //======================================================================
-
-
- private:
- /// The DB
- CppSQLite3DB* mDB;
- /// The physical location associated to the DicomDatabase (directory, db file...)
- std::string mFileName;
- /// Is the DB writable ?
- bool mWritable;
- void SetWritable(bool w) { mWritable = w; }
- bool GetWritable() const { return mWritable; }
- bool mIsAdding;
-
-
- };
- // EO class SQLiteTreeHandler
- //=======================================================================
-
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOSettings.h>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <iostream>
-#include <fstream>
-
-// Memory tracking allocation
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-using namespace boost;
-namespace po = boost::program_options;
-
-namespace creaImageIO
-{
- Settings::Settings(const std::string i_path)
- {
- //need to position path in user directory first.
- m_SettingsFileName = i_path + "\\.gimmick\\Shared\\gimmick\\app.config";
- //Test if Settings File exist
- if(!boost::filesystem::exists(m_SettingsFileName) )
- {
- createFile();
- }
- std::ifstream ifs(m_SettingsFileName.c_str());
- std::string line;
- std::string sets;
- if (ifs.is_open())
- {
- while (! ifs.eof() )
- {
- getline(ifs,line);
- sets += line;
- }
- ifs.close();
- }
- std::vector<std::string> Keys;
- Keys.push_back(SETTINGS_SYNC_EVENT);
- Keys.push_back(SETTINGS_DBPATH);
- Keys.push_back(SETTINGS_SYNC_FREQ);
- Keys.push_back(SETTINGS_COPY_PATH);
- Keys.push_back(SETTINGS_REMOVE_PATIENT_DISPLAY);
- readSettings(Keys, sets);
-
- }
-
- Settings::~Settings()
- {
-
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // create the config file //
- //@param : - //
- // return : - //
- ///////////////////////////////////////////////////////////////////////////////////////////////
- void Settings::createFile()
- {
- m_SettingsMap[SETTINGS_SYNC_FREQ] = "12";
- m_SettingsMap[SETTINGS_SYNC_EVENT] = "end";
- m_SettingsMap[SETTINGS_DBPATH] = "";
- m_SettingsMap[SETTINGS_DICOM_LIBRARY] = "gdcm";
- m_SettingsMap[SETTINGS_COPY_PATH] = m_SettingsFileName.substr(0,m_SettingsFileName.find_last_of('\\')+1)+"Copied files";
- m_SettingsMap[SETTINGS_REMOVE_PATIENT_DISPLAY] = "0";
- writeSettingsFile();
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // read Settings from config file //
- // @param i_keys : list of keys //
- // @param i_file : text from config file //
- // return : -
- ///////////////////////////////////////////////////////////////////////////////////////////////
- void Settings::readSettings(std::vector<std::string> &i_Keys, const std::string &i_file)
- {
- std::vector<std::string>::iterator it_key = i_Keys.begin();
- for(; it_key< i_Keys.end(); ++it_key)
- {
- size_t fpos = i_file.find(it_key->c_str());
- size_t lpos = i_file.rfind(it_key->c_str());
- if(fpos != std::string::npos && lpos != std::string::npos)
- {
- m_SettingsMap[it_key->c_str()] = i_file.substr(fpos + it_key->size(),lpos-fpos - it_key->size());
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Update settings in config file //
- // @param key : Key to update //
- // @param value: New value to set //
- // return : -
- ///////////////////////////////////////////////////////////////////////////////////////////////
- void Settings::updateSetting(const std::string& key, const std::string &val)
- {
- m_SettingsMap[key.c_str()] = val;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // add a path to a DB //
- // @param i_path : DB path to add //
- // return : - //
- ///////////////////////////////////////////////////////////////////////////////////////////////
- void Settings::addDB(const std::string &i_path)
- {
- if(m_SettingsMap[SETTINGS_DBPATH].find(i_path) == std::string::npos)
- {
- m_SettingsMap[SETTINGS_DBPATH] += i_path + ";";
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // remove a path to a DB //
- // @param i_path : DB path to delete (don't exist anymore) //
- // return : -
- ///////////////////////////////////////////////////////////////////////////////////////////////
-
- void Settings::removeDB(const std::string &i_path)
- {
- boost::algorithm::replace_all(m_SettingsMap[SETTINGS_DBPATH],i_path + ";","");
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // write Settings buffer from //
- // @param o_file : settings buffer //
- // //
- // return : - //
- ///////////////////////////////////////////////////////////////////////////////////////////////
- void Settings::writeSettings(std::ofstream &o_file)
- {
- std::map<std::string, std::string>::iterator it_map = m_SettingsMap.begin();
- std::stringstream st;
- for(; it_map != m_SettingsMap.end(); ++it_map)
- {
- o_file << it_map->first.c_str();
- o_file << it_map->second.c_str();
- o_file << it_map->first.c_str();
- o_file << std::endl;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // write Settings file //
- // @param : - //
- // return : -
- ///////////////////////////////////////////////////////////////////////////////////////////////
- void Settings::writeSettingsFile()
- {
- std::ofstream ofs(m_SettingsFileName.c_str());
- ofs.clear();
- writeSettings(ofs);
- ofs.close();
- }
-}
-
+++ /dev/null
-#include <boost/program_options.hpp>
-#include <map>
-
-#define SETTINGS_DICOM_LIBRARY "<DICOM Library>"
-#define SETTINGS_SYNC_EVENT "<syncro_event>"
-#define SETTINGS_SYNC_FREQ "<syncro_frequency>"
-#define SETTINGS_DBPATH "<dbpath>"
-#define SETTINGS_COPY_PATH "<copy_path>"
-#define SETTINGS_REMOVE_PATIENT_DISPLAY "<remove_patient>"
-
-
-namespace creaImageIO
-{
- class Settings{
- public :
- Settings(const std::string i_path);
- ~Settings();
-
- //get the value for a given option
- const std::string getValue(const std::string i_key){return m_SettingsMap[i_key];}
-
- void addDB(const std::string &i_path);
-
- void removeDB(const std::string &i_path);
-
- void updateSetting(const std::string& key, const std::string &val);
-
- //write configuration file
- void writeSettingsFile();
-
- private :
- // Settings Key-Value Map
- std::map<std::string, std::string> m_SettingsMap;
-
- //read the configuration file
- void readSettings(std::vector<std::string> &i_Keys, const std::string &i_file);
- // create the configuration file
- void createFile();
- void writeSettings(std::ofstream &o_filebuf);
- std::string m_SettingsFileName;
-
-
- };
-}
+++ /dev/null
-#include <creaImageIOSynchron.h>
-#include <creaImageIOSystem.h>
-#include <boost/filesystem.hpp>
-#include <boost/algorithm/string.hpp>
-
-
-//namespace fs = boost::filesystem;
-
-//=====================================================================
-
-
-namespace creaImageIO
-{
-
- //=====================================================================
- #define QUERYSYNCDB(QUER,RES) \
- try \
- { \
- RES = mDB->execQuery(QUER.c_str()); \
- } \
- catch (CppSQLite3Exception& e) \
- { \
- GimmickError("SQLite query '"<<QUER<<"' Error : " \
- << e.errorCode() << ":" \
- << e.errorMessage() ); \
- }
- //=====================================================================
- #define UPDATESYNCDB(UP) \
- try \
- { \
- mDB->execDML(UP.c_str()); \
- } \
- catch (CppSQLite3Exception& e) \
- { \
- GimmickError("SQLite update '"<<UP<<"' Error : " \
- << e.errorCode() << ":" \
- << e.errorMessage() ); \
- }
- //=====================================================================
-
- Synchronizer::Synchronizer(const std::string& path)
- {
- pathDB = path + "maintenance_database.db3";
- mDB = new CppSQLite3DB;
- Initialize();
- }
-
- //=====================================================================
- Synchronizer::~Synchronizer()
- {
- delete mDB;
- }
-
- //=====================================================================
- void Synchronizer::Initialize()
- {
- if (!boost::filesystem::exists(pathDB))
- {
- CreateDB();
- }
-
- // OPENING
- else
- {
- try
- {
- mDB->open(pathDB.c_str());
- }
- catch (CppSQLite3Exception& e)
- {
- GimmickError("Opening '"<<pathDB<<"' : "
- << e.errorCode() << ":"
- << e.errorMessage());
- }
- }
- // get the ADD operations List
- //UpdateAddList(pathDB);
- }
-
- //=====================================================================
- void Synchronizer::CreateDB()
- {
- mDB->open(pathDB.c_str());
- // CREATING TABLES
- std::string command;
- command = "CREATE TABLE ";
- command += "ADD_OPS";
- command += "\n(\nADD_KEY INTEGER PRIMARY KEY";
- command += ",\nPATH text";
- command += ",\nRECURSIVE boolean";
- command += ",\nFILES_ADDED int";
- command += ",\nREFERENCEDDB text";
- command += "\n)";
- UPDATESYNCDB(command);
-
- command = "CREATE TABLE ";
- command += "IGNORED_FILES";
- command += "\n(\nID INTEGER PRIMARY KEY";
- command += ",\nADD_KEY integer";
- command += ",\nPATH text";
- command += ",\nREMOVE boolean";
- command += ",\nTIME datetext";
- command += "\n)";
- UPDATESYNCDB(command);
- }
-
- //=====================================================================
- void Synchronizer::CleanName(std::string& str) const
- {
- size_t pos;
- do
- {
- pos = str.find('\\');
- if (pos!=-1)
- {
- str.replace(pos, 1, "/");
- }
- }
- while (pos!=-1);
- }
-
- //=====================================================================
- void Synchronizer::GetFileList(std::vector<AddList> & list, const std::string& refdb)
- {
- CleanList(refdb);
- list=mAddList;
- }
-
- //=====================================================================
- void Synchronizer::GetIgnoredFiles(const std::string& key, std::vector<std::string> &ignoreList)
- {
- ignoreList=GetIgnoreList(key);
- }
-
-//=====================================================================
- void Synchronizer::UpdateAddList(const std::string& refdb)
- {
- std::string query = "SELECT * FROM ADD_OPS WHERE REFERENCEDDB = '"+refdb+"';";
- CppSQLite3Query res;
- QUERYSYNCDB(query, res);
- while (!res.eof())
- {
- AddList temp = AddList(res);
- mAddList.push_back(temp);
- res.nextRow();
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // remove an entry of the DB
- //@param i_table : table where to do the remove
- // @param i_key : the add_key reference (one entry to remove for ADD_OP table, many for IGNORED_FILES table
- //@result : -
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void Synchronizer::RemoveEntry(const std::string i_table, const std::string i_key)
- {
- std::string query = "DELETE FROM " + i_table + " WHERE ADD_KEY = '" + i_key +"'";
- UPDATESYNCDB(query);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // remove several entries of the DB
- // @param i_table : table where to do the remove
- // @param i_attribute: attribute to match
- // @param i_operand : operand to use
- // @param i_val : the reference
- //@result : -
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void Synchronizer::RemoveEntries(const std::string i_table,
- const std::string i_attribute,
- const std::string i_operand,
- const std::string i_val)
- {
- std::stringstream query;
- query<<"DELETE FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
- UPDATESYNCDB(query.str());
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // clean DataBase if an operation has no child anymore
- // @param refdb: the database segement to clean
- // @result : -
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void Synchronizer::CleanList(const std::string& refdb)
- {
- mAddList.clear();
- UpdateAddList(refdb);
- std::vector<AddList>::iterator it_add = mAddList.begin();
- for(;it_add <mAddList.end(); ++it_add)
- {
- if(it_add->nbFiles == "0")
- {
- RemoveEntry("ADD_OPS", it_add->key);
- RemoveEntry("IGNORED_FILES", it_add->key);
-
- }
- }
- mAddList.clear();
- UpdateAddList(refdb);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Inserts a new add operation in the database
- // @param path: the path of the directory that was added
- // @param recursive: shows if the action was called recursively or not
- // @param nChildren: the number of files affected by the operation
- // @param refdb: the referenced database
- // @result : The operation has been added
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void Synchronizer::InsertAddOp(const std::string& path, const std::string& recursive, const std::string& nChildren, const std::string& refdb)
- {
- std::string insert;
- std::string pat=path.c_str();
- CleanName(pat);
- insert="INSERT INTO ADD_OPS (PATH,RECURSIVE,FILES_ADDED,REFERENCEDDB) VALUES('";
- insert+=pat+"','";
- insert+=recursive+"',";
- insert+=nChildren+",'";
- insert+=refdb+"');";
- UPDATESYNCDB(insert);
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Inserts a new ignored file in the database
- // @param add_key: the key of the add_op to which it corresponds
- // @param path: the path of the directory that was added
- // @param remove: shows if the file was removed or not
- // @param time: the time in which the file was removed
- // @result : The file has been inserted
- /////////////////////////////////////////////////////////////////////////////////////////////////
-
- void Synchronizer::InsertIgnoreFile(const std::string& addKey, const std::string& path, const std::string& remove, const std::string& time, const std::string& refdb )
- {
- std::string pat=path.c_str();
- CleanName(pat);
- std::string id=GetAttribute("ID","IGNORED_FILES","PATH",pat,refdb);
- if(id.compare("")==0)
- {
- std::string insert;
- insert="INSERT INTO IGNORED_FILES (ADD_KEY,PATH,REMOVE,TIME) VALUES('";
- insert+=addKey+"','";
- insert+=pat+"','";
- insert+=remove+"',";
- insert+=time+");";
- UPDATESYNCDB(insert);
- }
- else
- {
- //Gets the add key
- std::string ak=GetAttribute("ADD_KEY","IGNORED_FILES","ID",id,refdb);
- //gets the parent database to check if the file has been added to the current database
- std::string parentDB=GetAttribute("*","ADD_OPS","ADD_KEY",ak,refdb);
- //If there is no such entry, add it
- if(parentDB.compare("")==0)
- {
- std::string insert;
- insert="INSERT INTO IGNORED_FILES (ADD_KEY,PATH,REMOVE,TIME) VALUES('";
- insert+=addKey+"','";
- insert+=pat+"','";
- insert+=remove+"',";
- insert+=time+");";
- UPDATESYNCDB(insert);
- }
- else
- {
- //Sets the new add key attribute for the file
- SetAttribute("ADD_KEY","IGNORED_FILES",addKey,"ID", id,refdb);
- //Sets the new remove attribute for the file
- SetAttribute("REMOVE","IGNORED_FILES",remove,"ID", id,refdb);
- //Sets the new time attribute for the file
- SetAttribute("TIME","IGNORED_FILES",time,"ID", id,refdb);
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // get the files name to ignore for a add operation synchronization
- // @param : the add key
- //@result : list (path) of ignore files
- /////////////////////////////////////////////////////////////////////////////////////////////////
- std::vector<std::string> Synchronizer::GetIgnoreList(const std::string &i_key)
- {
- mIgnoreList.clear();
- std::vector<std::string> i_names;
- std::string query = "SELECT * FROM IGNORED_FILES WHERE ADD_KEY = ";
- query+=i_key;
- CppSQLite3Query res;
- QUERYSYNCDB(query, res);
- while (!res.eof())
- {
- RemoveList temp = RemoveList(res);
- if(temp.remove.compare("0")==0)
- {
- mIgnoreList.push_back(temp);
- }
- res.nextRow();
- }
- std::vector<RemoveList>::iterator it;
-
- for(it = mIgnoreList.begin();it != mIgnoreList.end(); ++it)
- {
- i_names.push_back((*it).path);
- }
- return i_names;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Gets the required attribute in the required table
- // @param attribute: the attribute to look for
- // @param table: the table to look in
- // @param searchParam: the search parameter
- // @param searchValue: the search value
- // @result : required attribute
- /////////////////////////////////////////////////////////////////////////////////////////////////
- std::string Synchronizer::GetAttribute(const std::string& attribute,
- const std::string& table,
- const std::string& searchParam,
- const std::string& searchValue,
- const std::string& refdb)
- {
- std::stringstream query;
- std::string result;
- std::string sVal=searchValue.c_str();
- CleanName(sVal);
- query<<"SELECT "<<attribute<<" FROM "<<table<<" WHERE "<<searchParam<<" = '"<<sVal;
- if(table.compare("ADD_OPS")==0)
- {
- query<<"' AND REFERENCEDDB = '"<<refdb<<"';";
- }
- else
- {
- query<<"';";
- }
- CppSQLite3Query res;
- QUERYSYNCDB(query.str(), res);
- while (!res.eof())
- {
- result=res.getStringField(0);
- res.nextRow();
- }
- return result;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Sets the attribute value in the required table and column
- // @param attribute: the attribute to look for
- // @param table: the table to look in
- // @param value: the value to set
- // @param searchParam: the search parameter
- // @param searchValue: the search value
- // @result : attribute value changed
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void Synchronizer::SetAttribute(const std::string& attribute,
- const std::string& table,
- const std::string& value,
- const std::string& searchParam,
- const std::string& searchValue,
- const std::string& refdb)
- {
- std::string val=value.c_str();
- std::string sVal=searchValue.c_str();
- CleanName(val);
- CleanName(sVal);
- std::string sql = "UPDATE ";
- sql+=table;
- sql+=" SET ";
- sql += attribute;
- sql += " = '";
- sql += val;
- sql += "' WHERE ";
- sql += searchParam;
- sql += " = '";
- sql += sVal;
- if(table.compare("ADD_OPS")==0)
- {
- sql += "' AND REFERENCEDDB = '";
- sql += refdb;
- }
- sql += "';";
- UPDATESYNCDB(sql);
- }
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////////
- // get the files name to ignore for a add operation synchronization
- // @param : the add key
- //@result : list (path) of ignore files
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void Synchronizer::GetList(const std::string i_db)
- {
- mList.clear();
- std::vector<std::string> i_names;
- std::vector<std::string> keys;
- CppSQLite3Query res;
- std::string query ="SELECT ADD_KEY, REFERENCEDDB FROM ADD_OPS";
- QUERYSYNCDB(query, res);
- keys.clear();
- while (!res.eof())
- {
- std::string key(res.getStringField(0));
- std::string db(res.getStringField(1));
- if (db == i_db)
- {
- keys.push_back(key);
- }
- res.nextRow();
- }
- query = "SELECT PATH, REMOVE FROM IGNORED_FILES WHERE";
- if(keys.size() > 0)
- {
- for (int i=0; i < keys.size(); i++)
- {
- query += " ADD_KEY = " + keys[i];
- query += " AND";
- }
- query = query.substr(0,query.size() - 4);
- }
- else
- {
- query += " ADD_KEY = -1";
- }
- QUERYSYNCDB(query, res);
- while (!res.eof())
- {
- std::string file(res.getStringField(0));
- std::string ignore(res.getStringField(1));
- mList[file] = ignore == "0"? true : false;
- res.nextRow();
- }
- }
-
- bool Synchronizer::isIndexed(const std::string filename)
- {
- bool valid = true;
- std::string name(filename);
- boost::algorithm::replace_all( name,"\\" , "/");
- std::map <std::string, bool>::iterator it_list = mList.begin();
- for(;it_list != mList.end(); it_list++)
- {
- if(it_list->first == name)
- {
- valid = false;
- break;
- }
- }
- return valid;
- }
-}
-
-
+++ /dev/null
-#ifndef __creaImageIOSynchron_h_INCLUDED__
-#define __creaImageIOSynchron_h_INCLUDED__
-
-#include <string>
-#include <map>
-#include <iostream>
-#include <vector>
-#include "CppSQLite3.h"
-
-namespace creaImageIO
-{
- using namespace std;
- //================================================================================================================
- ///Represents the list of currently added files
- class AddList
- {
- public :
- ///Key to be added into the database
- std::string key;
- ///Path of the directory
- std::string path;
- /// Defines if the operation was recursive or not
- std::string recursive;
- ///Number of added files
- std::string nbFiles;
- ///Ctor
- AddList(CppSQLite3Query& res):
- key(res.getStringField(0)),
- path(res.getStringField(1)),
- recursive(res.getStringField(2)),
- nbFiles(res.getStringField(3))
- {}
- };
- //================================================================================================================
-
- //================================================================================================================
- ///Represents the list of currently removed files
- class RemoveList
- {
- public :
- ///Key to be added into the database
- std::string key;
- ///Path of the remove file
- std::string path;
- ///Defines if the file was removed or not
- std::string remove;
- ///Time of the last change of the file
- std::string time;
- ///Ctor
- RemoveList(CppSQLite3Query& res):
- key(res.getStringField(1)),
- path(res.getStringField(2)),
- remove(res.getStringField(3)),
- time(res.getStringField(4))
- {}
- };
- //================================================================================================================
-
- //================================================================================================================
- ///In charge of the synchronization of the database and the disk state.
- class Synchronizer
- {
- public:
- ///Ctor
- Synchronizer(const std::string& path);
- ///Dtor
- virtual ~Synchronizer();
- ///Initializes the database
- void Initialize();
- ///Inserts an add operation to the database
- void InsertAddOp(const std::string& path,
- const std::string& recursive,
- const std::string& nChildren,
- const std::string& refdb);
- ///Inserts a file to be ignored
- void InsertIgnoreFile(const std::string& addKey,
- const std::string& path,
- const std::string& remove,
- const std::string& time,
- const std::string& refdb);
- ///Removes an entry that matches the given parameter
- void RemoveEntry(const std::string i_table, const std::string i_key);
- ///Removes several entries
- void RemoveEntries(const std::string i_table,
- const std::string i_attribute,
- const std::string i_operand,
- const std::string i_key);
- ///Gets the list of AddFiles
- void GetFileList(std::vector<AddList>& files , const std::string& refdb);
- ///Gets the list of ignored files
- void GetIgnoredFiles(const std::string& key, std::vector<std::string> &ignoreList);
- ///Gets the attribute that matches the parameters
- std::string GetAttribute(const std::string& attribute,
- const std::string& table,
- const std::string& searchParam,
- const std::string& searchValue,
- const std::string& refdb);
- ///Sets an attribute to an entry that matches the given parameters
- void SetAttribute(const std::string& attribute,
- const std::string& table,
- const std::string& value,
- const std::string& searchParam,
- const std::string& searchValue,
- const std::string& refdb);
- // Get the List of indexed files (removed or not)
- void GetList(const std::string i_db);
- // Test to not if a file is indexed on db or not
- bool isIndexed(const std::string filename);
- // List of all indexed files
- std::map <std::string, bool> mList;
- ///The current AddList
- std::vector<AddList> mAddList;
- ///The current RemoveList
- std::vector<RemoveList> mIgnoreList;
- private :
-
- /// The DB
- CppSQLite3DB* mDB;
- ///Path of the current database
- std::string pathDB;
- ///Creates a new database
- void CreateDB();
- ///Updates the AddList
- void UpdateAddList(const std::string& refdb);
- ///Cleans the list in case operations are no longer useful (0 added files)
- void CleanList(const std::string& refdb);
- ///Cleans the name (changes slashes and backslashes according to the system)
- void CleanName(std::string& str) const;
- ///Gets the ignore list
- std::vector<std::string> GetIgnoreList(const std::string &i_key);
-
- };
- //================================================================================================================
-
-
-}
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOSystem.h>
-#include <creaImageIOSynchronizer.h>
-#include "boost/filesystem.hpp"
-
-namespace fs = boost::filesystem;
-
-namespace creaImageIO
-{
-
- //==============================================================
- Synchronizer::Synchronizer(TreeHandler * th)
- : mHandler(th)
- {
-
- }
- //==============================================================
-
- //==============================================================
- Synchronizer::~Synchronizer()
- {
-
- }
- //==============================================================
-
- //==============================================================
- std::string Synchronizer::Synchronize(bool update)
- {
- GimmickMessage(1,"Synchronizing "<<std::endl);
- int id=1;
- std::stringstream mess;
- std::string file;
- mHandler->GetAttribute("Image","","","FullFileName",file);
- size_t ini=0;
- size_t fin=0;
- while(fin<file.size()-1)
- {
- fin=file.find('#',ini);
- SynchronizeFile(update,file.substr(ini,fin-ini),mess);
- ini=fin+1;
- }
- if(mess.str()=="")
- {
- mess<<"Database up to date"<<std::endl;
- }
- GimmickMessage(1,mess.str());
- return mess.str();
- }
- //==============================================================
-
- //==============================================================
- void Synchronizer::SynchronizeFile(bool update, std::string file, std::stringstream& mess)
- {
- if(!FileExists(file))
- {
- if(update)
- {
- mHandler->DeleteTuple("Image","FullFileName",file);
- mess<<file<<" has been removed from the DB"<<std::endl;
- }
- else
- {
- mess<<file<<" State: Non existant"<<std::endl;
- }
- }
- else
- {
- AttributesMatch(update,file,mess);
- }
- }
- //==============================================================
-
- //==============================================================
- bool Synchronizer::FileExists(std::string file)
- {
- GimmickDebugMessage(4,"Verifying if file "<<file<<" exists"<<std::endl);
- bool exists=true;
- if ( !fs::exists( file ) )
- {
- exists=false;
- }
- return exists;
- }
- //==============================================================
-
- //==============================================================
- void Synchronizer::AttributesMatch(bool update, std::string file, std::stringstream& mess)
- {
- std::map< std::string, std::string> attr;
- mHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
- mReader.ReadAttributes(file,attr);
- tree::LevelDescriptor::AttributeDescriptorListType adl= mHandler->GetTree().GetAttributeDescriptorList(mHandler->GetTree().GetNumberOfLevels()-1);
- tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = adl.begin();a!=adl.end();++a)
- {
- std::string databaseVal;
- mHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
- std::string fileVal=attr.find(a->GetKey())->second;
- if ( a->GetFlags()==0 && databaseVal.compare(fileVal)!=0 )
- {
- if(update)
- {
- mHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
- mess<<file<<" has been updated in the DB"<<std::endl;
- }
- else
- {
- mess<<file<<" State: Attributes differ"<<std::endl;
- }
- }
- }
- }
- //==============================================================
-
-}
\ No newline at end of file
+++ /dev/null
-#ifndef __creaImageIOSynchronizer_h_INCLUDED__
-#define __creaImageIOSynchronizer_h_INCLUDED__
-
-#include <creaImageIOSQLiteTreeHandler.h>
-#include <creaImageIOImageReader.h>
-
-namespace creaImageIO
-{
-
-//=======================================================================
-/// Synchronizes a given database with disk
-class Synchronizer
- {
- public:
- /// Ctor
- Synchronizer(TreeHandler* th);
- /// Dtor
- ~Synchronizer();
- ///Sets the tree handler to use in order to synchronize with a given database
- void SetTreeHandler(TreeHandler * handler){mHandler=handler;}
- ///Synchronizes the database in the current tree handler with disk by doing the passed action. If it is true,
- ///the database will be updated, otherwise a warning message will be returned.
- std::string Synchronize(bool update);
- ///Checks if the file given as a parameter exists in the drive
- bool FileExists(std::string file);
- ///Checks if the attributes of the node given as a parameter matchwith it correspondent file in disk
- ///NB: This method doesn't check the existence of the file, so FileExists should be called before.
- void AttributesMatch(bool update, std::string file, std::stringstream& mess);
-
-
- private:
- ///The tree handler
- TreeHandler* mHandler;
- ///The image reader
- ImageReader mReader;
- ///Synchronizes the given file, doing the action required and returning the result on the string supplied
- void SynchronizeFile(bool update, std::string file, std::stringstream& message);
-
- };
-} // EO namespace creaImageIO
-
-// EOF
-#endif
\ No newline at end of file
+++ /dev/null
-#ifndef __creaImageIOSystem_INCLUDED__
-#define __creaImageIOSystem_INCLUDED__
-
-#include "creaMessageManager.h"
-
-
-#if defined(_WIN32)
- #ifdef CREAIMAGEIO_EXPORT_SYMBOLS
- #define CREAIMAGEIO_EXPORT __declspec( dllexport )
-#else
- #define CREAIMAGEIO_EXPORT __declspec( dllimport )
- #endif
- #define CREAIMAGEIO_CDECL __cdecl
-#else
- #define CREAIMAGEIO_EXPORT
- #define CREAIMAGEIO_CDECL
-#endif // defined(_WIN32)
-
-
-namespace creaImageIO
-{
- //==============================================================
- inline void RegisterGimmickMessageTypes()
- {
- static bool first_time = true;
- if (first_time)
- {
- crea::MessageManager::RegisterMessageType("Gimmick!",
- "Gimmick",1);
- crea::MessageManager::RegisterMessageType("Gimmick! DEBUG",
- "Gimmick",0);
- first_time = false;
- }
- }
- //==============================================================
- inline void SetGimmickMessageLevel(int l)
- {
- RegisterGimmickMessageTypes();
- crea::MessageManager::SetMessageLevel("Gimmick!",l);
- }
- //==============================================================
- inline void SetGimmickDebugMessageLevel(int l)
- {
- RegisterGimmickMessageTypes();
- crea::MessageManager::SetMessageLevel("Gimmick! DEBUG",l);
- }
- //==============================================================
-
-
-
-#define GimmickMessage(LEV,MESS) \
- creaMessage("Gimmick!",LEV,"[Gimmick!] "<<MESS);
-#define GimmickDebugMessage(LEV,MESS) \
- creaDebugMessage("Gimmick! DEBUG",LEV,"[Gimmick!] DEBUG: "<<MESS);
-#define GimmickError(MESS) \
- creaError("[Gimmick!] "<<MESS);
-
-} // namespace
-
-#endif
-
+++ /dev/null
-#include <creaImageIOTimestampDatabaseHandler.h>
-#include <creaImageIOSystem.h>
-
-#include "CppSQLite3.h"
-
-#include <sys/stat.h>
-
-#include <deque>
-
-#include <boost/filesystem.hpp>
-#include <boost/algorithm/string/replace.hpp>
-
-namespace creaImageIO
-{
- using namespace tree;
- //=============================================================
- TimestampDatabaseHandler::TimestampDatabaseHandler(const std::string& filename)
- : mFileName(filename)
- {
- mDB = new CppSQLite3DB;
- GimmickMessage(1,"SQLite version : "
- <<std::string(mDB->SQLiteVersion())<< std::endl);
- }
- //=============================================================
-
- //=============================================================
- TimestampDatabaseHandler::~TimestampDatabaseHandler()
- {
- delete mDB;
- }
- //=============================================================
- //=====================================================================
- bool TimestampDatabaseHandler::Open()
- {
- return DBOpen();
- }
-
- //=====================================================================
- bool TimestampDatabaseHandler::Create()
- {
- return DBCreate();
- }
- //=====================================================================
-
-
- //=====================================================================
- bool TimestampDatabaseHandler::Close()
- {
- return true;
- }
- //=====================================================================
-
-
- //=====================================================================
- bool TimestampDatabaseHandler::Destroy()
- {
- return false;
- }
-
-
-
-
-
-
- //=====================================================================
- // SQLite DB specific methods
- //=====================================================================
- //=====================================================================
-#define QUERYTIMESTAMPDB(QUER,RES) \
- try \
- { \
- GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
- RES = mDB->execQuery(QUER.c_str()); \
- } \
- catch (CppSQLite3Exception& e) \
- { \
- GimmickError("SQLite query '"<<QUER<<"' : " \
- << e.errorCode() << ":" \
- << e.errorMessage() ); \
- } \
- //=====================================================================
-#define UPDATETIMESTAMPDB(UP) \
- try \
- { \
- GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
- mDB->execDML(UP.c_str()); \
- } \
- catch (CppSQLite3Exception& e) \
- { \
- GimmickError("SQLite update '"<<UP<<"' Error : " \
- << e.errorCode() << ":" \
- << e.errorMessage() ); \
- }
- //=====================================================================
-
-
- //=====================================================================
- bool TimestampDatabaseHandler::DBOpen()
- {
- GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
- <<"' ... "<<std::endl);
- // OPENING FILE
- if (!boost::filesystem::exists(GetFileName()))
- {
- return false;
- }
-
- try
- {
- mDB->open(GetFileName().c_str());
- }
- catch (CppSQLite3Exception& e)
- {
- GimmickError("Opening '"<<GetFileName()<<"' : "
- << e.errorCode() << ":"
- << e.errorMessage());
- return false;
- }
-
- GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
- <<"' ... OK"<<std::endl);
- return true;
- }
- //=====================================================================
-
- //=====================================================================
- bool TimestampDatabaseHandler::DBCreate()
- {
- GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
- <<"' ... "<<std::endl);
-
- if (boost::filesystem::exists(GetFileName()))
- {
- GimmickError(GetFileName()<<"' : "
- << "file already exists");
- return false;
- }
-
- // OPENING
- try
- {
- mDB->open(GetFileName().c_str());
- }
- catch (CppSQLite3Exception& e)
- {
- GimmickError(e.errorCode() << ":"
- << e.errorMessage() <<std::endl);
- return false;
- }
-
-
- // CREATING TABLES
-
- std::string command;
-
-
- command = "CREATE TABLE ";
- command += "FILES";
- command += "\n(\nID INTEGER PRIMARY KEY";
- command += ",\nPARENT_ID int not null";
- command += ",\nPATH text";
- command += ",\nLastModified datetext";
- command += ",\nLastRead datetext";
- command += ",\nTopLevelNodeId text";
- command += ",\nReferencedDB text";
- command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
- command += "FILES";
- command += "(ID) on delete restrict on update restrict";
-
- command += "\n)";
- UPDATETIMESTAMPDB(command);
-
- return true;
- }
-
-
-
- //=====================================================================
- void TimestampDatabaseHandler::CleanPath(std::string& str) const
- {
- size_t pos;
- do
- {
- pos = str.find('\\');
- if ((int)pos!=-1)
- {
- str.replace(pos, 1, "/");
- }
- }
- while ((int)pos!=-1);
- }
- //=====================================================================
-
- bool TimestampDatabaseHandler::AddDirectory(const std::string& parent,
- const std::string& path,
- const time_t lastModif,
- const time_t lastRead,
- const std::string& refdb)
- {
- bool valid=false;
- std::string par=parent.c_str();
- std::string pat=path.c_str();
- CleanPath(par);
- CleanPath(pat);
-
- std::string pathId=IsIndexed(pat,refdb);
- //Case: It is a root parent
- if(parent.compare("")==0)
- {
- if(pathId.compare("")==0)
- {
- AddFile(pat,lastModif,lastRead,refdb);
- valid=true;
- }
- else
- {
- valid=CheckTimestamp(pathId, lastModif, refdb);
- }
- }
- else
- {
- std::string parentId=IsIndexed(par,refdb);
- //Case: Parent is not in database
- if(parentId.compare("")==0)
- {
- AddFile(par,lastModif,lastRead,refdb);
- parentId=IsIndexed(par,refdb);
- }
-
- //Case path is not in database
- if(pathId.compare("")==0)
- {
- AddFile(parentId,pat,lastModif,lastRead,refdb);
- valid=true;
- }
- //Parent and path are in the database
- else
- {
- SetAttribute("PARENT_ID",parentId,"ID", pathId);
- valid=CheckTimestamp(pathId, lastModif, refdb);
- }
- }
- return valid;
-
- }
-
- //=====================================================================
-
- void TimestampDatabaseHandler::AddFile(const std::string& path, const time_t lastModif, const time_t lastRead, const std::string& refdb)
- {
- std::stringstream out;
- out<<"INSERT INTO FILES (PARENT_ID,PATH,LastModified,LastRead,ReferencedDB) VALUES(0,'"<<path<<"',";
- out<<lastModif<<","<<lastRead<<",'"<<refdb<<"');";
- UPDATETIMESTAMPDB(out.str());
-
- }
-
- //=====================================================================
-
- void TimestampDatabaseHandler::AddFile(const std::string& parentId,
- const std::string& path,
- const time_t lastModif,
- const time_t lastRead,
- const std::string& refdb)
- {
- std::stringstream out;
- out<<"INSERT INTO FILES (PARENT_ID,PATH,LastModified,LastRead,ReferencedDB) VALUES("<<parentId<<",'"<<path<<"',";
- out<<lastModif<<","<<lastRead<<",'"<<refdb<<"');";
- UPDATETIMESTAMPDB(out.str());
- }
-
- //=====================================================================
- std::string TimestampDatabaseHandler::IsIndexed(const std::string& path, const std::string& refdb)
- {
- std::string pat=path.c_str();
- CleanPath(pat);
- std::stringstream out;
- std::stringstream result;
- out<<"SELECT ID FROM FILES WHERE PATH='"<<pat<<"' AND REFERENCEDDB='"<<refdb<<"';";
-
- CppSQLite3Query q;
- QUERYTIMESTAMPDB(out.str(),q);
-
-
- while (!q.eof())
- {
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- result<<q.getStringField(fld);
- }
- q.nextRow();
- }
-
- return result.str();
- }
-
- //=====================================================================
- void TimestampDatabaseHandler::SetAttribute(const std::string& attName,
- const std::string& attValue,
- const std::string& searchParam,
- const std::string& searchValue)
- {
- std::string av=attValue.c_str();
- std::string sv=searchValue.c_str();
- CleanPath(av);
- CleanPath(sv);
-
- std::string sql = "UPDATE FILES SET ";
- sql += attName;
- sql += " = '";
- sql += av;
- sql += "' WHERE ";
- sql += searchParam;
- sql += " = '";
- sql += sv;
- sql += "'";
- UPDATETIMESTAMPDB(sql);
- }
-
- //=====================================================================
- void TimestampDatabaseHandler::RemoveNode(const std::string& searchAtt, const tree::Node* node, const std::string& refdb)
- {
- int n=node->GetNumberOfChildren();
- if(n>0)
- {
- std::vector<tree::Node*> children=node->GetChildrenList();
- std::vector<tree::Node*>::iterator it;
- for(it=children.begin();it!=children.end();++it)
- {
- RemoveNode(searchAtt,(*it),refdb);
- }
- }
- else if(node->GetLevel()==3)
- {
- RemoveFile(searchAtt,node->GetAttribute("FullFileName"),refdb);
- }
- else
- {
- DBRemove("TopLevelNodeId",node->GetAttribute("ID"),refdb);
- }
-
-
- }
- //=====================================================================
- void TimestampDatabaseHandler::RemoveFile(const std::string& searchAtt, const std::string& searchVal, const std::string& refdb )
- {
-
- std::stringstream result;
- std::string sel="SELECT PARENT_ID FROM FILES WHERE "+searchAtt+"='"+searchVal+"' AND REFERENCEDDB='"+refdb+"';";
-
- CppSQLite3Query q;
- QUERYTIMESTAMPDB(sel,q);
-
- while (!q.eof())
- {
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- result<<q.getStringField(fld);
- }
- q.nextRow();
- }
- DBRemove(searchAtt,searchVal,refdb);
-
- int nChildren=0;
- sel="SELECT ID FROM FILES WHERE PARENT_ID='"+result.str()+"'";
- CppSQLite3Query q2;
- QUERYTIMESTAMPDB(sel,q2);
- while (!q2.eof())
- {
- nChildren++;
- q2.nextRow();
- }
- if(nChildren<1)
- {
- if(!result.str().compare("0"))
- {
- RemoveFile("ID",result.str(),refdb);
- }
- else
- {
- DBRemove("ID",result.str(),refdb);
- }
- }
- }
-
- //=====================================================================
- void TimestampDatabaseHandler::DBRemove(const std::string& searchAtt, const std::string& searchVal, const std::string& refdb)
- {
-
- std::string query = "DELETE FROM FILES WHERE "+searchAtt+"='"+ searchVal + "' AND REFERENCEDDB='"+refdb+"';";
- UPDATETIMESTAMPDB(query);
- }
-
- //=====================================================================
- bool TimestampDatabaseHandler::CheckTimestamp(const std::string pathId, const time_t lastModif, const std::string& refdb)
- {
- std::string sel="SELECT LastModified FROM FILES WHERE ID='"+pathId+"' AND REFERENCEDDB='"+refdb+"';";
- CppSQLite3Query q;
- QUERYTIMESTAMPDB(sel,q);
- double timestamp;
-
- while (!q.eof())
- {
- for (int fld = 0; fld < q.numFields(); fld++)
- {
- timestamp=q.getFloatField(fld);
- }
- q.nextRow();
- }
-
-
- std::stringstream lm;
- lm<<lastModif;
- double modif=atof((lm.str()).c_str());
- if(timestamp<modif)
- {
- SetAttribute("LastModified",lm.str(),"ID",pathId);
- return true;
- }
- return false;
- }
-
- //=====================================================================
- void TimestampDatabaseHandler::RemoveEntries(const std::string i_table,
- const std::string i_attribute,
- const std::string i_operand,
- const std::string i_val)
- {
- std::stringstream query;
- query<<"DELETE FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
- UPDATETIMESTAMPDB(query.str());
- }
-
-}// namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOTimestampDatabaseHandler_h_INCLUDED__
-#define __creaImageIOTimestampDatabaseHandler_h_INCLUDED__
-#include <vector>
-#include <map>
-#include <creaImageIOTree.h>
-class CppSQLite3DB;
-
-namespace creaImageIO
-{
- using namespace std;
-//=======================================================================
- /// Concrete TreeHandler which manages a Tree stored in a sqlite database
- class TimestampDatabaseHandler
- {
- public:
- //====================================================================
- /// Ctor with database file name
- TimestampDatabaseHandler(const std::string& filename);
- /// Dtor
- virtual ~TimestampDatabaseHandler();
- //====================================================================
-
- //====================================================================
- /// Returns the sqlite db file name
- const std::string& GetFileName() const { return mFileName; }
- //====================================================================
-
- //====================================================================
- // INITIALIZATION / FINALIZATION
- //====================================================================
-
- //====================================================================
- /// Opens an existing 'source'
- bool Open();
- /// Closes the 'source'
- bool Close();
- /// Creates a new 'source'
- bool Create();
- /// Destroys the 'source'
- bool Destroy();
- //====================================================================
-
- //====================================================================
- // READ / WRITE
- //====================================================================
- //====================================================================
- ///Returns the id of the path if it's indexed, blank otherwise
- std::string IsIndexed(const std::string& path, const std::string& refdb);
- ///Sets the current path's parent
- bool AddDirectory(const std::string& parent,
- const std::string& path,
- const time_t lastModif,
- const time_t lastRead,
- const std::string& refdb);
- ///Adds a new file to the database without a parent
- void AddFile(const std::string& path, const time_t lastModif, const time_t lastRead, const std::string& refdb);
- ///Adds a new file to the database with a parent
- void AddFile(const std::string& parentId,const std::string& path, const time_t lastModif, const time_t lastRead, const std::string& refdb);
- ///Sets the attribute to the value passed as parameter where the searchParameter is searchValue
- void SetAttribute(const std::string& attName,
- const std::string& attValue,
- const std::string& searchParam,
- const std::string& searchValue);
- ///Removes the given node
- void RemoveNode(const std::string& searchAtt, const tree::Node* node, const std::string& refdb);
- ///Removes the filename with the given pathname
- void RemoveFile(const std::string& searchAtt, const std::string& searchVal, const std::string& refdb);
- ///Cleans the path name
- void CleanPath(std::string& str) const;
- ///Checks the timestamp in the database and compares it with the given one.
- //If there is a difference, it will return false, otherwise it will return true.
- bool CheckTimestamp(const std::string pathId, const time_t lastModif, const std::string& refdb);
- ///Removes the entries that match the given parameters
- void RemoveEntries(const std::string i_table,
- const std::string i_attribute,
- const std::string i_operand,
- const std::string i_val);
-
- //====================================================================
-
-
- protected:
- //======================================================================
- /// Open the database
- bool DBOpen();
- //======================================================================
- //======================================================================
- // Creation
- /// Creates a new database on disk and the tables
- bool DBCreate();
- //======================================================================
- //======================================================================
- // Removes a file from the database
- void DBRemove(const std::string& searchAtt, const std::string& searchVal, const std::string& refdb);
-
- private:
- /// The DB
- CppSQLite3DB* mDB;
- /// The physical location associated to the DicomDatabase (directory, db file...)
- std::string mFileName;
-
- };
- // EO class
- //=======================================================================
-
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOTree.h>
-#include <creaImageIOSystem.h>
-
-
-namespace creaImageIO
-{
- namespace tree
- {
-
- Tree::Tree()
- : Node(0)
- {
- GimmickMessage(5,"Default Tree constructor"
- << std::endl);
-
- }
-
- Tree::~Tree()
- {
-
- }
-
- void Tree::Print() const
- {
- GimmickMessage(1,GetLabel()<<std::endl);
- ChildrenListType::const_iterator i;
- for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
- {
- (*i)->Print();
- }
-
- }
- }
-}
+++ /dev/null
-#ifndef __creaImageIOTree_h_INCLUDED__
-#define __creaImageIOTree_h_INCLUDED__
-
-#include <creaImageIOTreeNode.h>
-
-namespace creaImageIO
-{
-
- namespace tree
- {
- /**
- * \ingroup Tree
- */
- //=====================================================================
- /// Abstract class to store user data on a Tree
- struct TreeData
- {
- TreeData() {}
- virtual ~TreeData() {}
- };
- //=====================================================================
-
- //=====================================================================
- /// An attributed Tree structure
- /** \ingroup Tree
- */
- class Tree : public Node
- {
- public:
- /// Ctor
- Tree();
- /// Virtual destructor
- virtual ~Tree();
-
- /// Returns the descriptor of the tree
-
- /// Returns the tree to which the node belongs
- virtual Tree* GetTree() { return this; }
- /// Returns the tree to which the node belongs
- virtual const Tree* GetTree() const { return this; }
- /// Returns the level of the node in the tree
- virtual int GetLevel() const { return 0; }
-
- /// Returns the Descriptor of the tree (const)
- const Descriptor& GetDescriptor() const { return mDescriptor; }
- /// Returns the descriptor of the tree
- Descriptor& GetDescriptor() { return mDescriptor; }
-
- /// Returns the number of levels of the tree
- unsigned int GetNumberOfLevels()
- { return GetDescriptor().GetNumberOfLevels(); }
-
- /// Returns the LevelDescriptor of a given level (const ref)
- const LevelDescriptor& GetLevelDescriptor(int level) const
- { return GetDescriptor().GetLevelDescriptor(level); }
-
- /// Returns the AttributeDescriptorList of a given level (const ref)
- const LevelDescriptor::AttributeDescriptorListType&
- GetAttributeDescriptorList(int level) const
- { return GetDescriptor().GetAttributeDescriptorList(level); }
-
- virtual void Print() const;
-
- private:
- Descriptor mDescriptor;
-
- };
- // EO class Tree
- //=====================================================================
-
- } // EO namespace tree
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOTreeAttributeDescriptor.h>
-#include <creaImageIOSystem.h>
-
-
-#if defined(USE_GDCM)
-#include <gdcmGlobal.h>
-#include <gdcmDictSet.h>
-#endif
-
-#if defined(USE_GDCM2)
-#include <gdcmGlobal.h>
-#include <gdcmDicts.h>
-#include <gdcmDict.h>
-#endif
-
-#include <boost/algorithm/string/replace.hpp>
-
-namespace creaImageIO
-{
-
- namespace tree
- {
-
- //========================================================================
- void AttributeDescriptor::CleanName(std::string& str) const
- {
- // quote must be doubled for SQL
- // crea::Utils::Replace( str, "'", "''" );
- boost::algorithm::replace_all(str,"'","''");
- // Found strange strings which contained NULL char INSIDE string
- int i,size=str.size();
- for (i=0;i<size;++i)
- {
- if (str[i]==0)
- {
- str = str.substr(0,i);
- break;
- }
- }
- }
- //========================================================================
-
- //=====================================================================
- // Ctor with key, name and flags
- AttributeDescriptor::AttributeDescriptor(const std::string& key,
- const std::string& name,
- unsigned int flags)
- : mKey(key), mName(name), mGroup(0), mElement(0), mFlags(flags)
- {
-
- CleanName(mName);
- GimmickDebugMessage(3,"AttributeDescriptor : '"<<key
- <<"' ["<<flags<<"]"<<std::endl);
- GimmickDebugMessage(3,"='"<<mName<<"'"<<std::endl);
- }
-
- //=====================================================================
-
- //=====================================================================
- // Ctor with dicom group, elem and flags
- // The key is built as 'Dgroup_elem'
- // The user name is retreived from dicom dictionnary
- AttributeDescriptor::AttributeDescriptor(unsigned short group,
- unsigned short element,
- unsigned int flags)
- : mGroup(group), mElement(element), mFlags(flags)
- {
-
- //GDCM_NAME_SPACE::TagKey tag(group,element);
- char ctag[12];
- sprintf(ctag,"D%04x_%04x",group,element);
- mKey = ctag;
-
- GimmickDebugMessage(3,"AttributeDescriptor : '"<<mKey
- <<"' ["<<flags<<"]"<<std::endl);
-
-#if defined(USE_GDCM)
- // Retrieve the name from gdcm dict
- GDCM_NAME_SPACE::DictEntry* entry =
- GDCM_NAME_SPACE::Global::GetDicts()
- ->GetDefaultPubDict()->GetEntry(mGroup,mElement);
-
- if (entry)
- {
- mName = entry->GetName();
- CleanName(mName);
- GimmickDebugMessage(3,"='"<<mName<<"'"<<std::endl);
- }
- else
- {
- GimmickMessage(1,"!! WARNING : tag '"<<mKey
- <<"' is not in DICOM dictionnary ! "
- <<"Considering it as a user attribute"
- << std::endl);
- mName = "UNKNOWN";
- mGroup = mElement = 0;
- }
-#endif
-
-
-
-
-#if defined(USE_GDCM2)
- // Retrieve the name from gdcm dict
- const gdcm::Global& g = gdcm::Global::GetInstance();
- const gdcm::Dicts &dicts = g.GetDicts();
- const gdcm::Dict &dict = dicts.GetPublicDict();
- gdcm::DictEntry dictentry = dict.GetDictEntry(gdcm::Tag(mGroup, mElement));
-
- mName = dictentry.GetName();
- if(!mName.empty())
- {
- CleanName(mName);
- GimmickDebugMessage(3,"='"<<mName<<"'"<<std::endl);
- }
- else
- {
- GimmickMessage(1,"!! WARNING : tag '"<<mKey
- <<"' is not in DICOM dictionnary ! "
- <<"Considering it as a user attribute"
- << std::endl);
- mName = "UNKNOWN";
- mGroup = mElement = 0;
- }
-#endif
-
- }
- //=====================================================================
-
-
- //=====================================================================
- /// Extracts group and element from a key of the form "Dgroup_elem"
- void AttributeDescriptor::GetDicomGroupElementFromKey(const std::string& key,
- unsigned short& group,
- unsigned short& elem)
- {
- group = elem = 0;
- if ( (key.size()==10) &&
- (key[0] == 'D') &&
- (key[5] == '_') )
- {
- sscanf(key.c_str(),"D%04hx_%04hx ",&group,&elem);
- GimmickDebugMessage(3,"GetDicomGroupElementFromKey '"<<key<<"' : " <<group<<"|"<<elem<<std::endl);
- }
- else
- {
- GimmickMessage(5,"GetDicomGroupElementFromKey '"<<key<<"' : "
- <<" not a DICOM key format"<<std::endl);
- }
- return;
- }
-
- //=====================================================================
- /// test if the type is a date
- bool AttributeDescriptor::isDateEntry() const
- {
-
- bool btest = false;
- // Retrieve the name from gdcm dict
-#if defined(USE_GDCM)
- GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GetGroup(),GetElement());
- if( entry != 0)
- {
- if( entry->GetVR().str() == "DA" )
- {
- btest = true;
- }
- }
-#endif
-#if defined(USE_GDCM2)
- const gdcm::Global& g = gdcm::Global::GetInstance();
- const gdcm::Dicts &dicts = g.GetDicts();
- const gdcm::Dict &dict = dicts.GetPublicDict();
- if(mGroup != 0 && mElement != 0)
- {
- gdcm::DictEntry dictentry = dict.GetDictEntry(gdcm::Tag(GetGroup(), GetElement()));
- if( gdcm::VR::GetVRString(dictentry.GetVR()) == "DA")
- {
- btest = true;
- }
- }
-#endif
- return btest;
- }
-
- //=====================================================================
- /// test if the type is a time
- bool AttributeDescriptor::isTimeEntry() const
- {
-
- bool btest = false;
-#if defined(USE_GDCM)
- // Retrieve the name from gdcm dict
- GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GetGroup(),GetElement());
- if( entry != 0)
- {
- if( entry->GetVR().str() == "TM" )
- {
- btest = true;
- }
- }
-#endif
-
-#if defined(USE_GDCM2)
- const gdcm::Global& g = gdcm::Global::GetInstance(); // sum of all knowledge !
- const gdcm::Dicts &dicts = g.GetDicts();
- const gdcm::Dict &dict = dicts.GetPublicDict(); // Part 6
- if(mGroup != 0 && mElement != 0)
- {
- gdcm::DictEntry dictentry = dict.GetDictEntry(gdcm::Tag(mGroup, mElement));
- if(gdcm::VR::GetVRString(dictentry.GetVR()) == "TM")
- {
- btest = true;
- }
- }
-#endif
-
- return btest;
- }
-
-
- //=====================================================================
- /// Decodes the type of the attribute
- void AttributeDescriptor::DecodeType(unsigned int& typ) const
- {
- std::string type="";
-#if defined(USE_GDCM)
- // Retrieve the name from gdcm dict
- GDCM_NAME_SPACE::DictEntry* entry =
- GDCM_NAME_SPACE::Global::GetDicts()
- ->GetDefaultPubDict()->GetEntry(GetGroup(),GetElement());
-
- if (entry==0)
- {
- typ = 2;
- return;
- }
- type = entry->GetVR().str();
-#endif
-#if defined(USE_GDCM2)
- const gdcm::Global& g = gdcm::Global::GetInstance(); // sum of all knowledge !
- const gdcm::Dicts &dicts = g.GetDicts();
- const gdcm::Dict &dict = dicts.GetPublicDict(); // Part 6
- gdcm::DictEntry dictentry = dict.GetDictEntry(gdcm::Tag(mGroup, mElement));
- type = gdcm::VR::GetVRString(dictentry.GetVR());
-#endif
-
- GimmickDebugMessage(3,"VR Value is "<<type<<"!"<<std::endl);
- if(type=="AS" ||
- type=="DA" ||
- type=="FL" ||
- type=="FD" ||
- type=="IS" ||
- type=="SL" ||
- type=="SS" ||
- type=="UI" ||
- type=="US" ||
- type=="SH")
- {
- // Numerical
- typ = 1;
- }
- else
- {
- // String
- typ = 2;
- }
-
- }
- //=====================================================================
-
- } // EO namespace tree
-
-} // EO namespace creaImageIO
+++ /dev/null
-#ifndef __creaImageIOTreeAttributeDescriptor_h_INCLUDED__
-#define __creaImageIOTreeAttributeDescriptor_h_INCLUDED__
-
-#include <string>
-//#include <iostream>
-
-namespace creaImageIO
-{
-
- namespace tree
- {
- /**
- * \ingroup Tree
- */
- //=====================================================================
- /// Descriptor of an attribute of a node of a Tree (name, dicom group/element)
- class AttributeDescriptor
- {
- public:
- /// Flags
- /// The attribute is hidden (not visible to user)
- static const unsigned int PRIVATE;
- /// The attribute enters in unique identifier constitution
- static const unsigned int IDENTIFIER;
- /// The attribute enters in label constitution (for printing)
- static const unsigned int LABEL;
- /// The attribute can be edited
- static const unsigned int EDITABLE;
-
- /// Types
- /// The attribute is of numeric type
- static const int NUMBER=1;
- /// The attribute is of string type
- static const int STRING=2;
- /// The attribute's type is unknown
- static const int UNKNOWN=0;
-
- /// Default ctor
- AttributeDescriptor()
- : mKey(""), mName(""), mGroup(0), mElement(0), mFlags(0)
- {
- }
- /// Ctor with all explicitely
- AttributeDescriptor(const std::string& key,
- const std::string& name,
- unsigned short group,
- unsigned short element,
- unsigned int flags)
- : mKey(key), mName(name), mGroup(group), mElement(element),
- mFlags(flags)
- {
- }
-
- // Ctor with key, name and flags
- AttributeDescriptor(const std::string& key,
- const std::string& name,
- unsigned int flags = 0);
- // Ctor with dicom group, elem and flags
- // The key is built as 'Dgroup_elem'
- // The user name is retreived from dicom dictionnary
- AttributeDescriptor(unsigned short group,
- unsigned short element,
- unsigned int flags = 0);
- /// Returns the key of the attribute
- const std::string& GetKey() const { return mKey; }
- /// Returns the name of the attribute
- const std::string& GetName() const { return mName; }
- /// Returns the DICOM group code of the attribute
- unsigned short GetGroup() const { return mGroup; }
- /// Returns the DICOM element code of the attribute
- unsigned short GetElement() const { return mElement; }
- /// Returns the flags of the attribute
- unsigned int GetFlags() const { return mFlags; }
-
- /// Extracts group and element from a key of the form "Dgroup_elem"
- static void GetDicomGroupElementFromKey(const std::string& key,
- unsigned short& group,
- unsigned short& elem);
- /// Cleans the name:
- /// Replace simple quote by double quotes
- /// Cut string at NULL chars
- void CleanName(std::string& str) const;
- ///Decodes the type of attribute into the existing ones
- void DecodeType(unsigned int& type) const;
-
- /// Determines if Attribute is a date
- bool isDateEntry() const;
-
- /// Determines if Attribute is a time
- bool isTimeEntry() const;
-
- private:
- std::string mKey;
- std::string mName;
- unsigned short mGroup;
- unsigned short mElement;
- unsigned int mFlags;
- };
- // EO class AttributeDescriptor
- //=====================================================================
-
-
-
- } // EO namespace tree
-
-} // EO namespace creaImageIO
-
-
-
-
-
-#endif // #ifndef __creaImageIOTreeAttributeDescriptor_h_INCLUDED__
+++ /dev/null
-#ifndef __creaImageIOTreeAttributeMapType_h_INCLUDED__
-#define __creaImageIOTreeAttributeMapType_h_INCLUDED__
-
-#include <map>
-#include <string>
-#include <iostream>
-
-namespace creaImageIO
-{
-
- /**
- * \ingroup Tree
- */
- namespace tree
- {
- typedef std::map<std::string,std::string> AttributeMapType;
-
-
-
-
- }
-
-}
-
-//=====================================================================
-inline std::ostream& operator<<(std::ostream& s,
- const creaImageIO::tree::AttributeMapType& d)
-{
- creaImageIO::tree::AttributeMapType::const_iterator i;
- for (i=d.begin();i!=d.end();++i)
- {
- s << "'" << i->first << "'='" << i->second << "'" << std::endl;
- }
- return s;
-}
-//=====================================================================
-
-
-#endif
+++ /dev/null
-#include <creaImageIOTreeComparators.h>
+++ /dev/null
-#ifndef __creaImageIOTreeNodeComparators_h_INCLUDED__
-#define __creaImageIOTreeNodeComparators_h_INCLUDED__
-
-#include <vector>
-#include <iostream>
-
-namespace creaImageIO
-{
-
- namespace tree
- {
-
-
- class Node;
-
-
- /**
- * \ingroup Tree
- */
- //=====================================================================
- /// Abstract definition of a comparator of Node
- struct Comparator
- {
- virtual ~Comparator() {}
- virtual bool operator() (Node* const & x, Node* const & y) = 0;
- };
- //=====================================================================
-
-
-
- //=====================================================================
- /// Abstract Comparator whose order can be reversed
- struct ComparatorWithOrder : public Comparator
- {
- ComparatorWithOrder(bool reverse_order = false)
- : mReverseOrder(reverse_order) {}
- virtual ~ComparatorWithOrder() {}
-
-
- virtual bool compare(Node* const &, Node* const &) = 0;
-
- virtual bool operator() (Node* const & x, Node* const & y)
- {
- if (mReverseOrder) return this->compare(y,x);
- return this->compare(x,y);
- };
-
- bool mReverseOrder;
- };
- //=====================================================================
-
-
-
- //=====================================================================
- /// A Comparator which stores a vector of Comparators and
- /// which performs lexicographical comparison
- class LexicographicalComparator : public Comparator
- {
- public:
- LexicographicalComparator(const std::string& name)
- : mName(name) {}
- ~LexicographicalComparator() {}
-
- const std::string& GetName() const { return mName; }
- void SetName(const std::string& s) { mName = s; }
- void Clear() { mComparator.clear(); }
- void DeleteComparators()
- {
- std::vector<Comparator*>::iterator i;
- for (i =mComparator.begin();
- i!=mComparator.end();
- ++i)
- {
- delete *i;
- }
- mComparator.clear();
- }
- void Add(Comparator* c) { mComparator.push_back(c); }
-
- bool operator() (Node* const & x, Node * const & y);
-
- private:
- std::string mName;
- std::vector<Comparator*> mComparator;
- };
- //=====================================================================
-
-
-
-
- //===================================================================
- /// Comparator which compares the values of a given Attribute of the Nodes which is decoded as an int value
- struct IntComparator :
- public ComparatorWithOrder
- {
- IntComparator(const std::string& key,
- bool reverse_order)
- :
- ComparatorWithOrder(reverse_order),
- mKey(key)
- {}
- virtual bool compare(Node* const & x, Node* const & y);
-
- private:
- std::string mKey;
- };
- //===================================================================
-
- //===================================================================
- /// Comparator which compares the values of a given Attribute of the Nodes which is decoded as an float value
- struct FloatComparator :
- public ComparatorWithOrder
- {
- FloatComparator(const std::string& key,
- bool reverse_order )
- :
- ComparatorWithOrder(reverse_order),
- mKey(key)
- {}
-
- virtual bool compare(Node* const & x, Node* const & y);
-
- private:
- std::string mKey;
- };
- //===================================================================
-
- //===================================================================
- /// Comparator which compares the values of a given Attribute of the Nodes which is decoded as a string value
- struct StringComparator :
- public ComparatorWithOrder
- {
- StringComparator(const std::string& key,
- bool reverse_order )
- :
- ComparatorWithOrder(reverse_order),
- mKey(key)
- {}
-
- virtual bool compare(Node* const & x, Node* const & y);
-
- private:
- std::string mKey;
- };
- //===================================================================
-
- //===================================================================
-#define INT_FIELD_COMP(NAME,FIELD) \
- struct Node##NAME##Comparator : \
- public IntComparator \
- { \
- Node##NAME##Comparator(bool o = false) : \
- IntComparator(FIELD,o) \
- {} \
- }
- //==================================================================
-
- //===================================================================
-#define FLOAT_FIELD_COMP(NAME,FIELD) \
- struct Node##NAME##Comparator : \
- public FloatComparator \
- { \
- Node##NAME##Comparator(bool o = false) : \
- FloatComparator(FIELD,o) \
- {} \
- }
- //===================================================================
-
- //===================================================================
-#define STRING_FIELD_COMP(NAME,FIELD) \
- struct Node##NAME##Comparator : \
- public StringComparator \
- { \
- Node##NAME##Comparator(bool o = false) : \
- StringComparator(FIELD,o) \
- {} \
- }
- //===================================================================
-
-
-
- //===================================================================
- // Patient comparators
- ///Compares the names of the patients
- STRING_FIELD_COMP(PatientName,"A0010_0010");
- ///Compares the sex of the patients
- STRING_FIELD_COMP(PatientSex, "A0010_0040");
- ///Compares the birthdays of the patients
- STRING_FIELD_COMP(PatientBirthday, "A0010_0030");
- //===================================================================
-
- //===================================================================
- // Study comparators
- ///Compares the dates of the studies
- STRING_FIELD_COMP(StudyDate,"A0008_0020");
- ///Compares the description of the studies
- STRING_FIELD_COMP(StudyDescription,"A0008_1030");
- //===================================================================
-
- //===================================================================
- // Series comparators
- ///Compares the modality of the series
- STRING_FIELD_COMP(Modality,"A0008_0060");
- ///Compares the description of the series
- STRING_FIELD_COMP(SeriesDescription,"A0008_103E");
- ///Compares the date of the series
- STRING_FIELD_COMP(SeriesDate,"A0008_0021");
- //===================================================================
-
- //===================================================================
- // Image comparators
- ///Compares the number of the images
- INT_FIELD_COMP(ImageNumber,"A0020_0013");
- ///Compares the location of the images
- FLOAT_FIELD_COMP(SliceLocation,"A0020_1041");
- ///Compares the filename of the images
- STRING_FIELD_COMP(FullFileName,"FullFileName");
- //===================================================================
- } // namespace tree
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIOComparators_h_INCLUDED__
+++ /dev/null
-#include <creaImageIOTreeDescriptor.h>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <creaImageIOSystem.h>
-#include <boost/filesystem.hpp>
-
-
-#include <fstream>
-
-
-namespace creaImageIO
-{
-
- namespace tree
- {
-
- //==================================================================
- /// The attribute is hidden (not visible to user)
- const unsigned int AttributeDescriptor::PRIVATE = 1;
- /// The attribute enters in unique identifier constitution
- const unsigned int AttributeDescriptor::IDENTIFIER = 2;
- /// The attribute can be edited
- const unsigned int AttributeDescriptor::EDITABLE = 3;
- /// the attribute describes the node
- const unsigned int AttributeDescriptor::LABEL = 4;
- //==================================================================
-
- //==================================================================
- Descriptor::Descriptor()
- {
- CreateLevel0Descriptor();
- }
- //==================================================================
-
- //==================================================================
- Descriptor::~Descriptor()
- {
- }
- //==================================================================
-
- //==================================================================
- void Descriptor::CreateLevel0Descriptor()
- {
- Add(LevelDescriptor("Root"));
- }
- //==================================================================
-
- //==================================================================
- /// Creates the default descriptor
- void Descriptor::CreateDefault()
- {
- // clears the existing one
- Clear();
-
- // Creates the level 0 descriptor
- CreateLevel0Descriptor();
- // Creates the attribute "Name"
- Add(AttributeDescriptor("Name","Name",
- AttributeDescriptor::LABEL),0);
-
- // Patient level
- Add(LevelDescriptor("Patient"));
- Add(AttributeDescriptor("NumberOfChildren","#Series",0),1); // Number of Series
- Add(AttributeDescriptor(0x0010,0x0010, // Patient name
- AttributeDescriptor::LABEL),1);
- Add(AttributeDescriptor(0x0010,0x0040),1); // Patient sex
- Add(AttributeDescriptor(0x0010,0x0030),1); // Patient birthday
- Add(AttributeDescriptor(0x0010,0x0020, // Patient ID
- AttributeDescriptor::IDENTIFIER),1);
-
- // Study-series level
- Add(LevelDescriptor("Series"));
- Add(AttributeDescriptor("NumberOfChildren","#Images",0),2); // Number of images
- Add(AttributeDescriptor(0x0008,0x0060, // Modality
- AttributeDescriptor::LABEL),2);
- Add(AttributeDescriptor(0x0008,0x1030),2); // Study Description
- Add(AttributeDescriptor(0x0008,0x103E),2); // Description
- Add(AttributeDescriptor(0x0008,0x0080),2); // Institution Name
- Add(AttributeDescriptor(0x0008,0x0081),2); // Institution Adress
- Add(AttributeDescriptor(0x0008,0x1010),2); // Station Name
- Add(AttributeDescriptor(0x0008,0x1048),2); // Physician of Record
- Add(AttributeDescriptor(0x0008,0x1050),2); // Performing Physician's Name
- Add(AttributeDescriptor(0x0018,0x1030),2); // Protocol Name
-
- Add(AttributeDescriptor(0x0020,0x0010),2); // Study ID
- Add(AttributeDescriptor(0x0008,0x0020),2); // Study Date
- Add(AttributeDescriptor(0x0008,0x0030),2); // Study Time
- Add(AttributeDescriptor(0x0008,0x0050),2); // Study Accession Number
- Add(AttributeDescriptor(0x0008,0x0005),2); // Specific character set
- Add(AttributeDescriptor(0x0008,0x0021),2); // Series Date
- Add(AttributeDescriptor(0x0008,0x0031),2); // Series time
-
- Add(AttributeDescriptor(0x0020,0x000D // Study Instance UID
- ),2);//AttributeDescriptor::IDENTIFIER),2);
- Add(AttributeDescriptor(0x0020,0x000E, // Series Instance UID
- AttributeDescriptor::IDENTIFIER),2);
- // |
- // AttributeDescriptor::LABEL),2);
-
-
- // Image level
- Add(LevelDescriptor("Image"));
-
- Add(AttributeDescriptor(0x0020,0x0013),3); // Image Number
-
- Add(AttributeDescriptor(0x0028,0x0010),3); // Rows
- Add(AttributeDescriptor(0x0028,0x0011),3); // Columns
- Add(AttributeDescriptor(0x0028,0x0012),3); // Planes
- Add(AttributeDescriptor(0x0028,0x0002),3); // Sample per pixels
- Add(AttributeDescriptor(0x0028,0x0008),3); // Number of Frames
- Add(AttributeDescriptor(0x0028,0x0004),3); // Photometric Interpretation
- Add(AttributeDescriptor(0x0028,0x0103),3); // Pixel Representation
-
- Add(AttributeDescriptor(0x0020,0x0032),3); // Image Position Patient
- Add(AttributeDescriptor(0x0020,0x0037),3); // Image Orientation Patient
- Add(AttributeDescriptor(0x0020,0x1041),3); // Slice Location
- Add(AttributeDescriptor(0x0028,0x0006),3); // Planar Configuration
-
- Add(AttributeDescriptor(0x0028,0x0030),3); // Pixel Spacing
- Add(AttributeDescriptor(0x0028,0x0100),3); // AlocatedBits
- Add(AttributeDescriptor(0x0028,0x0101),3); // StoredBits
-
- Add(AttributeDescriptor(0x0008,0x0008),3); // Image Type
- Add(AttributeDescriptor(0x0008,0x0023),3); // Content Date
- Add(AttributeDescriptor(0x0008,0x0033),3); // Content Time
-
- Add(AttributeDescriptor(0x0020,0x4000),3); // Image Comments
-
- Add(AttributeDescriptor(0x0004,0x1500, // File Name
- AttributeDescriptor::LABEL),3);
- Add(AttributeDescriptor(0x0028,0x1052),3); // Rescale Intercept
- Add(AttributeDescriptor(0x0028,0x1053),3); // Rescale Slope
-
- Add(AttributeDescriptor(0x0050,0x0004),3); // Calibration Image
-
- Add(AttributeDescriptor(0x0020,0x0052 // Frame Reference UID
- ),3);
- Add(AttributeDescriptor(0x0008,0x0016),3); // SOP Class UID
- Add(AttributeDescriptor("FullFileName", // Full file name
- "Full file name",
- AttributeDescriptor::IDENTIFIER),3);
-
- }
-
- //////////////////////////////////////////////////////////////
- // create a descriptor (name, attributes...) from a file) //
- // @param : file path //
- // return : - //
- //////////////////////////////////////////////////////////////
- void Descriptor::createDescriptorfromFile(const std::string &i_name)
- {
- Clear();
-
- // read file and put in buffer
- std::ifstream i_file(i_name.c_str());
- std::stringstream buffer;
- buffer << i_file.rdbuf();
- std::string line;
- bool bname;
- int ilevel = -1;
-
-
- while(std::getline(buffer, line))
- {
- if(line =="<level>")
- { //increment levels.
- ilevel++;
- bname = true;
- }
- else if(bname)
- {
- // For each level, a name to describe it
- Add(LevelDescriptor(line));
- bname = false;
- }
- else if(line.empty()) // to avoid end line
- {
- return;
- }
- else
- {
- // split line to find all tags
- std::vector<std::string> descriptors;
- std::string separator = " ";
- std::string::size_type last_pos = line.find_first_not_of(separator);
- //find first separator
- std::string::size_type pos = line.find_first_of(separator, last_pos);
- while(std::string::npos != pos || std::string::npos != last_pos)
- {
- descriptors.push_back(line.substr(last_pos, pos - last_pos));
- last_pos = line.find_first_not_of(separator, pos);
- pos = line.find_first_of(separator, last_pos);
- }
-
- // By default, the last tag is at zero and not recorded but if take in count
- unsigned int flag = 0;
- if(descriptors.size() == 4)
- {
- std::stringstream val;
- val << std::dec << descriptors[3];
- val>> flag;
- }
-
- // if Dicom tag, use "group" and "element" descriptor
- if(descriptors[0] == "D")
- { std::stringstream val, val2;
- unsigned short group;
- unsigned short element;
- val << std::dec << descriptors[1] ;
- val >> std::hex >> group;
- val2 << std::dec << descriptors[2];
- val2 >> std::hex >> element;
- Add(AttributeDescriptor( group,element,flag), ilevel);
- }
-
- else if(descriptors[0].find("#") != -1)
- {
- // commented line continue to next line
- }
- else
- { boost::algorithm::replace_all(descriptors[2],"_"," ");
- Add(AttributeDescriptor( descriptors[1].c_str(),descriptors[2].c_str(),flag), ilevel);
- }
- }
- }
- }
-
- //==================================================================
-
- //==================================================================
- /// Adds a LevelDescriptor at the end of the list
- void Descriptor::Add(const LevelDescriptor& d)
- {
- mLevelDescriptorList.push_back(d);
- }
- //==================================================================
-
- //==================================================================
- /// Adds an AttributeDescriptor to level l
- void Descriptor::Add(const AttributeDescriptor& d, int l)
- {
- mLevelDescriptorList[l].Add(d);
- // TO DO : update DicomTagToName and NameToDicomTag map
- }
- //==================================================================
-
- //==================================================================
- /// Clears the Descriptor
- void Descriptor::Clear()
- {
- mLevelDescriptorList.clear();
- }
-
- //==================================================================
-
- //==================================================================
- /// Builds the key to value map of all the attributes of the tree
- void Descriptor::BuildAttributeMap( std::map<std::string,std::string>& map ) const
- {
- map.clear();
- LevelDescriptorListType::const_iterator l;
- for (l = GetLevelDescriptorList().begin();
- l!= GetLevelDescriptorList().end();
- ++l)
- {
- LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = l->GetAttributeDescriptorList().begin();
- a!= l->GetAttributeDescriptorList().end();
- ++a)
- {
- map[a->GetKey()]="";
- }
- }
- }
- }
-}
+++ /dev/null
-#ifndef __creaImageIOTreeDescriptor_h_INCLUDED__
-#define __creaImageIOTreeDescriptor_h_INCLUDED__
-
-#include <creaImageIOTreeAttributeMapType.h>
-#include <creaImageIOTreeLevelDescriptor.h>
-
-
-namespace creaImageIO
-{
- using namespace std;
- namespace tree
- {
-
- /**
- * \ingroup Tree
- */
-
- ///Descriptor of the structure of a Tree (number of levels, descriptors of each level, ...).
- //Any Tree has at least one level (level 0) of name "Root"
-
- class Descriptor
- {
- public:
- /// Ctor : creates the mandatory level 0 descriptor called "Root"
- Descriptor();
- /// Destructor
- ~Descriptor();
-
- /// Loads from a xml description file
- void LoadXML(const std::string& filename);
- /// Creates the default descriptor
- void CreateDefault();
-
- /// Returns the number of levels of the tree
- unsigned int GetNumberOfLevels()
- { return mLevelDescriptorList.size(); }
-
- /// Returns the LevelDescriptor of a given level (const ref)
- const LevelDescriptor& GetLevelDescriptor(int level) const
- { return mLevelDescriptorList[level]; }
-
- /// Returns the AttributeDescriptorList of a given level (const ref)
- const LevelDescriptor::AttributeDescriptorListType&
- GetAttributeDescriptorList(int level) const
- { return mLevelDescriptorList[level].GetAttributeDescriptorList(); }
-
-
- /// Adds a LevelDescriptor at the end of the list
- void Add(const LevelDescriptor&);
-
- /// Adds an AttributeDescriptor to level l
- void Add(const AttributeDescriptor&, int l);
-
-
- /// Builds the key to value map of all the attributes of the tree
- void BuildAttributeMap( AttributeMapType& ) const;
-
- /// The type of LevelDescriptor container
- typedef std::vector<LevelDescriptor> LevelDescriptorListType;
-
- /// Returns the list of tree levels (const)
- const LevelDescriptorListType& GetLevelDescriptorList() const { return mLevelDescriptorList; }
-
- /// Clears the Descriptor
- void Clear();
-
- //Create Attribute Descriptors from a file
- void createDescriptorfromFile(const std::string &i_file);
-
- private:
- LevelDescriptorListType mLevelDescriptorList;
- /// Creates the mandatory level 0 descriptor called "Root"
- /// (assumes the list is empty)
- void CreateLevel0Descriptor();
-
- };
- // EO class Descriptor
- //=====================================================================
- } // EO namespace tree
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
+++ /dev/null
-#ifndef __creaImageIOTreeHandler_h_INCLUDED__
-#define __creaImageIOTreeHandler_h_INCLUDED__
-
-#include <creaImageIOTree.h>
-
-namespace creaImageIO
-{
-
-
- //=======================================================================
- //class TreeHandlerStatistics;
- //=======================================================================
- /**
- * \ingroup Model
- */
- //=======================================================================
-
- /// Abstract class which 'handles' a Tree structure
- class TreeHandler
- {
- public:
-
- //====================================================================
- // typedef TreeHandlerStatistics Statistics;
- //====================================================================
-
- //====================================================================
- /// Ctor
- TreeHandler() {}
- /// Virtual dtor
- virtual ~TreeHandler() {}
- //====================================================================
-
- //====================================================================
- /// Returns the Tree handled
- tree::Tree& GetTree() { return mTree; }
- /// Returns the Tree handled (const)
- const tree::Tree& GetTree() const { return mTree; }
- //====================================================================
-
- //====================================================================
- // QUERY METHODS
- /// Is the 'source' readable ?
- virtual bool IsReadable() { return false; }
- /// Is the 'source' writable ?
- virtual bool IsWritable() { return false; }
- //====================================================================
-
-
- //====================================================================
- // INITIALIZATION / FINALIZATION
- //====================================================================
-
- //====================================================================
- /// Opens an existing 'source'
- // Default mode is read only
- // If IsWritable and writable==true then opens in read/write mode
- virtual bool Open(bool writable = false) { return false; }
- /// Closes the 'source'
- virtual bool Close() { return false; }
- /// Creates a new 'source'
- // Default mode is read only
- // If IsWritable and writable==true then opens in read/write mode
- virtual bool Create(bool writable = false) { return false; }
- /// Destroys the 'source'
- virtual bool Destroy() { return false; }
- /// Begins a transaction
- virtual void BeginTransaction(){}
- ///Commits results and ends transaction
- virtual void EndTransaction(){}
- //====================================================================
-
-
- //====================================================================
- // READ METHODS
- //====================================================================
-
-
- //====================================================================
- /// Returns the number of children of the Node *WITHOUT LOADING THEM*
- // REM : The Tree itself is a Node and asking for its number of
- // children returns the number of children of level 1.
- virtual unsigned int GetNumberOfChildren(tree::Node* n) { return 0; }
- //====================================================================
-
- //====================================================================
- /// Returns the attribute requested. Useful for synchronization.
- virtual void GetAttribute(std::string levelDescriptor,
- std::string searchParam,
- std::string searchVal,
- std::string key,
- std::string& result){}
- //====================================================================
-
- //====================================================================
- /// Recursively loads the children of node 'parent' until maxlevel
- // is reached.
- // If maxlevel <= 0 then loads all the sub-tree rooted at parent
- // If parent == NULL or parent == tree then starts with the 'children' of
- // the tree itself.
- // Returns the total number of children loaded.
- virtual int LoadChildren(tree::Node* parent, int maxlevel)
- { return 0; }
- //====================================================================
-
- //====================================================================
- /// Unloads the Node and its descendants
- // WITHOUT altering the source, e.g. the database
- virtual void UnLoad(tree::Node* n) { return; }
- //====================================================================
-
- //====================================================================
- /// Returns the top level node id for the given search param and search value
- virtual void GetTopLevelNodeId(const std::string& searchParam,
- const std::string& searchValue,
- std::string& parent_id){ return; }
- ///====================================================================
-
-
- //====================================================================
- // WRITE METHODS : WORK ONLY IN WRITE MODE
- //====================================================================
- typedef tree::Node::AttributeMapType AttributeMapType;
- /// Adds a branch in the tree with the attributes provided
- // returns the Level in the tree where the branch was connected
- // (-1 for error, 0 for top level, etc. )
- // Of course the branch is loaded on exit
- virtual int AddBranch( const AttributeMapType& ) { return -1; }
- /// Removes the node and its descendants
- virtual bool Remove(tree::Node*) { return false; }
- /// Sets an attribute of a Node
- virtual bool SetAttribute(tree::Node*,
- const std::string& key,
- const std::string& value) { return false; }
- // Sets an attribute
- virtual void SetAttribute(const std::string& levelDescriptor,
- const std::string& key,
- const std::string& value,
- const std::string& searchParam,
- const std::string& searchVal){}
- //Deletes the tuple that matches the parameters given
- virtual void DeleteTuple(std::string levelDescriptor, std::string key, std::string value){}
- //Deletes the entries that match the parameters given
- virtual void RemoveEntries(const std::string i_table,
- const std::string i_attribute,
- const std::string i_operand,
- const std::string i_val){}
-
- //====================================================================
-
-
- private:
- /// The handled tree
- tree::Tree mTree;
-
- };
- // EO class TreeHandler
- //=======================================================================
- /*
- //=======================================================================
- /// Memorizes statistics on operations done by a tree handler
- // (nodes created, removed, ...)
- class TreeHandlerStatistics
- {
- public:
- //====================================================================
- /// Ctor
- TreeHandler(TreeHandler* tree) : mTreeHandler(tree) { Reset(); }
- /// Dtor
- ~TreeHandler() {}
- /// Resets the stats
- void Reset();
- /// Prints the stats
- void Print();
-
- ///
- void CreateNode(int level) { mNumberCreatedNode[level]++; }
- void DeleteNode(int level) { mNumberDeletedNode[level]++; }
-
- protected:
- TreeHandler* mTreeHandler;
- std::vector<int> mNumberCreatedNode;
- std::vector<int> mNumberDeletedNode;
-
-
- ///====================================================================
- };
- // EO class TreeHandlerStatistics
- //=======================================================================
- */
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOTreeHandlerImageAdder.h>
-#include <creaImageIOSystem.h>
-#include "boost/filesystem.hpp"
-#include <boost/filesystem/operations.hpp>
-#include <boost/utility.hpp>
-
-
-namespace fs = boost::filesystem;
-using boost::filesystem::path;
-using boost::next;
-using boost::prior;
-
-
-using namespace crea;
-
-namespace creaImageIO
-{
- //====================================================================
- // Ctor
- TreeHandlerImageAdder::TreeHandlerImageAdder(TreeHandler* tree)
- : mTreeHandler(tree)
- {
- }
- // Dtor
- TreeHandlerImageAdder::~TreeHandlerImageAdder()
- {
- }
- //====================================================================
-
- //====================================================================
- void TreeHandlerImageAdder::ConnectProgressObserver(ProgressCallbackType callback)
- {
- mProgressSignal.connect(callback);
- }
- //====================================================================
-
- //=====================================================================
- bool TreeHandlerImageAdder::IsHandledFile( const std::string& filename)
- {
- return (mReader.CanRead(filename));
- }
- //=====================================================================
-
- //=====================================================================
- void TreeHandlerImageAdder::AddFiles( const std::vector<std::string>& filenames)
- {
- mProgress.Reset();
-
- unsigned int nbf = filenames.size();
- std::vector<std::string>::const_iterator i;
- mSynchronizer->GetList(mCurrentDB);
- for (i=filenames.begin();i!=filenames.end();++i)
- {
-
- mProgress.IncNumberScannedFiles();
- if (IsHandledFile(*i))
- {
- mProgress.IncNumberHandledFiles();
- if(mSynchronizer->isIndexed(*i))
- {
- mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
- std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
- std::stringstream removedOn;
- removedOn<<time(0);
- mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
- AddFile(*i);
- }
- }
- mProgressSignal(mProgress);
- if (mProgress.GetStop()) break;
- }
- }
- //=====================================================================
-
- //=====================================================================
- void TreeHandlerImageAdder::AddDirectory( const std::string& directory,
- bool recurse)
- {
- mProgress.Reset();
- std::stringstream files;
-
- std::stringstream rec;
- rec<<recurse;
- mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
- std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
- mTreeHandler->BeginTransaction();
- mSynchronizer->GetList(mCurrentDB);
- AddDirectoryRecursor( directory, recurse, addKey );
-
- int nFiles=GetProgress().GetNumberAddedFiles();
- files<<nFiles;
- mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
- mTreeHandler->EndTransaction();
- GimmickDebugMessage(3,mProgress<<std::endl);
- }
-
- //=====================================================================
- void TreeHandlerImageAdder::AddFile( const std::string& filename )
- {
- GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
- std::map< std::string, std::string> attr;
- mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
-
-
- mReader.ReadAttributes(filename,attr);
- //// TO DO Create a function to test if the SOP Instance ID (0008,0018) is not already on DB
- //// test befor if this attr is present on DB if not don't perform the test!!!
- //bool bSOPIID = false;
- //std::map<std::string, std::string>::iterator it_att = attr.begin();
- //for(; it_att != attr.end(); it_att++)
- //{
- // if (it_att->first == "D0008_0018")
- // {
- // bSOPIID = mTreeHandler->TestSOPIID(it_attr->second);
- // break;
- // }
- //}
- //if(bSOPIID)
- // return;
-
- int lev = mTreeHandler->AddBranch(attr);
-
- // update the progress according to lev
- if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
- mProgress.IncNumberAddedFiles();
- }
- //=====================================================================
-
- void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
- {
- int n=node->GetNumberOfChildren();
- if(n>0)
- {
- RemoveFiles(node->GetChildrenList());
- }
- else
- {
- std::string path=node->GetAttribute("FullFileName");
- //Gets the add key
- std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
- //Gets the number of files added
- int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
- files=files-1;
- std::stringstream out;
- out<<files;
- //Sets the new number of files
- mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
- //Sets the file as removed
- mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
- }
- }
-
- //=====================================================================
-
- void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
- {
- std::vector<tree::Node*>::const_iterator it;
- for(it=nodes.begin();it!=nodes.end();++it)
- {
- int n=(*it)->GetNumberOfChildren();
- if(n>0)
- {
- RemoveFiles((*it)->GetChildrenList());
- }
- else
- {
- std::string path=(*it)->GetAttribute("FullFileName");
- //Gets the add key
- std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
- //Gets the number of files added
- int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
- files=files-1;
- std::stringstream out;
- out<<files;
- //Sets the new number of files
- mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
- //Sets the file as removed
- mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
- }
-
- }
- }
-
-
- //=====================================================================
- void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
- bool recursive,
- const std::string &addKey)
- {
- GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
- mProgress.IncNumberScannedDirs();
-
- if ( !fs::exists( dirpath ) ) return;
- time_t lastModif=fs::last_write_time(dirpath);
-
-
- fs::directory_iterator end_itr; // default construction yields past-the-end
- for ( fs::directory_iterator itr( dirpath );
- itr != end_itr;
- ++itr )
- {
- // If is directory & recurse : do recurse
- if ( fs::is_directory(itr->status()) )
- {
- if (recursive)
- {
- AddDirectoryRecursor( itr->string(), recursive, addKey);
- }
- }
- else
- {
- std::string parent_id;
- // tTest if directory (and only it) exists or not.
- bool valid = mSynchronizer->isIndexed(itr->string());//true;//=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
- if(valid)
- {
- mProgress.IncNumberScannedFiles();
- if (IsHandledFile(itr->string()))
- {
- mProgress.IncNumberHandledFiles();
- AddFile( itr->string() );
- mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
- std::stringstream removedOn;
- removedOn<<time(0);
- mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
- }
-
- mProgressSignal(mProgress);
- if (mProgress.GetStop())
- {
- //itr = end_itr;
- break;
- }
-
- }
- }
- }
-
- }
- //=======================================================================
-
- //=======================================================================
-
- void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
- bool recursive,
- bool repair,
- bool checkAttributes,
- std::vector<std::string> &i_ignorefiles,
- std::vector<std::string> & attsModified,
- std::vector<std::string> & newfiles)
- {
- if ( !fs::exists( dirpath ) ) return;
- fs::directory_iterator end_itr; // default construction yields past-the-end
-
- for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
- {
- // If is directory & recurse : do recurse
- if ( fs::is_directory(itr->status()) )
- {
- if (recursive)
- {
- CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
- }
- }
- else
- {
- if (IsHandledFile(itr->string()))
- {
- bool bfound = false;
- for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
- {
- if((*it_new) == itr->string())
- {
- bfound = true;
- //Additional checking of attributes
- if(checkAttributes)
- {
- CheckAttributes(repair,(*it_new),attsModified);
- }
- i_ignorefiles.erase(it_new);
- break;
- }
- }
- if(!bfound && i_ignorefiles.size()>0 )
- {
- newfiles.push_back( itr->string() );
- }
- }
- }
- }
- }
-
- //=======================================================================
-
- //=======================================================================
-
- std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
- {
- std::vector<AddList> fileList;
- std::vector<std::string> ignoreList;
- std::vector<std::string> newFiles;
- std::vector<std::string> attsModified;
- std::stringstream mess;
- std::vector<AddList>::iterator iter;
-
- //Gets the list of added files
- mSynchronizer->GetFileList(fileList,mCurrentDB);
-
- std::vector<std::string>::iterator i;
- //Actions to take if the user doesn't want to repair
- if(!repair)
- {
- //Iterates to see if they are in sync
- for(iter=fileList.begin();iter!=fileList.end();++iter)
- {
- mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
- bool rec=true;
- if((*iter).recursive=="0"){rec=false;}
- CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
- }
-
- //Add to message the result of new found files
- mess<<"New Files Found: "<<newFiles.size()<<std::endl;
- if(newFiles.size()>0)
- {
- mess<<"Filenames: "<<std::endl;
- for(i=newFiles.begin();i!=newFiles.end();++i)
- {
- mess<<*i<<std::endl;
- }
- }
-
- //Add to message the result of missing files
- mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
- if(ignoreList.size()>0)
- {
- mess<<"Filenames: "<<std::endl;
- for(i=ignoreList.begin();i!=ignoreList.end();++i)
- {
- mess<<*i<<std::endl;
- }
- }
-
- //In the case that the user wants to check the attributes...
- if(checkAttributes)
- {
- //... add to message the result of files that have been changed.
- mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
- if(attsModified.size()>0)
- {
- mess<<"Filenames: "<<std::endl;
- for(i=attsModified.begin();i!=attsModified.end();++i)
- {
- mess<<*i<<std::endl;
- }
- }
- }
-
- }
-
- //Actions to take if the user wants to repair
- else
- {
- int nf=0;
- //Iterates to see if they are in sync
- for(iter=fileList.begin();iter!=fileList.end();++iter)
- {
- mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
- bool rec=true;
- if((*iter).recursive=="0"){rec=false;}
- CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
-
- //For the new files, add them
- for (i=newFiles.begin();i!=newFiles.end();++i)
- {
- if (IsHandledFile(*i))
- {
- std::stringstream removedOn;
- removedOn<<time(0);
- mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
- //Gets the number of files added
- int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
- files=files+1;
- std::stringstream out;
- out<<files;
- //Sets the new number of files
- mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
- AddFile(*i);
- }
- }
- nf+=newFiles.size();
- newFiles.clear();
-
- }
- //Reports number of added files
- mess<<"Files Added: "<<nf<<std::endl;
-
- //Removes the necessary files and reports the results
- if(ignoreList.size()>0)
- {
- tree::Node* node;
- mTreeHandler->LoadChildren(NULL,4);
- for(i=ignoreList.begin();i!=ignoreList.end();++i)
- {
- FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
- RemoveFile(node);
- mTreeHandler->Remove(node);
- }
- }
- mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
- //In the case that the user wants to check the attributes...
- if(checkAttributes)
- {
- //... add to message the result of files that were modified.
- mess<<"Files Modified: "<<attsModified.size()<<std::endl;
- }
- }
- return mess.str();
-
- }
- //=======================================================================
-
- void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
- {
- std::map< std::string, std::string> attr;
- mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
- mReader.ReadAttributes(file,attr);
- tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
- tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = adl.begin();a!=adl.end();++a)
- {
- std::string databaseVal;
- mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
- std::string fileVal=attr.find(a->GetKey())->second;
- if ( a->GetFlags()==0 && databaseVal == fileVal)
- {
- if(repair)
- {
- mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
- }
- attsModified.push_back(file);
- }
-
- }
-
- }
-
- //=======================================================================
-
-
- void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
- {
- if(level>1)
- {
- std::vector<tree::Node*>::iterator iter;
- for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
- {
- FindNode(*iter,level-1,searchParam,searchVal,node);
- }
- }
- else
- {
- if(parent->GetAttribute(searchParam).compare(searchVal)==0)
- {
- node=parent;
- }
-
- }
- }
-
- void TreeHandlerImageAdder::SaveAs(const std::vector<std::string>& filenames, std::vector<vtkImageData *> i_images)
- {
- std::vector<std::string>::const_iterator it_file = filenames.begin();
- std::vector<vtkImageData *>::iterator it_image = i_images.begin();
- /* mWriter.CanWrite(".jpeg");
- for(; it_file != filenames.end(); ++it_file, ++it_image)
- mWriter.WriteImage(it_file->c_str(), (vtkImageData &)it_image);*/
- }
-
- //=======================================================================
- void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
- {
- if(level>1)
- {
- std::vector<tree::Node*>::iterator iter;
- for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
- {
- FindNodePartial(*iter,level-1,searchParam,searchVal,node);
- }
- }
- else
- {
- if(parent->GetAttribute(searchParam).find(searchVal)<9000)
- {
- node=parent;
- return;
- }
-
- }
- }
-
- //=======================================================================
-
- void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
- {
- std::vector<std::string>::const_iterator i;
- if(!boost::filesystem::exists(directory))
- {
- boost::filesystem::create_directory(boost::filesystem::path(directory));
- mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
- }
- std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
- size_t last;
- std::vector<std::string> newNames;
- for(i=filenames.begin();i!=filenames.end();++i)
- {
- std::string dir=directory.c_str();
- if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
- {
- std::string path=*i;
- last=(*i).find_last_of('/');
- std::string f="\\"+(*i).substr(last+1);
-
- int p=1;
- std::stringstream out;
- out<<directory<<f;
- while(boost::filesystem::exists(out.str()))
- {
- out.str("");
- out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
- p++;
- }
- std::string result=out.str();
- boost::filesystem::copy_file((*i),result);
-
- //To update image database
- mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
-
- //To update maintenance database
- //1.Add the new path and increase number of children on new operation.
- std::stringstream removedOn;
- removedOn<<time(0);
- //Inserts the file
- mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
- //Gets the number of files added
- int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
- files=files+1;
- std::stringstream fil;
- fil<<files;
- //Sets the new number of files
- mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
- fil.str("");
-
- //2.Set the old path as removed and decrease number of children on old operation.
- //Gets the old add key
- std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
- //Sets the file as removed
- mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
- //Gets the number of files added
- files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
- files=files-1;
- fil<<files;
- //Sets the new number of files
- mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
-
- }
-
- }
- }
-
- //=======================================================================
-
- void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
- {
- //Delete from local database and others
- tree::Node* node=0;
- mTreeHandler->LoadChildren(NULL,4);
- FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
- while(node!=0)
- {
- mTreeHandler->Remove(node);
- node=0;
- mTreeHandler->LoadChildren(NULL,4);
- FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
- }
- }
-
- //=======================================================================
-
- void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
- {
- //Delete from maintenance
- mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
- mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
- }
-
- //=======================================================================
- void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
- {
- node->SetAttribute(key,val);
- mTreeHandler->SetAttribute(node,key,val);
- }
-
- //=======================================================================
- void TreeHandlerImageAdder::GetAttributes(const std::vector<std::string>& params,
- const std::string& filename,
- std::vector<std::string>& results)
- {
- std::vector<std::string>::const_iterator i;
- std::string result;
- for(i=params.begin();i!=params.end();i++)
- {
- mTreeHandler->GetAttribute("Image","FullFileName",filename,*i,result);
- results.push_back(result);
- }
- }
-
-
-}
+++ /dev/null
-#ifndef __creaImageIOTreeHandlerImageAdder_h_INCLUDED__
-#define __creaImageIOTreeHandlerImageAdder_h_INCLUDED__
-
-#include <creaImageIOTreeHandler.h>
-#include <creaImageIOSynchron.h>
-#include <creaImageIOImageReader.h>
-//#include <creaImageIOImageWriter.h>
-
-// Signal/slot mechanism for progress events
-#include <boost/signal.hpp>
-#include <boost/bind.hpp>
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup Model
- */
-
- //=======================================================================
- /// Object which can add images files to a TreeHandler. Is able to parse (recursively) a part of a filesystem to look for known images and load their attributes in order to add the images to a Tree (submission via a TreeHandler::AddBranch)
-
- class TreeHandlerImageAdder
- {
-
- public:
- //====================================================================
- /// Ctor
- TreeHandlerImageAdder(TreeHandler* tree);
- /// Dtor
- ~TreeHandlerImageAdder();
- /// Sets the TreeHandler
- void SetTreeHandler(TreeHandler* tree) { mTreeHandler = tree;}
-
- /// Sets the synchronizer
- void SetSynchronizer(Synchronizer* s){mSynchronizer=s;}
- /// Sets the synchronizer
- void SetCurrentDatabase(std::string cur){mCurrentDB=cur;}
- //====================================================================
-
- //====================================================================
- /// Structure which holds progress information
- /// To stop the image adder use SetStop()
- class Progress
- {
- public:
- Progress() { Reset(); }
- ~Progress() {}
-
- void Reset()
- {
- mStop = false;
- mNumberScannedFiles = 0;
- mNumberScannedDirs = 0;
- mNumberHandledFiles = 0;
- mNumberAddedFiles = 0;
- }
-
- int GetNumberScannedFiles() const { return mNumberScannedFiles; }
- int GetNumberScannedDirs() const { return mNumberScannedDirs; }
- int GetNumberHandledFiles() const { return mNumberHandledFiles; }
- int GetNumberAddedFiles() const { return mNumberAddedFiles; }
-
- void IncNumberScannedFiles() { mNumberScannedFiles++; }
- void IncNumberScannedDirs() { mNumberScannedDirs++; }
- void IncNumberHandledFiles() { mNumberHandledFiles++; }
- void IncNumberAddedFiles() { mNumberAddedFiles++; }
-
- void SetStop() { mStop = true; }
- bool GetStop() const { return mStop; }
-
- private:
- bool mStop;
- int mNumberScannedFiles;
- int mNumberScannedDirs;
- int mNumberHandledFiles;
- int mNumberAddedFiles;
- };
- //=============================================
-
- //=============================================
- const Progress& GetProgress() const { return mProgress; }
- //=============================================
-
- //=============================================
- typedef boost::signal<void (Progress&)> ProgressSignalType;
- typedef ProgressSignalType::slot_function_type ProgressCallbackType;
- //=============================================
-
- //==================================================================
- /// Adds the function f to the list of functions to call
- /// when the addition progresses.
- /// f is of type ProgressCallbackType which is:
- /// void (*ProgressCallbackType)(Progress&)
- /// To pass a member function 'f' of an instance 'c' of a class 'C'
- /// as callback you have to 'bind' it, i.e. call:
- /// ConnectProgressObserver ( boost::bind( &C::f , c, _1 ) );
- void ConnectProgressObserver(ProgressCallbackType callback);
- //==================================================================
-
- //====================================================================
- /// Returns if the file can be read or not
- bool IsHandledFile( const std::string& filename);
- /// Adds a list of files to the TreeHandler
- void AddFiles( const std::vector<std::string>& filename );
- /// (Recursively) adds the files of a directory to the TreeHandler
- void AddDirectory( const std::string& directory,
- bool recurse);
- /// Removes a file from the databases
- void RemoveFile(tree::Node* node);
- /// Removes files from the databases
- void RemoveFiles(const std::vector<tree::Node*>& nodes);
- /// Synchronizes the DB and disk by repeating the operations the user has done and returns a report
- std::string Synchronize(bool repair, bool checkAttributes);
- ///Recursively checks if the directory is synchronized and optionally the state of the attributes
- void CheckSyncDirectory(const std::string &dirpath,
- bool recursive,
- bool repair,
- bool checkAttributes,
- std::vector<std::string> &i_ignorefiles,
- std::vector<std::string> & attsModified,
- std::vector<std::string> & newfiles);
- ///Copies the files indicated in the vector and updates all databases
- void CopyFiles(const std::vector<std::string>& filenames, const std::string directory );
-
- ///Saves as the files indicated in the vector in a specific directory
- void SaveAs(const std::vector<std::string>& filenames, std::vector<vtkImageData *> i_images);
- ///Finds the node that matches the specified parameters
- void FindNode(tree::Node* parent, int level,
- const std::string& searchParam,
- const std::string& searchVal,
- tree::Node*& node);
-
- ///Finds the nodes that partially match the searchVal
- void FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node);
-
- ///Checks the attributes of the database against the ones in disk
- void CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified);
- ///Deletes the drive with the given name (use for all databases except maintenance and timestamp)
- void DeleteDriveFromMainDB(const std::string& drive);
- ///Deletes the drive with the given name (use for maintenance and timestamp databases)
- void DeleteDriveFromOtherDB(const std::string& drive);
- ///Edits the given field and sets the new parameters
- void EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val);
- ///Returns the demanded attributes for the given file
- void GetAttributes(const std::vector<std::string>& params,
- const std::string& filename,
- std::vector<std::string>& results);
-
-
-
-
- //====================================================================
-
- private:
-
- /// Adds a single file to the TreeHandler
- /// **WITHOUT** testing wether it is handled or not
- /// hence you have to call IsHandledFile before using AddFile!
- void AddFile( const std::string& filename );
-
- /// Recursive method which does the main job for AddDirectory
- void AddDirectoryRecursor( const std::string& directory,
- bool recurse,
- const std::string &addKey);
-
- TreeHandler* mTreeHandler;
- Synchronizer* mSynchronizer;
- ImageReader mReader;
- //ImageWriter mWriter;
- std::string mCurrentDB;
-
- Progress mProgress;
- ProgressSignalType mProgressSignal;
-
-
- };
- // EO class TreeHandlerImageAdder
- //=======================================================================
-
-
-
-
-
-} // EO namespace creaImageIO
-
-#include <iostream>
-inline std::ostream& operator << ( std::ostream& o,
- const creaImageIO::TreeHandlerImageAdder::Progress& p)
-{
- o << p.GetNumberScannedFiles() << " files - "
- << p.GetNumberScannedDirs() << " dirs - "
- << p.GetNumberHandledFiles() << " handled -"
- << p.GetNumberAddedFiles() << " added";
- return o;
-}
-
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOTreeLevelDescriptor.h>
-#include <creaImageIOSystem.h>
-
-
-namespace creaImageIO
-{
- namespace tree
- {
- /// Adds the AttributeDescriptor to the list
- void LevelDescriptor::Add(const AttributeDescriptor& a)
- {
- GimmickMessage(5,"Adding Attribute Descriptor '"<<a.GetKey()
- <<"' to LevelDescriptor"
- <<std::endl);
- mAttributeDescriptorList.push_back(a);
- if ( a.GetFlags() & AttributeDescriptor::IDENTIFIER )
- {
- GimmickMessage(6,"Is an IDENTIFIER"<<std::endl);
- mIdentifierList.push_back(a.GetKey());
- }
- if ( a.GetFlags() & AttributeDescriptor::LABEL )
- {
- GimmickMessage(6,"Is a LABEL"<<std::endl);
- mLabelList.push_back(a.GetKey());
- }
- }
-
-
-
- }
-}
-
+++ /dev/null
-#ifndef __creaImageIOTreeLevelDescriptor_h_INCLUDED__
-#define __creaImageIOTreeLevelDescriptor_h_INCLUDED__
-
-#include <creaImageIOTreeAttributeDescriptor.h>
-#include <vector>
-
-namespace creaImageIO
-{
-
- namespace tree
- {
- /**
- * \ingroup Tree
- */
- //=====================================================================
- /// Descriptor of a level of a Tree (name, attributes, ...)
- class LevelDescriptor
- {
- public:
- /// Ctor with name
- LevelDescriptor(const std::string& name) : mName(name) {}
- /// Destructor
- ~LevelDescriptor() {}
-
- /// Returns the name of the level
- const std::string& GetName() const { return mName; }
-
- /// Returns the number of attributes of the level
- unsigned int GetNumberOfAttributes() const
- { return mAttributeDescriptorList.size(); }
-
- /// Adds the AttributeDescriptor to the list
- void Add(const AttributeDescriptor&);
-
- /// The type of attribute container
- typedef std::vector<AttributeDescriptor> AttributeDescriptorListType;
-
- /// Returns the list of AttributeDescriptor (const)
- const AttributeDescriptorListType& GetAttributeDescriptorList() const
- { return mAttributeDescriptorList; }
-
- /// \return The list of attributes with flag IDENTIFIER set
- const std::vector<std::string>& GetIdentifierList() const
- { return mIdentifierList; }
- /// \return The list of attributes with flag LABEL set
- const std::vector<std::string>& GetLabelList() const
- { return mLabelList; }
-
- private:
- std::string mName;
- AttributeDescriptorListType mAttributeDescriptorList;
- /// The list of attributes with flag IDENTIFIER set
- std::vector<std::string> mIdentifierList;
- /// The list of attributes with flag LABEL set
- std::vector<std::string> mLabelList;
-
- };
- // EO class LevelDescriptor
- //=====================================================================
- }// EO namespace tree
-
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOTreeNode.h>
-#include <creaImageIOTree.h>
-#include <creaImageIOSystem.h>
-#include <algorithm>
-#include <creaImageIOGimmick.h>
-
-namespace creaImageIO
-{
- namespace tree
- {
-
- //=============================================================
- /// Ctor with parent
- Node::Node(Node* parent)
- : mParent(parent),//mData(0),
- mChildrenLoaded(false)
- {
- mData.reset();
- if (parent)
- {
- GimmickDebugMessage(6,"Default Node constructor (level "<<GetLevel()<<")"
- << std::endl);
- // Insert into parent's children list
- InitializeAttributeMap();
- parent->GetChildrenList().push_back(this);
- }
- else
- {
- GimmickDebugMessage(6,"Default Node constructor without parent"
- << std::endl);
- }
- }
- //=============================================================
-
- //=============================================================
- /// Ctor with parent and attributes map
- Node::Node(Node* parent, const AttributeMapType& attr)
- : mParent(parent),//mData(0),
- mChildrenLoaded(false)
- {
- mData.reset();
- GimmickDebugMessage(6,"Node constructor (level "<<GetLevel()<<")"
- << std::endl);
-
- if (parent)
- {
- // Insert into parent's children list
- parent->GetChildrenList().push_back(this);
- // Initialize attributes
- LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = GetTree()->GetAttributeDescriptorList(GetLevel()).begin();
- a!= GetTree()->GetAttributeDescriptorList(GetLevel()).end();
- ++a)
- {
- std::string v;
- AttributeMapType::const_iterator i = attr.find(a->GetKey());
- if ( i != attr.end() )
- {
- v = i->second;
- }
- GimmickDebugMessage(6,"Setting attribute '"<<a->GetName()<<"' = '"
- <<v<<"'"<<std::endl);
- UnsafeSetAttribute( a->GetKey(), v );
- }
- }
-
- }
- //=============================================================
-
-
- //=============================================================
- Node::~Node()
- {
- GimmickDebugMessage(6,"Node destructor"
- << std::endl);
- ChildrenListType::iterator i;
- for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
- {
- delete *i;
- }
- mData.reset();
- }
- //=============================================================
-
-
- //=============================================================
- /// Initializes the attribute map i.e. creates the entries
- void Node::InitializeAttributeMap()
- {
- // Initialize attributes
- LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = GetTree()->GetAttributeDescriptorList(GetLevel()).begin();
- a!= GetTree()->GetAttributeDescriptorList(GetLevel()).end();
- ++a)
- {
- UnsafeSetAttribute( a->GetKey(), "" );
- }
- }
- //=============================================================
-
- //=============================================================
- /// Returns the level descriptor of the node
- const LevelDescriptor& Node::GetLevelDescriptor() const
- {
- return GetTree()->GetLevelDescriptor(GetLevel());
- }
-
- //=============================================================
-
- //=============================================================
- /// Returns the attribute descriptor of the passed parameter
- const AttributeDescriptor& Node::GetAttributeDescriptor(const std::string& k)const
- {
- LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = GetTree()->GetAttributeDescriptorList(GetLevel()).begin();
- a!= GetTree()->GetAttributeDescriptorList(GetLevel()).end();
- ++a)
- {
-
- if(a->GetKey()==k)
- {
- return *a;
- }
-
- }
- return *a;
- }
- //=============================================================
-
- //=============================================================
- int Node::RemoveChildrenFromList(Node* node)
- {
- ChildrenListType::iterator i = find(GetChildrenList().begin(),
- GetChildrenList().end(),
- node);
- if (i != GetChildrenList().end())
- {
- GetChildrenList().erase(i);
- }
- return GetChildrenList().size();
- }
- //=============================================================
-
- //=============================================================
- const std::string& Node::GetAttribute(const std::string& k) const
- {
- // std::cout << "this = "<<(void*)this<<std::endl;
- // std::cout << "mFieldValueMap="<<(void*)(&mFieldValueMap)<<std::endl;
- AttributeMapType::const_iterator i = mAttributeMap.find(k);
- if (i == mAttributeMap.end())
- {
- static std::string def("");
- return def;
- // CREAIMAGEIO_ERROR("DicomNode::GetFieldValue : no field with key '"<<k<<"'");
- }
- return i->second;
- }
- //=============================================================
-
- //=============================================================
- void Node::SetAttribute(const std::string& k,
- const std::string& v)
- {
- AttributeMapType::iterator i = mAttributeMap.find(k);
- if (i==mAttributeMap.end())
- {
- std::cout<<"[Gimmick!] Node::SetAttribute : no attribute with key '"
- <<k<<"'"<<std::endl;
- creaError( "[Gimmick!] Node::SetAttribute : no attribute with key '"
- <<k<<"'");
- }
- i->second = v;
- }
- //=============================================================
-
- //=============================================================
- bool Node::Matches( const AttributeMapType& m ) const
- {
- GimmickDebugMessage(2,"'"<<GetLabel()<<"' matching..."<<std::endl);
- const std::vector<std::string>& id
- = GetLevelDescriptor().GetIdentifierList();
- std::vector<std::string>::const_iterator i;
- for (i = id.begin(); i != id.end(); ++i)
- {
- if (mAttributeMap.find(*i)->second != m.find(*i)->second )
- {
- GimmickDebugMessage(2,"IDENTIFIER '"<<*i<<"' values do not match"<<std::endl);
- return false;
- }
- GimmickDebugMessage(2,"IDENTIFIER '"<<*i<<"' values match"<<std::endl);
- }
- return true;
- }
- //=============================================================
-
- //=============================================================
- void Node::Print() const
- {
- std::string mess;
- for (int i = 0; i<GetLevel(); ++i) mess += " ";
- mess += "|_ " + GetLabel();
- GimmickMessage(1,mess<<std::endl);
- ChildrenListType::const_iterator j;
- for (j=GetChildrenList().begin(); j!=GetChildrenList().end(); j++)
- {
- (*j)->Print();
- }
- }
- //=============================================================
-
- //=============================================================
- std::string Node::GetLabel() const
- {
- std::string l;
- const std::vector<std::string>& label
- = GetLevelDescriptor().GetLabelList();
-
- std::vector<std::string>::const_iterator i;
- for (i = label.begin(); i != label.end(); )
- {
- GimmickDebugMessage(9,"LABEL '"<<*i<<"'"<<std::endl);
- AttributeMapType::const_iterator j = mAttributeMap.find(*i);
- if (j != mAttributeMap.end())
- {
- l += j->second;
- ++i;
- if (i != label.end()) l += "|";
- }
- else
- {
- GimmickError("Node::GetLabel() : LABEL attribute '"
- <<*i
- <<"' is not in node attribute map (should be!)" );
- }
- }
- if (l.size()==0) l="?";
- return l;
- }
- //=============================================================
-
- }
-
-}
-
+++ /dev/null
-#ifndef __creaImageIOTreeNode_h_INCLUDED__
-#define __creaImageIOTreeNode_h_INCLUDED__
-
-#include <creaImageIOTreeDescriptor.h>
-#include <creaImageIOTreeComparators.h>
-#include<boost/filesystem/operations.hpp>
-#include <vector>
-#include <map>
-
-
-namespace creaImageIO
-{
-
- namespace tree
- {
- /**
- * \ingroup Tree
- */
- //=====================================================================
- /// Forward declaration of Tree
- class Tree;
- //=====================================================================
-
- //=====================================================================
- /// Abstract class to store user data on a Tree node
- struct NodeData
- {
- NodeData() {}
- virtual ~NodeData() {}
- };
- //=====================================================================
-
-
- //=====================================================================
- /// Node of an attributed Tree structure
- class Node
- {
- public:
- typedef std::map<std::string,std::string> AttributeMapType;
-
-
- /// Ctor with parent
- Node(Node* parent);
- /// Ctor with parent and attributes map
- Node(Node* parent, const AttributeMapType& );
- /// Virtual destructor
- virtual ~Node();
-
- /// Initializes the attribute map i.e. creates the entries
- void InitializeAttributeMap();
-
- /// Returns the level descriptor of the node
- const LevelDescriptor& GetLevelDescriptor() const;
-
-
- /// Returns the tree to which the node belongs
- virtual Tree* GetTree() { return mParent->GetTree(); }
- /// Returns the tree to which the node belongs
- virtual const Tree* GetTree() const { return mParent->GetTree(); }
- /// Returns the level of the node in the tree
- virtual int GetLevel() const { return mParent->GetLevel()+1; }
-
-
- /// Returns the parent of the node
- Node* GetParent() const { return mParent; }
-
- /// Returns the number of children of the node.
- /// Warning : if the children are not loaded then might return 0
- /// even if the node has children !
- /// see TreeHandler::GetNumberOfChildren
- unsigned int GetNumberOfChildren() const { return mChildren.size(); }
-
- /// Returns true iff the node's children are loaded
- bool GetChildrenLoaded() const { return mChildrenLoaded; }
-
- /// Sets the node's children
- void SetChildrenLoaded(bool l) { mChildrenLoaded = l; }
-
- /// The type of children container
- typedef std::vector<Node*> ChildrenListType;
- /// Returns the list of children
- ChildrenListType& GetChildrenList() { return mChildren; }
- /// Returns the list of children (const)
- const ChildrenListType& GetChildrenList() const { return mChildren; }
-
- /// Remove the given children from the children list
- int RemoveChildrenFromList(Node*);
-
-
- /// Get the Attributes Map
- AttributeMapType& GetAttributeMap() { return mAttributeMap; }
-
- /// Get the Attributes Map
- const AttributeMapType& GetAttributeMap() const { return mAttributeMap; }
-
- /// Get the Attribute for a specific key
- const std::string& GetAttribute(const std::string& k) const;
-
- /// Get the Attribute for a specific key without OS dependance (not implemented)
- // TODO : backslash OS uniformity
- const std::string& GetCleanAttribute(const std::string& k) const;
-
- /// Set an Attribute for a specific key
- void SetAttribute(const std::string& k, const std::string& v);
-
- /// Set an Attribute for a specific key(unsafe mode)
- void UnsafeSetAttribute(const std::string& k, const std::string& v)
- { mAttributeMap[k] = v; }
-
- /// Get Descriptor for an Attribute
- const AttributeDescriptor& GetAttributeDescriptor(const std::string& k)const;
-
- /// Returns true if the KEY attributes of the node match those of the map provided
- bool Matches( const AttributeMapType& ) const;
-
- /// Returns the node data casted into the type T
- template<class T> T GetData() const
- { if (mData!=0) return dynamic_cast<T>(mData); return 0; }
-
- /// Sets the node data. Deletes existing data if any.
- void SetData(boost::shared_ptr<NodeData> d) {mData.reset(); mData = d; }//{ if (mData) delete mData; mData = d; }
-
- /// Sorts the children of the node
- void SortChildren(const LexicographicalComparator&);
-
- /// Print the node
- virtual void Print() const;
-
- /// Get the Label of the node
- std::string GetLabel() const;
-
-
- private:
- /// The parent of the node
- Node* mParent;
- /// The list of children
- ChildrenListType mChildren;
- /// The map of attributes
- AttributeMapType mAttributeMap;
- /// User data
- boost::shared_ptr<NodeData> mData;
- /// Are the children loaded ?
- bool mChildrenLoaded;
- /// The number of children
- // int mNumberOfChildren;
-
- }; // class Node
- //=====================================================================
-
- } // namespace tree
-
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIOTreeNode_h_INCLUDED__
+++ /dev/null
-#include <creaImageIOTreeView.h>
-#include <creaImageIOSystem.h>
-
-
-
-namespace creaImageIO
-{
- // CTor
- TreeView::TreeView(TreeHandler* handler, GimmickView* gimmick )
- : mTreeHandler(handler),
- mGimmickView(gimmick)
- {
- GimmickDebugMessage(1,"TreeView::TreeView"
- <<std::endl);
- }
-
- /// Destructor
- TreeView::~TreeView()
- {
- GimmickDebugMessage(1,"TreeView::~TreeView"
- <<std::endl);
- }
-
-
-
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOTreeView_h_INCLUDED__
-#define __creaImageIOTreeView_h_INCLUDED__
-
-#include <creaImageIOTreeHandler.h>
-#include <creaImageIOTimestampDatabaseHandler.h>
-#include <creaImageIOSystem.h>
-#include <vtkImageData.h>
-
-namespace creaImageIO
-{
-
- class GimmickView;
-
- /**
- * \ingroup View
- */
-
- //=====================================================================
-
- //=====================================================================
- /// Abstract class that handles the view of a Tree through its TreeHandler
- class TreeView
- {
- public:
- /// Ctor
- TreeView(TreeHandler*,GimmickView*);
- /// Virtual destructor
- virtual ~TreeView();
-
-
- /// Updates the view of a level given the selected items of upper level
- virtual void UpdateLevel( int )
- { GimmickError("INTERNAL ERROR : TreeView::UpdateLevel not overloaded");}
-
- ///Removes selected nodes
- virtual void RemoveSelected(std::string &i_save )
- { GimmickError("INTERNAL ERROR : TreeView::RemoveSelected not overloaded");}
-
- ///Validates the selected images
- virtual void ValidateSelectedImages()
- { GimmickError("INTERNAL ERROR : TreeView::ValidateSelected not overloaded");}
-
- ///Returns the last selected level
- virtual unsigned int GetLastSelectedLevel(){GimmickError("INTERNAL ERROR : TreeView::GetLastSelectedLevel not overloaded");}
-
- ///Returns the maximum number of levels
- virtual int GetNumberOfLevels(){ GimmickError("INTERNAL ERROR : TreeView::GetLevels not overloaded"); }
- ///Gets the current selections filenames
- virtual void GetSelectedAsString(std::vector<std::string>&s){ GimmickError("INTERNAL ERROR : TreeView::GetSelectedAsString not overloaded"); }
-
- /// Gets the user selected data from the level passed as a parameter
- virtual const std::vector<tree::Node*>& GetSelected(int level){ GimmickError("INTERNAL ERROR : TreeView::GetSelected not overloaded"); }
-
- /// Gets the next nodes on the list, be it up(true) or down(false).
- virtual void GetNodes(std::vector<tree::Node*>& nodes, bool direction){ GimmickError("INTERNAL ERROR : TreeView::GetNodes not overloaded"); }
-
- /// Gets the attributes that are being shown and the ones that have been blocked on a specific level
- virtual void GetAttributes(std::vector<std::string>& areShown, std::vector<std::string>& notShown, int level){ GimmickError("INTERNAL ERROR : TreeView::GetAttributes not overloaded"); }
-
- ///Sets the non visible attributes and refreshes the GUI
- virtual void SetNonVisibleAttributes(const std::vector<std::string>& notShown, int level){ GimmickError("INTERNAL ERROR : TreeView::SetNonVisibleAttributes not overloaded"); }
-
- ///Creates a new listctrl
- virtual void CreateCtrl(std::vector<std::string>& notShown, int nlevel){ GimmickError("INTERNAL ERROR : TreeView::CreateCtrl not overloaded"); }
-
- protected:
- TreeHandler* GetTreeHandler() { return mTreeHandler; }
- GimmickView* GetGimmickView() { return mGimmickView; }
-
- private:
- /// The TreeHandler with which it corresponds
- TreeHandler* mTreeHandler;
- /// The GimmickView which holds the TreeView
- GimmickView* mGimmickView;
-
- };
- // EO class TreeView
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-// EOF
-#endif
+++ /dev/null
-
-#include "creaImageIOSystem.h"
-#include "creaImageIOUltrasonixImageReader.h"
-#include <creaVtk.h>
-#include <boost/filesystem/path.hpp>
-namespace creaImageIO
-{
-#define HEADER_SIZE 19
-#define TYPE_RF 16
-#define TYPE_B8 4
-#define TYPE_B32 8
-
-
- //=====================================================================
- UltrasonixImageReader::UltrasonixImageReader()
- {
- SetName("Ultrasonix");
- }
- //=====================================================================
-
- //=====================================================================
- UltrasonixImageReader::~UltrasonixImageReader()
- {
- }
- //=====================================================================
-
- //=====================================================================
- struct Ultrasonix_header
- {
- // frames, width, height, ultrasounds frequency, sampling rate
- int type, frame, width, height, frequency, samplingRate;
- };
- //=====================================================================
-
-
- //=====================================================================
- bool ReadHeader( FILE *Ultrasonix_file, Ultrasonix_header& h )
- {
- //int *header=(int*)malloc(sizeof(int)*HEADER_SIZE);
- int header[HEADER_SIZE];
- fread(header, sizeof(int), HEADER_SIZE, Ultrasonix_file);
- if (ferror(Ultrasonix_file))
- return false;
- h.type = header[0];
- h.frame = header[1];
- h.height = header[2];
- h.width = header[3];
- h.frequency = header[14];
- h.samplingRate = header[15];
- //free(header);
- return true;
- }
- //=====================================================================
-
- //=====================================================================
- bool UltrasonixImageReader::CanRead(const std::string& filename)
- {
- long size;
- bool ok = false;
- FILE *Ultrasonix_file=fopen(filename.c_str(), "rb");
- if (Ultrasonix_file)
- {
- Ultrasonix_header h;
- if (!ReadHeader(Ultrasonix_file, h) )
- {
- fclose(Ultrasonix_file);
- std::cout << "cannot read Ultrasonix header for file [" << filename << "]" << std::endl;
- return false;
- }
-
- fseek(Ultrasonix_file,0,SEEK_END); // go to end of file
- if (h.type == TYPE_RF)
- size = (ftell(Ultrasonix_file) - (HEADER_SIZE+h.frame) * sizeof(int)) / sizeof(short);
- else if (h.type == TYPE_B8)
- size = (ftell(Ultrasonix_file) - HEADER_SIZE * sizeof(int)) / sizeof(char);
- else if (h.type == TYPE_B32)
- size = (ftell(Ultrasonix_file) - HEADER_SIZE * sizeof(int)) / sizeof(int);
-
- // check if the data size corresponds to the dimensions of the images
- if (size == h.width * h.height * h.frame)
- ok = true;
-
- fclose(Ultrasonix_file);
- }
- return ok;
- }
- //=====================================================================
-
- //=====================================================================
- vtkImageData* UltrasonixImageReader::ReadImage(const std::string& filename)
- {
- FILE *Ultrasonix_file=fopen(filename.c_str(),"rb");
- if (!Ultrasonix_file)
- {
- std::cout << "cannot open file [" << filename << "]" << std::endl;
- return 0;
- }
- Ultrasonix_header h;
- if (!ReadHeader(Ultrasonix_file,h))
- {
- std::cout << "cannot read Ultrasonix header for file [" << filename << "]" << std::endl;
- fclose(Ultrasonix_file);
- return 0;
- }
-
- long frame_size = h.height * h.width;
- long im_size = frame_size * h.frame;
-
- short *dataRF, *ptrRF;
- char *dataB8, *ptrB8;
- int *dataB32, *ptrB32;
- vtkImageData* im;
- int temp;
-
- switch (h.type)
- {
- case TYPE_RF:
- dataRF = (short*)malloc(sizeof(short)*im_size);
- ptrRF = dataRF;
-
- for (int k=0; k<h.frame; k++)
- {
- int frame_number;
- fread(&frame_number, sizeof(int), 1, Ultrasonix_file);
- fread(ptrRF,sizeof(short), frame_size, Ultrasonix_file);
- ptrRF += frame_size;
- }
- fclose(Ultrasonix_file);
-
- im = crea::NewVtkImageDataFromRaw( dataRF, h.width, h.height, h.frame);
- break;
-
- case TYPE_B8:
- dataB8 = (char*)malloc(sizeof(char)*im_size);
- ptrB8 = dataB8;
- for (int k=0; k<h.frame; k++)
- {
- fread(ptrB8,sizeof(char), frame_size, Ultrasonix_file);
- ptrB8 += frame_size;
- }
- // in mode b frames width and height are inverted
- temp = h.width;
- h.width = h.height;
- h.height = temp;
-
- fclose(Ultrasonix_file);
-
- im = crea::NewVtkImageDataFromRaw( dataB8, h.width, h.height, h.frame);
- break;
-
- case TYPE_B32:
- dataB32 = (int*)malloc(sizeof(int)*im_size);
- ptrB32 = dataB32;
- for (int k=0; k<h.frame; k++)
- {
- fread(ptrB32, sizeof(int), frame_size, Ultrasonix_file);
- ptrB32 += frame_size;
- }
- // in B mode frames width and height are inverted
- temp = h.width;
- h.width = h.height;
- h.height = temp;
-
- fclose(Ultrasonix_file);
-
- im = crea::NewVtkImageDataFromRaw( dataB32, h.width, h.height, h.frame);
- break;
- }
-
- return im;
-}
- //=====================================================================
-
-
- //=====================================================================
- void UltrasonixImageReader::PushBackExtensions(std::vector<std::string>& v)
- {
- v.push_back("Ultrasonix");
- }
- //=====================================================================
-
-
-
- //=====================================================================
- void UltrasonixImageReader::ReadAttributes(const std::string& filename,
- std::map<std::string,std::string>& attr)
- {
- GimmickMessage(2,"Reading attributes from '" << filename << std::endl);
-
- FILE *Ultrasonix_file = fopen(filename.c_str(), "rb");
- if (!Ultrasonix_file)
- {
- std::cout << "cannot open RF file [" << filename << "]" << std::endl;
- return;
- }
-
- Ultrasonix_header h;
- if (!ReadHeader(Ultrasonix_file, h))
- {
- fclose(Ultrasonix_file);
- std::cout << "cannot read Ultrasonix Attributes for RF file [" << filename << "]" << std::endl;
- return;
- }
-
- fclose(Ultrasonix_file);
-
- // Columns
- char cols[128];
- sprintf(cols,"%i", h.width);
- // Rows
- char rows[128];
- sprintf(rows,"%i", h.height);
- // Planes
- char planes[128];
- sprintf(planes,"%i", h.frame);
- // Sampling frequency
- char samplingFrequency[128];
- sprintf(samplingFrequency,"%i", h.samplingRate);
- // Transducer frequency
- char transducerFrequency[128];
- sprintf(transducerFrequency,"%i", h.frequency);
-
- //
- std::map<std::string,std::string>::iterator i;
- if ( (i = attr.find("FullFileName")) != attr.end())
- {
- i->second = filename;
- }
- if ( (i = attr.find("D0004_1500")) != attr.end())
- {
- boost::filesystem::path full_path(filename);
- std::string f = full_path.leaf();
- i->second = f;
- }
- if ( (i = attr.find("D0028_0010")) != attr.end())
- {
- i->second = rows;
- }
- if ( (i = attr.find("D0028_0011")) != attr.end())
- {
- i->second = cols;
- }
- if ( (i = attr.find("D0028_0012")) != attr.end())
- {
- i->second = planes;
- }
- if ( (i = attr.find("D003a_001a")) != attr.end())
- {
- i->second = samplingFrequency;
- }
- if ( (i = attr.find("D0018_6030")) != attr.end())
- {
- i->second = transducerFrequency;
- }
-
- GimmickMessage(2,"Attributes map:"<<std::endl<<attr<<std::endl);
- return;
-}
- //=====================================================================
-
-} // namespace creaImageIO
+++ /dev/null
-#ifndef __creaImageIOUltrasonixImageReader_h_INCLUDED__
-#define __creaImageIOUltrasonixImageReader_h_INCLUDED__
-
-#include <creaImageIOAbstractImageReader.h>
-#include <creaImageIOSystem.h>
-
-namespace creaImageIO
-{
- /**
- * \ingroup IO
- */
-
- //=====================================================================
- /// Concrete image reader for ultrasonix 'rf' files
- class CREAIMAGEIO_EXPORT UltrasonixImageReader : virtual public AbstractImageReader
- {
- public:
- UltrasonixImageReader();
-
- virtual ~UltrasonixImageReader();
- /// Add file extensions read by the reader
- virtual void PushBackExtensions(std::vector<std::string>&);
- /// Test if file is read by this reader
- virtual bool CanRead(const std::string& filename);
- /// return for a file a 2D VTkImage
- virtual vtkImageData* ReadImage(const std::string& filename);
- /// Read the attributes for a file
- virtual void ReadAttributes(const std::string& filename,
- tree::AttributeMapType& attr);
-
- };
- //=====================================================================
-
-} // namespace creaImageIO
-
-#endif // #ifndef __creaImageIOUltrasonixImageReader_h_INCLUDED__
+++ /dev/null
-#include <creaImageIOVtkImageReader.h>
-#include <vtkImageReader2.h>
-#include <creaImageIOSystem.h>
-#include "boost/filesystem/path.hpp"
-
-namespace creaImageIO{
- //=====================================================================
- VtkImageReader::VtkImageReader(vtkImageReader2* r,
- const std::string& name,
- const std::string& extensions)
- : mReader(r), mExtensions(extensions)
- {
- if (name.size() == 0)
- {
- const char *test =mReader->GetDescriptiveName();
- if(test != "")
- {
- SetName ( "toto");// mReader->GetDescriptiveName());
- }
-
- }
- else
- {
- SetName ( name );
- }
- GimmickDebugMessage(5,"Constructing vtkImageReader : "<<GetName()
- <<std::endl);
-
- }
- //=====================================================================
-
- //=====================================================================
- VtkImageReader::~VtkImageReader()
- {
-
- mReader->Delete();
- }
- //=====================================================================
-
- //=====================================================================
- bool VtkImageReader::CanRead(const std::string& filename)
- {
-
- return (mReader->CanReadFile(filename.c_str())!=0);
-/* if(filename != "")
- {
- return (mReader->CanReadFile(filename.c_str())!=0);
- }
- else
- {
- return false;
- }*/
- }
- //=====================================================================
-
- //=====================================================================
- vtkImageData* VtkImageReader::ReadImage(const std::string& filename)
- {
- vtkImageData* im = 0;
- try
- {
- mReader->SetFileName(filename.c_str());
- mReader->Update();
- im = vtkImageData::New();
- im->ShallowCopy(mReader->GetOutput());
- }
- catch (...)
- {
- if (im!=0) im->Delete();
- im = 0;
- }
- return im;
- }
- //=====================================================================
-
- //=====================================================================
- void SplitExtensionsString ( const std::string& str,
- const std::string& delimiters,
- std::vector<std::string>& tokens)
- {
- // Skip delimiters at beginning.
- std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
- // Find first delimiter.
- std::string::size_type pos = str.find_first_of(delimiters, lastPos);
-
- while (std::string::npos != pos || std::string::npos != lastPos)
- {
- // Found a token, add it to the vector.
- // SPECIFIC : REMOVE INITIAL DOT (lastPos + 1)
- tokens.push_back(str.substr(lastPos+1, pos - lastPos));
- // Skip delimiters. Note the "not_of"
- lastPos = str.find_first_not_of(delimiters, pos);
- // Find next delimiter
- pos = str.find_first_of(delimiters, lastPos);
- }
-
- }
- //=====================================================================
-
- //=====================================================================
- void VtkImageReader::PushBackExtensions(std::vector<std::string>& v)
- {
- std::string ext = mExtensions;
- if (ext.size()==0) ext = mReader->GetFileExtensions ();
-
- SplitExtensionsString(ext," ",v);
- }
- //=====================================================================
-
-
-
- //=====================================================================
- void VtkImageReader::ReadAttributes(const std::string& filename,
- std::map<std::string,std::string>& attr)
- {
- GimmickMessage(2,"Reading attributes from '"<<filename<<std::endl);
- // Get image dimensions
- // How to get the image info without loading it in vtk ?
- mReader->SetFileName(filename.c_str());
- mReader->Update(); //OpenFile();
- int ext[6];
- mReader->GetDataExtent(ext);
- // Columns
- char cols[128];
- sprintf(cols,"%i",ext[1]-ext[0]);
- // Rows
- char rows[128];
- sprintf(rows,"%i",ext[3]-ext[2]);
- // Planes
- char planes[128];
- sprintf(planes,"%i",ext[5]-ext[4]);
-
- std::map<std::string,std::string>::iterator i;
- if ( (i = attr.find("FullFileName")) != attr.end())
- {
- i->second = filename;
- }
- if ( (i = attr.find("D0004_1500")) != attr.end())
- {
- boost::filesystem::path full_path(filename);
- std::string f = full_path.leaf();
- i->second = f;
- }
- if ( (i = attr.find("D0028_0010")) != attr.end())
- {
- i->second = rows;
- }
- if ( (i = attr.find("D0028_0011")) != attr.end())
- {
- i->second = cols;
- }
-
- if ( (i = attr.find("D0028_0012")) != attr.end())
- {
- i->second = planes;
- }
- if ( (i = attr.find("FullFileDirectory")) != attr.end())
- {
- std::string::size_type last_pos = filename.find_last_of("//");
- i->second = filename.substr(0, last_pos);
- }
-
- GimmickMessage(2,"Attributes map:"<<std::endl<<attr<<std::endl);
- }
- //=====================================================================
-
-} // namespace creaImageIO
+++ /dev/null
-#ifndef __creaImageIOVtkImageReader_h_INCLUDED__
-#define __creaImageIOVtkImageReader_h_INCLUDED__
-
-
-#include <creaImageIOAbstractImageReader.h>
-
-// forward decl
-class vtkImageReader2;
-
-namespace creaImageIO
-{
-
-
- /**
- * \ingroup IO
- */
-
- //=====================================================================
- /// Concrete image reader based on a vtkImageReader2
- class VtkImageReader : virtual public AbstractImageReader
- {
- public:
- VtkImageReader(vtkImageReader2* reader,
- const std::string& name = "",
- const std::string& extensions = "");
-
- virtual ~VtkImageReader();
-
-
-
- /// Add file extensions read by the reader
- virtual void PushBackExtensions(std::vector<std::string>&);
- /// Test if file is read by this reader
- virtual bool CanRead(const std::string& filename);
- /// return for a file a 2D VTkImage
- virtual vtkImageData* ReadImage(const std::string& filename);
- /// Read the attributes for a file
- virtual void ReadAttributes(const std::string& filename,
- tree::AttributeMapType& attr);
-
- private:
- vtkImageReader2* mReader;
- std::string mExtensions;
- };
- //=====================================================================
-
-
-
-} // namespace creaImageIO
-
-
-
-#endif // #ifndef __creaImageIOVtkImageReader_h_INCLUDED__
+++ /dev/null
-#include <creaImageIOWxAttributeSelectionPanel.h>
-#include <creaImageIOSystem.h>
-
-
-namespace creaImageIO
-{
- const int ID_COMBO = 180;
- // CTor
- WxAttributeSelectionPanel::WxAttributeSelectionPanel(wxWindow *parent,
- wxDialog* dial,
- WxGimmickView* view,
- std::vector<std::string> sAtts,
- std::vector<std::string> nsAtts,
- int numLev)
- : wxPanel( parent,
- -1, wxDefaultPosition,
- wxDefaultSize,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- dialog(dial),
- shownA(sAtts),
- notShownA(nsAtts),
- mView(view)
- {
- GimmickDebugMessage(1,"WxCustomizeConfigPanel::WxCustomizeConfigPanel"
- <<std::endl);
- wxStaticText * aa=new wxStaticText(this,-1,_T(" Currently shown attributes for level: "), wxPoint(5,10));
- wxArrayString as;
- std::stringstream out;
- for(int i=1;i<=numLev;i++)
- {
- out<<i;
- as.Add(crea::std2wx(out.str()));
- out.str("");
- }
- levels=new wxComboBox(this, ID_COMBO,_T("1"),wxPoint(190, 5),wxDefaultSize,as);
- wxStaticText * na=new wxStaticText(this,-1,_T(" Currently hidden attributes: "), wxPoint(255,10));
-
- shownAtts=new wxListCtrl(this, wxID_ANY, wxPoint(5,30), wxSize(160,90), wxLC_REPORT | wxLC_NO_HEADER );
-
- shownAtts->InsertColumn(0,
- crea::std2wx(""),
- wxLIST_FORMAT_LEFT);
- shownAtts->SetColumnWidth(0,155);
- shownAtts->Show();
-
- wxButton *add = new wxButton(this,wxID_ANY,_T(">>"), wxPoint(170,50) );
- Connect( add->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxAttributeSelectionPanel::OnAdd );
-
- wxButton *remove = new wxButton(this,wxID_ANY,_T("<<"), wxPoint(170,70) );
- Connect( remove->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxAttributeSelectionPanel::OnRemove );
-
- notShownAtts=new wxListCtrl(this, wxID_ANY, wxPoint(255,30), wxSize(160,90), wxLC_REPORT | wxLC_NO_HEADER );
-
- notShownAtts->InsertColumn(0,
- crea::std2wx(""),
- wxLIST_FORMAT_LEFT);
- notShownAtts->SetColumnWidth(0,155);
- notShownAtts->Show();
- LoadCtrls();
-
- wxButton *save = new wxButton(this,wxID_ANY,_T("Save Changes"), wxPoint(5,130) );
- Connect( save->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxAttributeSelectionPanel::OnSaveConfig );
-
- Layout();
- }
-
- /// Destructor
- WxAttributeSelectionPanel::~WxAttributeSelectionPanel()
- {
- GimmickDebugMessage(1,"WxAttributeSelectionPanel::~WxAttributeSelectionPanel"
- <<std::endl);
- }
-
- void WxAttributeSelectionPanel::OnSaveConfig(wxCommandEvent& event)
- {
- int n=levels->GetSelection();
- if(n<0){n=0;}
- mView->OnAttributesChanged(notShownA,n);
- dialog->Destroy();
- }
-
- void WxAttributeSelectionPanel::OnAdd(wxCommandEvent& event)
- {
- long item = -1;
- for ( ;; )
- {
- item = shownAtts->GetNextItem(item,
- wxLIST_NEXT_ALL,
- wxLIST_STATE_SELECTED);
- if ( item == -1 )
- break;
-
- std::string change = crea::wx2std(shownAtts->GetItemText(item));
- std::vector<std::string>::iterator it;
- bool found=false;
- for(it=shownA.begin();it!=shownA.end()&&!found;++it)
- {
- if((*it).compare(change)==0)
- {
- found=true;
- }
- }
- shownA.erase(it-1);
- notShownA.push_back(change);
- }
- LoadCtrls();
-
- }
-
- void WxAttributeSelectionPanel::OnRemove(wxCommandEvent& event)
- {
-
- long item = -1;
- for ( ;; )
- {
- item = notShownAtts->GetNextItem(item,
- wxLIST_NEXT_ALL,
- wxLIST_STATE_SELECTED);
- if ( item == -1 )
- break;
-
- std::string change = crea::wx2std(notShownAtts->GetItemText(item));
- std::vector<std::string>::iterator it;
- bool found=false;
- for(it=notShownA.begin();it!=notShownA.end()&&!found;++it)
- {
- if((*it).compare(change)==0)
- {
- found=true;
- }
- }
- notShownA.erase(it-1);
- shownA.push_back(change);
-
- }
- LoadCtrls();
-
- }
-
-
- void WxAttributeSelectionPanel::LoadCtrls()
- {
-
- wxListItem item;
- item.SetMask(wxLIST_MASK_STATE |
- wxLIST_MASK_TEXT |
- // wxLIST_MASK_IMAGE |
- wxLIST_MASK_DATA |
- // wxLIST_MASK_WIDTH |
- wxLIST_MASK_FORMAT
- );
- std::vector<std::string>::iterator it;
- shownAtts->DeleteAllItems();
- notShownAtts->DeleteAllItems();
- for(it=shownA.begin();it!=shownA.end();++it)
- {
- item.SetText(crea::std2wx(*it));
- shownAtts->InsertItem(item);
- }
-
-
- for(it=notShownA.begin();it!=notShownA.end();++it)
- {
- item.SetText(crea::std2wx(*it));
- notShownAtts->InsertItem(item);
- }
-
- }
- void WxAttributeSelectionPanel::OnComboChange(wxCommandEvent& event)
- {
- int n=levels->GetSelection()+1;
- mView->GetVisibleAttributes(shownA,notShownA,n);
- LoadCtrls();
- }
-
-//======================================================================
-BEGIN_EVENT_TABLE(WxAttributeSelectionPanel, wxPanel)
-EVT_COMBOBOX (ID_COMBO,WxAttributeSelectionPanel::OnComboChange)
-END_EVENT_TABLE()
-//======================================================================
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxAttributeSelectionPanel_h_INCLUDED__
-#define __creaImageIOWxAttributeSelectionPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <creaImageIOWxGimmickView.h>
-#include <wx/listctrl.h>
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- class WxAttributeSelectionPanel : public wxPanel
- {
- public:
- WxAttributeSelectionPanel();
- WxAttributeSelectionPanel(wxWindow *parent,
- wxDialog* dial,
- WxGimmickView* view,
- std::vector<std::string> sAtts,
- std::vector<std::string> nsAtts,
- int numLev);
-
- ~WxAttributeSelectionPanel();
- ///Saves the configuration
- void OnSaveConfig(wxCommandEvent& event);
- ///Changes items from shown to notShown
- void OnAdd(wxCommandEvent& event);
- ///Changes items from notShown to shown
- void OnRemove(wxCommandEvent& event);
- void OnComboChange(wxCommandEvent& event);
-
-
- private :
- ///Loads the information on the vectors onto the lists
- void LoadCtrls();
- std::vector<std::string> shownA;
- std::vector<std::string> notShownA;
- wxComboBox* levels;
- wxListCtrl* shownAtts;
- wxListCtrl* notShownAtts;
- wxDialog* dialog;
- WxGimmickView* mView;
-
-
- DECLARE_EVENT_TABLE()
-
- }; // class WxAttributeSelectionPanel
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOWxCustomizeConfigPanel.h>
-#include <creaImageIOSystem.h>
-namespace creaImageIO
-{
- // CTor
- WxCustomizeConfigPanel::WxCustomizeConfigPanel(wxWindow *parent, wxDialog* dial, WxGimmickView* view, const std::string& cPath,
- const std::string& dPath,
- const std::string& sEvent,
- const std::string& sFreq)
- : wxPanel( parent,
- -1, wxDefaultPosition,
- wxDefaultSize,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- dialog(dial),
- copyP (cPath),
- databaseP(dPath),
- syncEv(sEvent),
- syncFr(sFreq),
- mView(view)
- {
- GimmickDebugMessage(1,"WxCustomizeConfigPanel::WxCustomizeConfigPanel"
- <<std::endl);
- wxStaticText * cp=new wxStaticText(this,-1,_T(" Copy Path: "), wxPoint(5,10));
- copyPath=new wxTextCtrl(this, wxID_ANY, crea::std2wx(copyP), wxPoint(150,10), wxSize(250,20));
-
- wxStaticText * dp=new wxStaticText(this,-1,_T(" Database Path: "), wxPoint(5,40));
- dbPath=new wxTextCtrl(this, wxID_ANY, crea::std2wx(databaseP), wxPoint(150,40), wxSize(250,20));
-
- wxStaticText * se=new wxStaticText(this,-1,_T(" Synchronization Event: "), wxPoint(5,70));
- syncEvent=new wxTextCtrl(this, wxID_ANY, crea::std2wx(syncEv), wxPoint(150,70), wxSize(250,20));
-
- wxStaticText * sf=new wxStaticText(this,-1,_T(" Synchronization Frequency: "), wxPoint(5,100));
- syncFrequency=new wxTextCtrl(this, wxID_ANY, crea::std2wx(syncFr), wxPoint(150,100), wxSize(250,20));
-
- wxButton *save = new wxButton(this,wxID_ANY,_T("Save Changes"), wxPoint(5,130) );
- Connect( save->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxCustomizeConfigPanel::OnSaveConfig );
-
- Layout();
- }
-
- /// Destructor
- WxCustomizeConfigPanel::~WxCustomizeConfigPanel()
- {
- GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
- <<std::endl);
- }
-
- void WxCustomizeConfigPanel::OnSaveConfig(wxCommandEvent& event)
- {
- mView->OnSaveSettingsCallback(crea::wx2std(copyPath->GetValue()),
- crea::wx2std(dbPath->GetValue()),
- crea::wx2std(syncEvent->GetValue()),
- crea::wx2std(syncFrequency->GetValue()));
- dialog->Destroy();
- }
-
-//======================================================================
-
-//======================================================================
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxCustomizeConfigPanel_h_INCLUDED__
-#define __creaImageIOWxCustomizeConfigPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <creaImageIOWxGimmickView.h>
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- class WxCustomizeConfigPanel : public wxPanel
- {
- public:
- WxCustomizeConfigPanel();
- WxCustomizeConfigPanel(wxWindow *parent,
- wxDialog* dial,
- WxGimmickView* view,
- const std::string& cPath,
- const std::string& dPath,
- const std::string& sEvent,
- const std::string& sFreq);
-
- ~WxCustomizeConfigPanel();
- ///Saves the configuration
- void OnSaveConfig(wxCommandEvent& event);
-
- private :
- std::string copyP;
- std::string databaseP;
- std::string syncEv;
- std::string syncFr;
- wxTextCtrl* copyPath;
- wxTextCtrl* dbPath;
- wxTextCtrl* syncEvent;
- wxTextCtrl* syncFrequency;
- wxDialog* dialog;
- WxGimmickView* mView;
-
-
- }; // class WxCustomizeConfigPanel
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
-
+++ /dev/null
-#include "creaImageIOWxDescriptorPanel.h"
-#include <creaImageIOSystem.h>
-#if defined(USE_GDCM)
-#include <gdcmGlobal.h>
-#include <gdcmDictSet.h>
-#endif
-
-#if defined(USE_GDCM2)
-#include <gdcmGlobal.h>
-#include <gdcmDicts.h>
-#include <gdcmDict.h>
-#endif
-#include <boost/algorithm/string.hpp>
-
-namespace creaImageIO
-{
- // CTor
-
- WxDescriptorPanel::WxDescriptorPanel(wxWindow *parent, const std::string path)
- : wxDialog(parent, -1,_T("Descriptor Creation"), wxDefaultPosition, wxSize(550,550)) , m_path(path)
-{
-
-
- GimmickDebugMessage(1,"WxDescriptorPanel::WxDescriptorPanel"
- <<std::endl);
-
- lv = 0;
- ownatt["FullFileName"] = "Full_File_Name";
- ownatt["FullFileDirectory"] = "Full_File_Directory";
-
-
- // START BUTTONS
- wxButton *NewDescriptor = new wxButton(this, -1,_T("Create a new descriptor"), wxPoint(10,7) );
- Connect( NewDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnNew );
-
- wxButton *LoadDescriptor = new wxButton(this, -1,_T("Load a descriptor"), wxPoint(150,7) );
- Connect( LoadDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnLoad );
-
- wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
-
- // LEVEL
- wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
- LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
- wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
- Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel );
-
- wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
-
- // ATTRIBUTES
-
- wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
- GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
- Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
-
- wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
- ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
- Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
-
-
- wxString choices[3];
- choices[0] = _T("Unknow Attribute");
- std::map<std::string, std::string>::iterator it_att =ownatt.begin();
- for(int i = 1; it_att != ownatt.end(); it_att++, i++)
- {
- choices[i] = crea::std2wx(it_att->second);
- }
-
-
- AttributeCombo = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
- AttributeCombo->SetSelection(0);
-
-
- wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
- Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute );
-
- wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
-
- // RESULT
-
- ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
- wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
- Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove );
-
- wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
- // VALIDATION BUTTON
- wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
- Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK );
-
- wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
- Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply );
-
- wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
-// Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close );
-
- Layout();
- CreateDescriptor(0);
- }
-
- /// Destructor
- WxDescriptorPanel::~WxDescriptorPanel()
- {
- GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
- <<std::endl);
- }
-
- //////////////////////////////////////////////////////////
- // Add an attribute //
- // @param event : Wxevent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
- {
- std::string name_lv;
- std::string name_att;
- if (AttributeCombo->GetSelection() == 0)
- {
- name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
- }
- else
- {
- wxString wd = AttributeCombo->GetValue();
- std::string st = crea::wx2std(wd);
- name_att = OwnAttribute(st);
- }
- onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
- }
- //////////////////////////////////////////////////////////
- // add an attribute //
- // @param att : attribute //
- // @param name_att : 's name //
- // @param level : level to add the attribute //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
- {
- if(lv == 0)
- {
- wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
- }
- else
- {
- if( !att.empty() )
- {
- // Find Name of level
- if(level.empty())
- {
- level = findLevel();
- }
-
- if (!addAtribute(level, name_att))
- {
- wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
- }
- else
- {
- ResultCtrl->SetInsertionPoint(InsertPt);
- for (int i = 1; i<=lv;i++)
- {
- ResultCtrl->WriteText(_T(" "));
- }
- ResultCtrl->WriteText(_T("| - "));
- ResultCtrl->WriteText(crea::std2wx(att));
- wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
- ResultAttr.SetTextColour(*wxWHITE);
- ResultCtrl->SetDefaultStyle(ResultAttr);
- std::string text = " ";
- ResultCtrl->WriteText(crea::std2wx(" " + name_att));
- ResultAttr.SetTextColour(*wxBLACK);
- ResultCtrl->SetDefaultStyle(ResultAttr);
- ResultCtrl->WriteText(_T("\n"));
- }
- InsertPt = ResultCtrl->GetInsertionPoint();
- }
- }
- }
-
- //////////////////////////////////////////////////////////
- // add a level //
- // @param event : Wxevent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
- {
- if( !LevelCtrl->GetValue().IsEmpty() )
- {
- onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
- }
- }
-
- //////////////////////////////////////////////////////////
- // add a level //
- // @param level : level's name //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::onAddLevel(const std::string &level)
- {
- if(addLevel(level))
- {
- wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
- return;
- }
-
- lv++;
- ResultCtrl->SetInsertionPoint(InsertPt);
- for (int i = 1; i<lv;i++)
- {
- ResultCtrl->WriteText(_T(" "));
- }
- if(lv>1)
- { ResultCtrl->WriteText(_T("| \n"));
- for (int i = 1; i<lv;i++)
- {
- ResultCtrl->WriteText(_T(" "));
- }
- ResultCtrl->WriteText(_T("|_"));
- }
-
- wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
- ResultAttr.SetTextColour(*wxRED);
- ResultCtrl->SetDefaultStyle(ResultAttr);
- ResultCtrl->WriteText(crea::std2wx(level));
- ResultAttr.SetTextColour(*wxBLACK);
- ResultCtrl->SetDefaultStyle(ResultAttr);
- ResultCtrl->WriteText(_T("\n"));
- InsertPt = ResultCtrl->GetInsertionPoint();
-
- }
-
- //////////////////////////////////////////////////////////
- // Find a DICOM attribute from group and element values //
- // @param event : Wxevent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
- {
- int i = 0;
- if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty()
- && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
- {
-
- std::string gr = crea::wx2std(GRCtrl->GetValue());
- std::string el = crea::wx2std(ELCtrl->GetValue());
- std::stringstream val;
-
- unsigned short group;
- unsigned short element;
- val << std::dec << gr ;
- val >> std::hex >> group;
- val.clear();
- val << std::dec << el ;
- val >> std::hex >> element;
-#if defined(USE_GDCM)
- // Retrieve the name from gdcm dict
- GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
- // AttributeCombo->Clear();
- if(entry)
- {
- AttributeCombo->Delete(0);
- AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
- }
- else
- {
- AttributeCombo->Delete(0);
- AttributeCombo->Insert(_T("Unknown Attribute"),0);
- }
-#endif
- AttributeCombo->SetSelection(0);
-
- }
-
- }
-
-
- //////////////////////////////////////////////////////////
- // determine values for own attributes //
- // @param name : attribute's name //
- // @param key : indicates key map or not //
- // @return : - //
- //////////////////////////////////////////////////
- std::string WxDescriptorPanel::OwnAttribute(const std::string name)
- {
- std::string result;
-
- std::map<std::string, std::string>::iterator it_att = ownatt.begin();
- for(; it_att != ownatt.end(); it_att++)
- {
- if(it_att->second == name)
- {
- result = it_att->first.c_str();
- break;
- }
- }
- return result;
- }
-
- //////////////////////////////////////////////////////////
- // Find a level in function of position in Return Ctrl //
- // @param - : //
- // @return : - //
- //////////////////////////////////////////////////
- std::string WxDescriptorPanel::findLevel()
- {
- long column;
- long line;
-
- ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
- std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
- std::string::size_type level_pos_start = tx.rfind("|_");
- if(level_pos_start == -1)
- {
- level_pos_start = 0;
- }
- else
- {
- level_pos_start += 2;
- }
-
- std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
- return tx.substr(level_pos_start,level_pos_end - level_pos_start);
- }
-
- //////////////////////////////////////////////////////
- // Remove an item //
- // @param event : Wxevent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
- {
- long line;
- long column;
- long pos_start;
- long pos_end;
-
- pos_start = ResultCtrl->GetInsertionPoint();
- ResultCtrl->PositionToXY( pos_start,&column, &line);
- if (line == 0)
- {
- std::string name("root");
- RemoveLevel(name);
- ResultCtrl->Clear();
- lv = 0;
- }
- else
- {
- wxString text = ResultCtrl->GetLineText(line);
- if ( text.Find(_T("|_")) == -1)
- {
- std::string level = findLevel();
- // find GR and EL values to remove
- std::string tx = crea::wx2std(text);
- std::string::size_type EL_start_pos = tx.find_last_of(" ");
- RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
- ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
- }
- else
- {
- RemoveLevel(crea::wx2std(text.AfterFirst('_')));
- lv = text.Find(_T("|"))/3;
- pos_start= ResultCtrl->XYToPosition(0,line-1);
- ResultCtrl->SetInsertionPointEnd();
- pos_end = ResultCtrl->GetInsertionPoint();
- ResultCtrl->Remove(pos_start, pos_end);
- }
- }
-
- }
- //////////////////////////////////////////////
- // create a descriptor structure //
- // @param name : level's name to add //
- // @return : boolean result //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::CreateDescriptor(int type)
- {
- if(type == 0) // First initialization
- {
- outDscp.clear();
- outDscp += "<level>";
- outDscp += "\n";
- outDscp += "root";
- outDscp += "\n";
- outDscp += "O Name Name 4";
- outDscp += "\n";
- }
- if(type == 1)
- {
- if(lv > 1)
- {
- outDscp += "O NumberOfChildren ";
- outDscp += crea::wx2std(LevelCtrl->GetValue());
- outDscp += "s";
- outDscp += "\n";
- }
- outDscp += "<level>";
- outDscp += "\n";
- outDscp += crea::wx2std(LevelCtrl->GetValue());
- outDscp += "\n";
-
- }
- if(type == 2)
- {
- outDscp += "D";
- outDscp += " ";
- outDscp += crea::wx2std(GRCtrl->GetValue());
- outDscp += " ";
- outDscp += crea::wx2std(ELCtrl->GetValue());
- outDscp += " ";
- outDscp += "3";
- outDscp += "\n";
- }
-
-
- }
-
-
- //////////////////////////////////////////////////////
- // add a level //
- // @param name : level's name to add //
- // @return : boolean result //
- //////////////////////////////////////////////////
- bool WxDescriptorPanel::addLevel(const std::string &name)
- {
- bool bfound = false;
- std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
- for (;it_tree != DscpTree.end(); it_tree++)
- {
- if(it_tree->first == name)
- {
- bfound = true;
- break;
- }
- }
- if(!bfound)
- {
- lvlist[lv] = name;
- std::vector <std::string> branch;
- DscpTree[name] = branch;
- }
- return bfound;
- }
-
- //////////////////////////////////////////////////////
- // remove a level //
- // @param name : level's name to remove //
- // @return : boolean result //
- //////////////////////////////////////////////////
- bool WxDescriptorPanel::RemoveLevel(const std::string &name)
- {
- bool bresult = false;
- std::map<int, std::string>::iterator it_list= lvlist.begin();
- for(; it_list != lvlist.end(); it_list++)
- {
- if(it_list->second == name)
- {
- break;
- }
- }
- std::map<int, std::string>::iterator it_list2 = it_list;
- for(;it_list != lvlist.end(); it_list++)
- {
- std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
- for (;it_tree != DscpTree.end(); it_tree++)
- {
- if(it_tree->first == name)
- {
- DscpTree.erase(it_tree);
- break;
- }
- }
- }
- lvlist.erase(it_list2, lvlist.end());
- return bresult;
- }
-
-
- //////////////////////////////////////////////////////
- // add an attribute in a level //
- // @param level : level's name to add attribute //
- // @param name : attribute's name //
- // @return : boolean result //
- //////////////////////////////////////////////////
- bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
- {
- bool bresult = true;
- std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
- for (;it_tree != DscpTree.end(); it_tree++)
- {
- if (it_tree->first.c_str() == level)
- {
- std::vector<std::string>::iterator it_branch = it_tree->second.begin();
- for(;it_branch != it_tree->second.end(); it_branch++)
- {
- if(it_branch->c_str() == name)
- {
- bresult = false;
- }
- }
- if(bresult)
- {
- it_tree->second.push_back(name);
- break;
- }
- }
- }
- return bresult;
- }
-
- //////////////////////////////////////////////////////
- // remove an attribute from a level //
- // @param level : level's name to remove attribute //
- // @param name : attribute's name //
- // @return : boolean result //
- //////////////////////////////////////////////////
- bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
- {
- bool bresult = false;
- std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
- for (;it_tree != DscpTree.end(); it_tree++)
- {
- if(it_tree->first == level)
- {
- std::vector<std::string>::iterator it_branch = it_tree->second.begin();
- cout << it_tree->second.size();
- for(;it_branch != it_tree->second.end(); it_branch++)
- {
- if(it_branch->c_str() == name)
- {
- bresult = true;
- it_tree->second.erase(it_branch);
- break;
- }
- }
- }
- }
- return bresult;
- }
-
- //////////////////////////////////////////////////
- // create a new descriptor //
- // @param event : WxEvent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
- {
- LevelCtrl->SetValue(_T("patient"));
- ResultCtrl->Clear();
- DscpTree.clear();
- lv = 0;
- }
-
- //////////////////////////////////////////////////
- // Load a descriptor file //
- // @param event : WxEvent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
- {
- long style = wxOPEN | wxFILE_MUST_EXIST;
- LevelCtrl->SetValue(_T("patient"));
- ResultCtrl->Clear();
- DscpTree.clear();
- lv = 0;
-
- std::string wc("*.dscp");
- wxFileDialog* FD = new wxFileDialog( 0,
- _T("Select file"),
- crea::std2wx(m_path),
- _T(""),
- crea::std2wx(wc),
- style,
- wxDefaultPosition);
- if (FD->ShowModal()==wxID_OK)
- {
- loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
- }
-
- }
-
- //////////////////////////////////////////////////
- // Save a descriptor //
- // @param event : WxEvent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
- {
- saveDescriptor();
- wxWindow::Close();
- }
-
- /////////////////////////////////////////////////////
- // Save a descriptor and apply it (create a new DB//
- // @param event : WxEvent //
- // @return : - //
- /////////////////////////////////////////////////////
- void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
- {
- m_DscpFile = saveDescriptor();
- wxWindow::Close();
- SetReturnCode(ID_DSCP_APPLY);
- }
-
- const std::string WxDescriptorPanel::saveDescriptor()
- {
- std::string file = "";
- long style = wxSAVE;
- std::string wc("*.dscp");
- wxFileDialog* FD = new wxFileDialog( 0,
- _T("Select file"),
- _T(""),
- _T(""),
- crea::std2wx(wc),
- style,
- wxDefaultPosition);
-
-
- if (FD->ShowModal()==wxID_OK)
- {
- createDescriptorFile();
- file = crea::wx2std(FD->GetPath()).c_str();
- std::ofstream ofs(file.c_str());
- ofs.clear();
- ofs << outDscp;
- ofs.close();
- }
- return file.c_str();
- }
-
- ///////////////////////////////////////////////////////
- // Cancel action //
- // @param event : WxEvent //
- // @return : - //
- ///////////////////////////////////////////////////////
-
- void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
- {
- }
-
- ///////////////////////////////////////////////////////
- // create a descriptor file //
- // @param - : //
- // @return : - //
- ///////////////////////////////////////////////////////
- void WxDescriptorPanel::createDescriptorFile()
- {
-
- outDscp.clear();
- outDscp += "<level>";
- outDscp += "\n";
- outDscp += "Root";
- outDscp += "\n";
- outDscp += "O Name Name 4";
- outDscp += "\n";
- std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
- std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
- std::map<int, std::string >::iterator it_lv = lvlist.begin();
- it_lv_nb++;
- for (;it_lv != lvlist.end(); it_lv++)
- {
- outDscp +="<level>";
- outDscp += "\n";
- outDscp += it_lv->second.c_str();
- outDscp += "\n";
- if(it_lv_nb != lvlist.end())
- {
- outDscp += "O NumberOfChildren ";
- outDscp += it_lv_nb->second.c_str();
- outDscp += "s";
- outDscp += "\n";
- it_lv_nb++;
- }
- std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();
- for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
- {
- std::string att = it_branch->c_str();
- if(att[0] == 'D' && att[7] == '_' && att.size() == 14)
- {
- outDscp += "D ";
- outDscp += att.substr(1,6) + " "; // GR
- outDscp += att.substr(8,6) + " ";// EL
- outDscp += "3";
- outDscp += "\n";
- }
- else
- {
- outDscp += "O ";
- outDscp += it_branch->c_str();
- outDscp += " ";
- outDscp += ownatt[att];
- outDscp += " ";
- outDscp += "2";
- outDscp += "\n";
- }
- }
-
- }
- }
-
-
- ///////////////////////////////////////////////////////
- // load a descriptor //
- // @param i_name : file name to load //
- // @return : - //
- /////////////////////////////////////////////////////
- void WxDescriptorPanel::loadDescriptor(const std::string i_name)
- {
- std::ifstream i_file(i_name.c_str());
- std::stringstream buffer;
- buffer << i_file.rdbuf();
- std::string line;
- std::string level;
-
-#if defined(USE_GDCM2)
- const gdcm::Global& g = gdcm::Global::GetInstance(); // sum of all knowledge !
- const gdcm::Dicts &dicts = g.GetDicts();
- const gdcm::Dict &dict = dicts.GetPublicDict(); // Part 6
-#endif
-
-
- bool bname;
- int ilevel = -1;
-
-
- while(std::getline(buffer, line))
- {
- if(line =="<level>")
- { //increment levels.
- ilevel++;
- bname = true;
- }
- else if(bname)
- {
- // For each level, a name to describe it
- level = line;
- if(ilevel>0)
- {
- onAddLevel(level);
- }
- bname = false;
- }
- else
- {
- // split line to find all tags
- std::vector<std::string> descriptors;
- std::string separator = " ";
- std::string::size_type last_pos = line.find_first_not_of(separator);
- //find first separator
- std::string::size_type pos = line.find_first_of(separator, last_pos);
- while(std::string::npos != pos || std::string::npos != last_pos)
- {
- descriptors.push_back(line.substr(last_pos, pos - last_pos));
- last_pos = line.find_first_not_of(separator, pos);
- pos = line.find_first_of(separator, last_pos);
- }
-
- // By default, the last tag is at zero and not recorded but if take in count
- unsigned int flag = 0;
- if(descriptors.size() == 4)
- {
- std::stringstream val;
- val << std::dec << descriptors[3];
- val>> flag;
- }
-
- // if Dicom tag, use "group" and "element" descriptor
- if(descriptors[0] == "D")
- { std::stringstream val, val2;
- unsigned short group;
- unsigned short element;
- val << std::dec << descriptors[1] ;
- val >> std::hex >> group;
- val2 << std::dec << descriptors[2];
- val2 >> std::hex >> element;
- std::string compose = "D";
- compose += descriptors[1];
- compose += "_";
- compose += descriptors[2];
-#if defined(USE_GDCM)
- GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
- if(ilevel>0)
- {
- onAddAttribute( entry->GetName(),compose, level);
- }
-#endif
-
-#if defined(USE_GDCM2)
- gdcm::DictEntry dictentry = dict.GetDictEntry(gdcm::Tag(group, element));
- if(ilevel>0)
- {
- onAddAttribute( dictentry.GetName(),compose, level);
- }
-
-
-#endif
- }
- else if(descriptors[0].find("#") != -1)
- {
- // commented line continue to next line
- }
- else // "O" means if user's own tag.
- {
- boost::algorithm::replace_all(descriptors[2],"_"," ");
- if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
- {
- onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
- }
- }
- }
- }
- }
-
-//======================================================================
-
-//======================================================================
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxDescriptorPanel_h_INCLUDED__
-#define __creaImageIOWxDescriptorPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <string>
-#include <map>
-#include <vector>
-#include <creaImageIOWxGimmickView.h>
-#include <wx/listctrl.h>
-#include <wx/statline.h>
-
-
-#define ID_DESCRIPTOR 1500
-#define ID_LEVEL_CTRL ID_DESCRIPTOR+1
-#define ID_LEVEL_ADD ID_DESCRIPTOR+2
-#define ID_GR_CTRL ID_DESCRIPTOR+3
-#define ID_EL_CTRL ID_DESCRIPTOR+4
-#define ID_NAME_CTRL ID_DESCRIPTOR+5
-#define ID_ATTRIBUTE_CTRL ID_DESCRIPTOR+6
-#define ID_ATTRIBUTE_ADD ID_DESCRIPTOR+7
-#define ID_REMOVE_ADD ID_DESCRIPTOR+8
-#define ID_DSCP_APPLY ID_DESCRIPTOR+9
-
-namespace creaImageIO
-{
-
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- /// Gimmick DB are based on descriptors with a tree structure .
- /// Each level contains attributes (DICOM or other) to identify data
- /// WxDescriptorPanel allows creation, modification and save of descriptors.
- ///
-
- class WxDescriptorPanel : public wxDialog
- {
- public:
- WxDescriptorPanel();
- WxDescriptorPanel(wxWindow *parent, const std::string path);
- ~WxDescriptorPanel();
-
- // Get file to load Descriptor
- const std::string& GetDescriptor(){ return m_DscpFile;}
-
- private :
-
- // WxControls
- wxTextCtrl *LevelCtrl; //TextCtrl to enter level's name
- wxTextCtrl *GRCtrl; // TextCtrl to enter DICOM Group value
- wxTextCtrl *ELCtrl; // TextCtrl to enter DICOM element value
- wxTextCtrl *ResultCtrl; //TextCtrl to visualize Descriptor
- wxComboBox *AttributeCombo; // Combox to choose Attribute values
-
- /// Add an attribute (DICOM or own)
- void OnAddAttribute(wxCommandEvent& event);
-
- /// Add an attribute (DICOM or own)
- void onAddAttribute( const std::string &att, const std::string &name_att, std::string level = "");
-
- /// Add a Level
- void OnAddLevel(wxCommandEvent& event);
-
- /// Add a Level
- void onAddLevel(const std::string &level);
-
- /// Find a DICOM attribute from group and element values
- void OnDicomAttribute(wxCommandEvent& event);
-
- /// Remove a value (level or attribute)
- void OnRemove(wxCommandEvent& event);
-
- /// Create a new descriptor
- void OnNew(wxCommandEvent& event);
-
- /// Load an exsitant descriptor
- void OnLoad(wxCommandEvent& event);
-
- /// Save a descriptor
- void OnOK(wxCommandEvent& event);
-
- /// Save a descriptor and use it
- void OnApply(wxCommandEvent& event);
-
- /// Cancel
- void OnCancel(wxCommandEvent& event);
-
- /// Create a descriptor structure
- void CreateDescriptor(int type);
-
- /// add a level
- bool addLevel(const std::string &name);
-
- /// add an attribute
- bool addAtribute(const std::string &level, const std::string &name);
-
- /// remove an attribute
- bool RemoveAttribute(const std::string &level, const std::string &name);
-
- /// remove a level
- bool RemoveLevel(const std::string &name);
-
- /// Create a descriptor file
- void createDescriptorFile();
-
- /// load a descriptor file
- void loadDescriptor(const std::string i_name);
-
- /// find a level'name
- std::string findLevel();
-
- /// determine values for own attributes
- std::string OwnAttribute(const std::string name);
-
- /// save a descriptor in a file
- const std::string saveDescriptor();
-
- /// number of level
- int lv;
-
- /// Insert point in result control
- long InsertPt;
-
- /// Output file for Descriptor
- std::string m_DscpFile;
-
- /// Output Descriptor
- std::string outDscp;
-
- // Vector of attributes
- std::vector<std::string> VLevel;
-
- // map of level, attributes
- std::map<std::string, std::vector<std::string> > DscpTree;
-
- // map of own application attributes
- std::map<std::string, std::string> ownatt;
-
- // List of added level
- std::map<int, std::string> lvlist;
-
- // DB Gimmick path
- std::string m_path;
-
- }; // class WxDescriptorPanel
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOWxDumpPanel.h>
-#include <creaImageIOSystem.h>
-#include <creaImageIOGimmick.h>
-#if defined(USE_GDCM)
-#include <gdcmGlobal.h>
-#include <gdcmDictSet.h>
-#include "gdcmFile.h"
-#include "gdcmDocument.h"
-#include "gdcmFileHelper.h"
-#endif
-#include "icons/save.xpm"
-
-namespace creaImageIO
-{
- // CTor
- WxDumpPanel::WxDumpPanel(wxWindow *parent, std::string i_filename)
- : wxDialog(parent, -1,_T("DICOM TAGS"), wxDefaultPosition, wxSize(550,580)), filename(i_filename)
- {
- int size = 16;
- mIcon = new wxImageList(size,size,true);
- mIcon->Add(wxBitmap(wxBitmap(wxIcon(save_xpm)).ConvertToImage().Rescale(size, size)));
- wxToolBar *mToolBar = new wxToolBar(this,-1,wxDefaultPosition,wxDefaultSize);
- mToolBar->AddTool( DUMP_SAVE_ID,_T("Save"), mIcon->GetBitmap(0), _T("Save Dicom Tags in text file"));
- mToolBar->Realize();
- DumpText = new wxTextCtrl( this, wxID_ANY,_T(""), wxPoint(5,30), wxSize(520,510), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
- Layout();
- Print();
- }
-
- // DTor
- WxDumpPanel::~WxDumpPanel(){}
-
- ///////////////////////////////////////////////////
- /// Display in a control Text all dicom tags
- ///////////////////////////////////////////////////
- void WxDumpPanel::Print()
- {
- std::stringstream os;
- if ( !filename.empty()) // ====== Deal with a single file ======
- {
- /* GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New();
- f->SetLoadMode(GDCM_NAME_SPACE::LD_ALL);
- f->SetFileName( filename );
- f->SetMaxSizeLoadEntry(0xffff);
- f->Load();
- GDCM_NAME_SPACE::FileHelper *fh = GDCM_NAME_SPACE::FileHelper::New(f);
- f->SetLoadMode(GDCM_NAME_SPACE::LD_NOSEQ |GDCM_NAME_SPACE::LD_NOSHADOW);
- fh->SetPrintLevel( 0 );
- fh->Print(os);
- std::string result;
- std::string line;
- while(std::getline(os, line))
- {
- result +=clean(line.c_str());
- result += "\n";
- }
- DumpText->SetValue(crea::std2wx(result));
-
- std::string pixelType =f->GetPixelType();
- int nX,nY,nZ,nT,sPP,planarConfig;
-
- nX=f->GetXSize();
- nY=f->GetYSize();
- nZ=f->GetZSize();
- nT=f->GetTSize();*/
- }
- }
-
-
- const std::string WxDumpPanel::clean(const std::string &i_line)
- {
-
- if (i_line.substr(4,1) == "|")
- {
- std::string tag;
- std::string line;
- std:string signification;
- std::string value;
- std::string resultat;
-
- tag = "(" + i_line.substr(0,9) + ")";
- line = i_line.substr(14,i_line.size()-10);
- int pos1 = line.find_first_of("[");
- int pos2 = line.find_first_of("]");
- signification = line.substr(pos1+1, pos2-pos1-1);
- line = line.substr(pos2+1);
- pos1 = line.find_first_of("[");
- pos2 = line.find_first_of("]");
- value = line.substr(pos1+1, pos2-pos1-1);
- resultat = tag + " " + signification + ": " +value;
- return resultat;
- }
- else
- {
- return i_line;
- }
- }
-
-///////////////////////////////////////////////////
-/// wxEvent to save Dicom Tags in a text file //
-///////////////////////////////////////////////////
- void WxDumpPanel::SaveInfos(wxCommandEvent& event)
- {
- wxFileDialog* FD = new wxFileDialog( 0,_T("Select file"), _T(""), _T(""),
- crea::std2wx("*.txt"), wxOPEN, wxDefaultPosition);
- if (FD->ShowModal()==wxID_OK)
- {
- wxBusyCursor busy;
- std::ofstream ofs(crea::wx2std(FD->GetPath()).c_str());
- ofs.clear();
- ofs << crea::wx2std(DumpText->GetValue());;
- ofs.close();
- }
- Close();
- }
-
-////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////
-BEGIN_EVENT_TABLE(WxDumpPanel, wxDialog)
- EVT_TOOL(DUMP_SAVE_ID, WxDumpPanel::SaveInfos)
-END_EVENT_TABLE()
-}
-
+++ /dev/null
-#ifndef __creaImageIOWxDumpPanel_h_INCLUDED__
-#define __creaImageIOWxDumpPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <creaImageIOWxGimmickView.h>
-
-#define DUMP_SAVE_ID 1800
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- /// Display all dicom tags from a given DICOM file
- class WxDumpPanel : public wxDialog
- {
- public:
-
- /// Constructor
- WxDumpPanel(wxWindow *parent, std::string i_filename);
-
- /// Destructor
- ~WxDumpPanel();
-
-
- private :
-
- const std::string clean(const std::string &i_line);
- /// Display in a control Text all dicom tags
- void Print();
-
- /// wxEvent to save Dicom Tags in a text file
- void SaveInfos(wxCommandEvent& event);
-
- /// Parent DialogBox
- wxDialog* dialog;
-
- /// Icons list
- wxImageList *mIcon;
-
- /// ControlText to display tags
- wxTextCtrl *DumpText;
-
- /// Dicom file to display
- std::string filename;
-
- DECLARE_EVENT_TABLE()
-
- }; // class WxEditFieldsPanel
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOWxEditFieldsPanel.h>
-#include <creaImageIOSystem.h>
-#include <wx/arrstr.h>
-
-//using namespace tree;
-namespace creaImageIO
-{
- const int ID_COMBO = 140;
- // CTor
- WxEditFieldsPanel::WxEditFieldsPanel(wxWindow *parent, wxDialog* dial, WxGimmickView* view, tree::Node* nod,
- const std::vector<std::string> name,
- const std::vector<std::string> key)
- : wxPanel( parent,
- -1, wxDefaultPosition,
- wxDefaultSize,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- dialog(dial),
- node (nod),
- names(name),
- keys(key),
- mView(view)
- {
- GimmickDebugMessage(1,"WxCustomizeConfigPanel::WxCustomizeConfigPanel"
- <<std::endl);
- wxStaticText * cp=new wxStaticText(this,-1,_T(" Attribute to change: "), wxPoint(5,10));
- wxArrayString as;
- std::vector<std::string>::const_iterator it;
- for(it=names.begin();it!=names.end();++it)
- {
- as.Add(crea::std2wx(*it));
- }
- attributes=new wxComboBox(this, ID_COMBO, crea::std2wx(names.front()), wxPoint(110, 10), wxDefaultSize,as);
- std::string val=node->GetAttribute(keys[0]);
- if(val.compare("")==0){val="?";}
-
- wxStaticText * av=new wxStaticText(this,-1,_T(" Current Value: "), wxPoint(5,40));
- actualVal=new wxStaticText(this,-1,crea::std2wx(val), wxPoint(110,40));
-
- wxStaticText * nv=new wxStaticText(this,-1,_T(" New Value: "), wxPoint(5,70));
- newVal=new wxTextCtrl(this, wxID_ANY, crea::std2wx(val), wxPoint(110,70), wxSize(220,20));
-
- wxButton *save = new wxButton(this,wxID_ANY,_T("Save Changes"), wxPoint(5,100) );
- Connect( save->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxEditFieldsPanel::OnEdit );
-
- Layout();
- }
-
- /// Destructor
- WxEditFieldsPanel::~WxEditFieldsPanel()
- {
- GimmickDebugMessage(1,"WxEditFieldsPanel::~WxEditFieldsPanel"
- <<std::endl);
- }
-
- void WxEditFieldsPanel::OnEdit(wxCommandEvent& event)
- {
- std::string val=crea::wx2std(newVal->GetValue());
- int sel=attributes->GetSelection();
- if(sel==-1)
- {
- sel=0;
- }
- mView->OnFieldsEdited(node,names[sel],keys[sel],val);
- dialog->Destroy();
- }
-
- void WxEditFieldsPanel::OnComboChange(wxCommandEvent& event)
- {
- std::string val=node->GetAttribute(keys[attributes->GetSelection()]);
- if(val.compare("")==0){val="?";}
- actualVal->SetLabel(crea::std2wx(val));
- newVal->SetValue(crea::std2wx(val));
- }
-
-//======================================================================
-BEGIN_EVENT_TABLE(WxEditFieldsPanel, wxPanel)
-EVT_COMBOBOX (ID_COMBO,WxEditFieldsPanel::OnComboChange)
-END_EVENT_TABLE()
-//======================================================================
-
-} // EO namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOWxEditFieldsPanel_h_INCLUDED__
-#define __creaImageIOWxEditFieldsPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <creaImageIOWxGimmickView.h>
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- class WxEditFieldsPanel : public wxPanel
- {
- public:
- WxEditFieldsPanel();
- WxEditFieldsPanel(wxWindow *parent,
- wxDialog* dial,
- WxGimmickView* view,
- tree::Node* nod,
- const std::vector<std::string> name,
- const std::vector<std::string> key);
-
- ~WxEditFieldsPanel();
- ///Saves the configuration
- void OnEdit(wxCommandEvent& event);
- void OnComboChange(wxCommandEvent& event);
-
- private :
- tree::Node* node;
- std::vector<std::string> names;
- std::vector<std::string> keys;
- wxDialog* dialog;
- WxGimmickView* mView;
- wxComboBox* attributes;
- wxStaticText * actualVal;
- wxTextCtrl* newVal;
-
- DECLARE_EVENT_TABLE()
-
-
- }; // class WxEditFieldsPanel
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
-
+++ /dev/null
-#include <creaImageIOWxExportDlg.h>
-
-namespace creaImageIO
-{
- // CTor
- WxExportDlg::WxExportDlg(wxWindow *parent, const std::vector<std::string> storages)
- : wxDialog(parent, -1,_T("EXPORT FILES TO STORAGE"), wxDefaultPosition, wxSize(260,150))
- {
- int size = 16;
-
- wxStaticText * ExportText=new wxStaticText(this,-1,_T(" Storage to export: "), wxPoint(5,10));
- wxArrayString names;
- std::vector<std::string>::const_iterator it = storages.begin();
- for(;it != storages.end(); it++)
- {
- names.Add(crea::std2wx(*it));
- }
- ExportCombo = new wxComboBox(this, ID_EXPORTCOMBO_CTRL,_T(""),wxPoint(120,10), wxSize(120,25),names);
- ExportCombo->SetSelection(0);
- // Connect( ExportCombo->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
-
- // VALIDATION BUTTON
- wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(5,50) );
- Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxExportDlg::OnOk );
-
- wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(100,50) );
- Layout();
-
- }
-
- WxExportDlg::~WxExportDlg(){}
-
- void WxExportDlg::OnOk(wxCommandEvent &event)
- {
- m_name = crea::wx2std(ExportCombo->GetValue());
- Close();
- SetReturnCode(ID_EXPORT_OK);
- }
-}
+++ /dev/null
-#ifndef __creaImageIOWxExportDlg_h_INCLUDED__
-#define __creaImageIOWxExportDlg_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <creaImageIOWxGimmickView.h>
-
-#define ID_EXPORTCOMBO_CTRL 1801
-#define ID_EXPORT_OK 1802
-
-namespace creaImageIO{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- /// Gimmick can handle multiple database with different organisations.
- /// WxDescriptorPanel allows to select the storage to export data.
- ///
- class WxExportDlg : public wxDialog
- {
- public:
- ///CTor
- WxExportDlg(wxWindow *parent, const std::vector<std::string> storages);
- ///DTor
- ~WxExportDlg();
-
- /// Get selected storage
- const std::string& GetStorage(){ return m_name;}
-
- private:
-
- /// Storage ComboBox
- wxComboBox *ExportCombo;
-
- ///Validate selected storage
- void OnOk(wxCommandEvent &event);
-
- /// Storage name
- std::string m_name;
- };
-}
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOWxGimmickFrame.h>
-#include <creaImageIOSystem.h>
-
-namespace creaImageIO
-{
- // CTor
- WxGimmickFrame::WxGimmickFrame(wxWindow *parent,
- wxWindowID id,
- wxString title,
- const wxPoint& pos,
- const wxSize& size,
- int threads)
- : wxFrame( parent,
- id,
- title,
- pos,
- size,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- // mGimmick(0),
- mView(0)
- {
- GimmickDebugMessage(1,"WxGimmickFrame::WxGimmickFrame"
- <<std::endl);
- wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
-
- try {
-
-// mGimmick = boost::shared_ptr<Gimmick>(new Gimmick());
- mGimmick->Initialize();
-
- int min_dim = GIMMICK_2D_IMAGE_SELECTION;
- int max_dim = GIMMICK_3D_IMAGE_SELECTION;
- mView = new WxGimmickView(mGimmick,
- this,
- -1,
- wxDefaultPosition,
- size,
- min_dim,
- max_dim,
- threads);
- mView->Initialize();
- }
- catch (crea::Exception e)
- {
- e.Print();
- return;
- }
-
- topsizer->Add( mView,1,wxGROW,0);
-
- SetSizer( topsizer );
- Layout();
- }
-
- /// Destructor
- WxGimmickFrame::~WxGimmickFrame()
- {
- GimmickDebugMessage(1,"WxGimmickFrame::~WxGimmickFrame"
- <<std::endl);
- if (mView)
- {
- delete mView;
- }
- if (mGimmick)
- {
- mGimmick->Finalize();
-// delete mGimmick;
- }
- }
-
-
- //================================================================
- // BEGIN_EVENT_TABLE(WxGimmickFrame, wxDialog)
- // END_EVENT_TABLE()
- //================================================================
-
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxGimmickFrame_h_INCLUDED__
-#define __creaImageIOWxGimmickFrame_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-
-#include <creaImageIOWxGimmickView.h>
-#include <creaWx.h>
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- class CREAIMAGEIO_EXPORT WxGimmickFrame : public wxFrame
- {
- public:
- WxGimmickFrame();
- WxGimmickFrame(wxWindow *parent,
- const wxWindowID id,
- wxString title,
- const wxPoint& pos,
- const wxSize& size,
- int threads = 0);
-
- ~WxGimmickFrame();
-
- // Gimmick* GetGimmick() { return mGimmick; }
- // typedef WxGimmick ViewType;
- // typedef WxGimmickView::EventType EventType;
-
-
-
-
- // void OnSelChanged(EventType& event);
- // void OnContextualMenu(EventType& event);
- // void OnMenuTest(wxCommandEvent& event);
- // void OnButtonOk(wxCommandEvent& event);
- // void OnButtonCancel(wxCommandEvent& event);
-
- // DECLARE_EVENT_TABLE();
- private :
-
- boost::shared_ptr<Gimmick> mGimmick;
- WxGimmickView* mView;
-
- }; // class WxGimmickFrame
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOWxGimmickPanel.h>
-#include <creaImageIOSystem.h>
-
-namespace creaImageIO
-{
- // CTor
- WxGimmickPanel::WxGimmickPanel(wxWindow *parent,
- wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- const std::string i_namedescp ,
- const std::string i_namedb ,
- int threads)
- : wxPanel( parent,
- id,
- pos,
- size,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- //mGimmick(0),
- mView(0)
- {
- GimmickDebugMessage(1,"WxGimmickPanel::WxGimmickPanel"
- <<std::endl);
- wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
-
- try {
-
- mGimmick = boost::shared_ptr<Gimmick>(new Gimmick());
- mGimmick->Initialize(i_namedescp,i_namedb);
- int min_dim = GIMMICK_2D_IMAGE_SELECTION;
- int max_dim = GIMMICK_3D_IMAGE_SELECTION;
- mView = new WxGimmickView(mGimmick,
- this,
- -1,
- wxDefaultPosition,
- size,
- min_dim,
- max_dim,
- threads);
- mView->Initialize();
- // Connect the AddProgress callback
- mView->ConnectValidationObserver ( boost::bind( &WxGimmickPanel::OnSelectedImage , this, _1 ) );
- }
- catch (crea::Exception e)
- {
- e.Print();
- return;
- }
-
- topsizer->Add( mView,1,wxGROW,0);
-
- SetSizer( topsizer );
- Layout();
- }
-
- /// Destructor
- WxGimmickPanel::~WxGimmickPanel()
- {
- GimmickDebugMessage(1,"WxGimmickPanel::~WxGimmickPanel"
- <<std::endl);
- if (mView)
- {
- delete mView;
- }
- if (mGimmick)
- {
- mGimmick->Finalize();
- }
- }
-
-//======================================================================
-
-//======================================================================
-
- ///Callback method on a selection
- void WxGimmickPanel::OnSelectedImage(bool t)
- {
- mSendImageSignal(t);
- }
-
- void WxGimmickPanel::AddImagesToDB(std::string dir)
- {
- mView->AddDir(dir);
- }
-
- //================================================================
- // BEGIN_EVENT_TABLE(WxGimmickPanel, wxDialog)
- // END_EVENT_TABLE()
- //================================================================
-
-
- //====================================================================
-
- //====================================================================
- void WxGimmickPanel::ConnectSendImageObserver(SendImageCallbackType callback)
- {
- mSendImageSignal.connect(callback);
- }
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxGimmickPanel_h_INCLUDED__
-#define __creaImageIOWxGimmickPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-
-// Signal/slot mechanism for progress events
-#include <boost/signal.hpp>
-#include <boost/bind.hpp>
-
-#include <creaImageIOWxGimmickView.h>
-#include <creaWx.h>
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- class CREAIMAGEIO_EXPORT WxGimmickPanel : public wxPanel
- {
- public:
- WxGimmickPanel();
- WxGimmickPanel(wxWindow *parent,
- const wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- const std::string i_namedescp ,
- const std::string i_namedb = "Local Database",
- int threads = 0);
-
- ~WxGimmickPanel();
-
- //=============================================
- typedef boost::signal<void (bool)> SendImageSignalType;
- typedef SendImageSignalType::slot_function_type SendImageCallbackType;
- //=============================================
-
- //==================================================================
- /// Adds the function f to the list of functions to call
- /// when the addition progresses.
- /// f is of type ProgressCallbackType which is:
- /// void (*ProgressCallbackType)(Progress&)
- /// To pass a member function 'f' of an instance 'c' of a class 'C'
- /// as callback you have to 'bind' it, i.e. call:
- /// ConnectSendImageObserver ( boost::bind( &C::f , c, _1 ) );
- void ConnectSendImageObserver(SendImageCallbackType callback);
- //==================================================================
-
- //===============================================================================================
- //Image Selection
- //===============================================================================================
-
- void GetSelectedImages(std::vector<vtkImageData*>& s, int dim)
- {
- mView->GetSelectedImages(s, dim);
- }
-
- void GetSelectedImagesInVector(std::vector<vtkImageData*>& s, int dim)
- {
- mView->GetSelectedImagesInVector(s, dim);
- }
-
- void OnSelectedImage(bool t);
-
- void AddImagesToDB(std::string dir);
-
- // DECLARE_EVENT_TABLE();
- private :
-
- boost::shared_ptr<Gimmick> mGimmick;
- WxGimmickView* mView;
-
- ///The sendImage signal
- SendImageSignalType mSendImageSignal;
-
- }; // class WxGimmickPanel
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOWxGimmickReaderDialog.h>
-#include <creaImageIOSystem.h>
-#include <creaImageIOGimmick.h>
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-namespace creaImageIO
-{
- // CTor
- WxGimmickReaderDialog::WxGimmickReaderDialog(wxWindow *parent,
- wxWindowID id,
- const std::string i_namedescp,
- const std::string i_namedb,
- wxString title,
- const wxPoint& pos,
- const wxSize& size,
- int min_dim,
- int max_dim,
- int output_dim, // never used ?!? // JPR
- int threads)
- : wxDialog( parent,
- id,
- title,
- pos,
- size,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- // mGimmick(0),
- mView(0)
- {
- GimmickDebugMessage(1,"WxGimmickReaderDialog::WxGimmickReaderDialog"
- <<std::endl);
- mtopsizer = new wxBoxSizer(wxVERTICAL);
-
- try {
-
- mGimmick = boost::shared_ptr<Gimmick>(new Gimmick());
- mGimmick->Initialize(i_namedescp,i_namedb);
-
- mView = new WxGimmickView(mGimmick,
- this,
- TVID,
- wxDefaultPosition,
- size,
- min_dim,
- max_dim,
- threads);
- mView->Initialize();
- // Connect the AddProgress callback
- mView->ConnectValidationObserver
- ( boost::bind( &WxGimmickReaderDialog::OnValid , this, _1 ) );
- }
- catch (crea::Exception e)
- {
- e.Print();
- return;
- }
-
- mtopsizer->Add( mView,1,wxGROW,0);
-
- wxSizer* bsizer = this->CreateSeparatedButtonSizer(wxOK|wxCANCEL);
- /*mOkButton = new wxButton(this, wxID_OK, _T("OK"), wxPoint(170,50));
- mCancelButton = new wxButton(this, wxID_CANCEL, _T("CANCEL"), wxPoint(210,50));
- */ mOkButton = (wxButton*)FindWindowById(GetAffirmativeId(), this);
- mCancelButton = (wxButton*)FindWindowById(GetEscapeId(), this);
-
- mOkButton->Enable(false);
- mtopsizer->Add ( bsizer, 0, wxGROW );
-
- SetSizer( mtopsizer );
-
- Layout();
- }
-
- /// Destructor
- WxGimmickReaderDialog::~WxGimmickReaderDialog()
- {
- GimmickDebugMessage(1,"WxGimmickReaderDialog::~WxGimmickReaderDialog"
- <<std::endl);
- if (mView)
- {
- delete mView;
- }
- if (mGimmick)
- {
- mGimmick->Finalize();
- }
- deleteMessage();
- }
-
-void WxGimmickReaderDialog::deleteMessage()
- {
- deleteGimmickDebugMessage();
- };
- ///Callback method on a selection
- void WxGimmickReaderDialog::OnValid(bool t)
- {
- mOkButton->Enable(t);
- }
-
- //================================================================
- //BEGIN_EVENT_TABLE(WxGimmickReaderDialog, wxDialog)
- //END_EVENT_TABLE()
- //================================================================
-
-} // EO namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOWxGimmickReaderDialog_h_INCLUDED__
-#define __creaImageIOWxGimmickReaderDialog_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-
-#include <creaImageIOWxGimmickView.h>
-#include "creaImageIOSystem.h"
-#include <creaWx.h>
-#include "wx/wx.h"
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
-
- //=====================================================================
- //=====================================================================
- class CREAIMAGEIO_EXPORT WxGimmickReaderDialog : public wxDialog
- {
- public:
- WxGimmickReaderDialog();
- WxGimmickReaderDialog(wxWindow *parent,
- const wxWindowID id,
- const std::string i_namedescp ,
- const std::string i_namedb ,
- wxString title,
- const wxPoint& pos,
- const wxSize& size,
- int image_min_dim = GIMMICK_2D_IMAGE_SELECTION,
- int image_max_dim = GIMMICK_3D_IMAGE_SELECTION,
- int output_dim = NATIVE,
- int threads = 0);
-
- boost::shared_ptr<Gimmick> GetGimmick() { return mGimmick; }
- // typedef WxGimmick ViewType;
- typedef WxGimmickView::EventType EventType;
-
- ~WxGimmickReaderDialog();
-
- //===============================================================================================
- //Image Selection
- //===============================================================================================
-
- void GetSelectedImages(std::vector<vtkImageData*>& s, int dim)
- { mView->GetSelectedImages(s, dim); }
-
- void GetSelectedImagesInVector(std::vector<vtkImageData*>& s, int dim)
- { mView->GetSelectedImagesInVector(s, dim); }
-
- void GetSelectedFiles(std::vector<std::string>& s)
- { mView->GetSelectedFiles(s); }
-
- void OnSelChanged(EventType& event);
- void OnContextualMenu(EventType& event);
- void OnMenuTest(wxCommandEvent& event);
- void OnValid(bool valid);
- void OnExit(){ mView->StopPlayer(); }
- void deleteMessage();
- // void OnButtonOk(wxCommandEvent& event);
- // void OnButtonCancel(wxCommandEvent& event);
-
- private :
-
- boost::shared_ptr<Gimmick> mGimmick;
- WxGimmickView* mView;
-
- wxButton* mOkButton;
- wxButton* mCancelButton;
- wxBoxSizer *mtopsizer;
-
- enum
- {
- TVID = 1
- // OKID = 2,
- // CANCELID = 3
- };
-
- }; // class WxGimmickReaderDialog
- //=====================================================================
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOWxGimmickTools.h>
-
-
-namespace creaImageIO
-{
- /**
- ** Begin of the threshold panel
- **/
- WxGimmickTools::WxGimmickTools(wxWindow* parent, wxString mCurrentDirectory)
- : wxPanel(parent, -1, wxDefaultPosition, wxSize(300,250), wxBORDER_SUNKEN)
- {
- _currentDir = mCurrentDirectory;
- _addFiles = true;
- _mhd = false;
-
- _inputPath = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition, wxSize(400,30));
- _outputPath = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition, wxSize(400,30));
- _addCheckBox = new wxCheckBox(this, -1, _T("Add Images to Database?") );
- _mhdCheckBox = new wxCheckBox(this, -1, _T("Convert to MHD?") );
- _addCheckBox->SetValue(_addFiles);
- _mhdCheckBox->SetValue(_mhd);
-
- wxButton *inputDir = new wxButton(this, wxID_ANY,_T("Input Directory"), wxDefaultPosition, wxSize(140,30) );
- wxButton *outputDir = new wxButton(this, wxID_ANY,_T("Output Directory"), wxDefaultPosition, wxSize(140,30) );
-
- Connect( inputDir->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxGimmickTools::onInputDir );
- Connect( outputDir->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxGimmickTools::onOutputDir );
- Connect( _addCheckBox->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, (wxObjectEventFunction) &WxGimmickTools::onAddToDatabase );
- Connect( _mhdCheckBox->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, (wxObjectEventFunction) &WxGimmickTools::onMHD );
-
- wxFlexGridSizer *textSizer = new wxFlexGridSizer(1,2);
- textSizer->Add( new wxStaticText(this, -1, _T("Transform a Bruker image into Dicom / MHD format.")), 1, wxGROW );
- textSizer->Add( new wxStaticText(this, -1, _T("If checkbox is selected images will be loaded into the DB.")), 1, wxGROW );
-
- wxFlexGridSizer *sizer = new wxFlexGridSizer(2,5);
- sizer->Add( new wxStaticText(this, -1, _T(" ")), 1, wxGROW );
- sizer->Add( new wxStaticText(this, -1, _T(" ")), 1, wxGROW );
- sizer->Add( _inputPath, 1, wxGROW );
- sizer->Add( inputDir, 1, wxGROW );
- sizer->Add( _outputPath, 1, wxGROW );
- sizer->Add( outputDir, 1, wxGROW );
- sizer->Add( new wxStaticText(this, -1, _T(" ")), 1, wxGROW );
- sizer->Add( new wxStaticText(this, -1, _T(" ")), 1, wxGROW );
- sizer->Add( _addCheckBox, 1, wxGROW );
- sizer->Add( _mhdCheckBox, 1, wxGROW );
-
- wxFlexGridSizer *topSizer = new wxFlexGridSizer(1, 2);
- topSizer->Add( textSizer, 1, wxGROW );
- topSizer->Add( sizer, 1, wxGROW );
- this->SetSizer( topSizer );
- this->SetAutoLayout( true );
- this->Layout();
- }
-
- WxGimmickTools::~WxGimmickTools()
- {
-
- }
-
- wxString WxGimmickTools::getInputDir()
- {
- return _inputPath->GetValue();
- }
-
- wxString WxGimmickTools::getOutputDir()
- {
- return _outputPath->GetValue();
- }
-
- bool WxGimmickTools::getAddToDBCheckBoxValue()
- {
- return _addCheckBox->GetValue();
- }
-
- bool WxGimmickTools::getMHDCheckBoxValue()
- {
- return _mhdCheckBox->GetValue();
- }
-
- void WxGimmickTools::onInputDir(wxCommandEvent& event)
- {
- long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
- wxDirDialog* FD = new wxDirDialog( 0, _T("Select the Input Directory"), _currentDir, style);
-
- if (FD->ShowModal()==wxID_OK)
- {
- _inputPath->SetValue(FD->GetPath());
- }
- }
-
- void WxGimmickTools::onOutputDir(wxCommandEvent& event)
- {
- long style = wxDD_DEFAULT_STYLE;
- wxDirDialog* FD = new wxDirDialog( 0, _T("Select the Output Directory"), _currentDir, style);
-
- if (FD->ShowModal()==wxID_OK)
- {
- _outputPath->SetValue(FD->GetPath());
- }
- }
-
- void WxGimmickTools::onAddToDatabase(wxCommandEvent& event)
- {
- _addFiles = _addCheckBox->GetValue();
- }
-
- void WxGimmickTools::onMHD(wxCommandEvent& event)
- {
- _mhd = _mhdCheckBox->GetValue();
- }
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxGimmickTools_h_INCLUDED__
-#define __creaImageIOWxGimmickTools_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-
-#include <creaWx.h>
-
-namespace creaImageIO
-{
- /**
- * \ingroup Tools
- */
- //=====================================================================
-
- //=====================================================================
-
- class WxGimmickTools : public wxPanel
- {
- public:
- WxGimmickTools(wxWindow *parent, wxString mCurrentDirectory);
- ~WxGimmickTools();
-
- wxString getInputDir();
- wxString getOutputDir();
- bool getAddToDBCheckBoxValue();
- bool getMHDCheckBoxValue();
- private:
- wxCheckBox * _addCheckBox;
- wxCheckBox * _mhdCheckBox;
- wxTextCtrl * _inputPath;
- wxTextCtrl * _outputPath;
- wxString _currentDir;
- bool _addFiles;
- bool _mhd;
- void onInputDir(wxCommandEvent& event);
- void onOutputDir(wxCommandEvent& event);
- void onAddToDatabase(wxCommandEvent& event);
- void onMHD(wxCommandEvent& event);
- };
-
-} // EO namespace creaImageIO
-
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOPACSConnection.h>
-#include <creaImageIOWxPACSConnectionPanel.h>
-#include <creaImageIOWxGimmickView.h>
-#include <creaImageIOWxTreeView.h>
-#include <creaImageIOSystem.h>
-#include <creaImageIOWxCustomizeConfigPanel.h>
-#include <creaImageIOWxListenerPanel.h>
-#include <creaImageIOWxEditFieldsPanel.h>
-#include <creaImageIOWxAttributeSelectionPanel.h>
-#include <creaImageIOWxDescriptorPanel.h>
-#include <creaImageIOWxDumpPanel.h>
-#include <creaImageIOWxExportDlg.h>
-
-using namespace crea;
-// Icons
-#include "icons/accept.xpm"
-#include "icons/add.xpm"
-#include "icons/folder-down.xpm"
-#include "icons/page-down.xpm"
-#include "icons/remove.xpm"
-#include "icons/database-add.xpm"
-#include "icons/create-database.xpm"
-#include "icons/help.xpm"
-#include "icons/synchronize.xpm"
-#include "icons/settings.xpm"
-#include "icons/tools.xpm"
-//#include "icons/import.xpm"
-
-#include <wx/imaglist.h>
-#include <wx/popupwin.h>
-#include<boost/filesystem/operations.hpp>
-#if defined(BUILD_BRUKER)
- #include "bruker2dicom.h"
-#endif
-
-
-#include <creaImageIOGimmick.h>
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-
-namespace creaImageIO
-{
-
- //======================================================================
- // The ids of the different tools
- enum
- {
- TOOL_ADDFILES_ID = 1,
- TOOL_ADDDIR_ID = 2,
- TOOL_ADDDATABASE_ID = 3,
- TOOL_REMOVE_ID = 4,
- TOOL_SYNCHRONIZE_ID = 5,
- TOOL_HELP_ID = 6,
- TOOL_SETTINGS_ID = 7,
- TOOL_TOOLS_ID = 8,
- TOOL_CREATEDB_ID = 9,
- TOOL_PACS_ID = 10
- };
- //======================================================================
-
- //================================================================
- //
- const int icon_number = 11;
- // Icon ids
- typedef enum
- {
- Icon_create_database,
- Icon_accept,
- Icon_add,
- Icon_folder_down,
- Icon_page_down,
- Icon_database_add,
- Icon_remove,
- Icon_synchronize,
- Icon_help,
- Icon_settings,
- Icon_tools
- }
- icon_id;
- //================================================================
-
- //================================================================
- /*
- const icon_id Icon[5] = { Icon_Database,
- Icon_Patient,
- Icon_Study,
- Icon_Series,
- Icon_Image };
- */
- //================================================================
-
-
- //======================================================================
- // CTor
- WxGimmickView::WxGimmickView(boost::shared_ptr<Gimmick> gimmick,
- wxWindow *parent,
- const wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- int min_dim,
- int max_dim,
- int number_of_threads)
- : wxPanel(parent,id,pos,size),
- GimmickView(gimmick, number_of_threads),
- mProgressDialog(0),
- mConstructed(false)
- {
- GimmickDebugMessage(1,"WxGimmickView::WxGimmickView"
- <<std::endl);
- // Sets the current directory to the home dir
- mCurrentDirectory = std2wx(gimmick->GetHomeDirectory());
-
- // Connect the AddProgress callback
- gimmick->ConnectAddProgressObserver
- ( boost::bind( &WxGimmickView::OnAddProgress , this, _1 ) );
-
- // Create the list of icons (mIcon)
- CreateIconList();
-
- // Global sizer
- msizer = new wxBoxSizer(wxVERTICAL);
-
- // Create the tool bar
- CreateToolBar();
- msizer->Add( mToolBar, 0, wxGROW, 0);
-
- // Split part below toolbar into notebook for views and panel
- // for preview, messages...
- mSplitter = new wxSplitterWindow( this , -1);
-
- // Notebook
- mNotebook = new wxNotebook(mSplitter,
- -1, wxDefaultPosition, wxDefaultSize, 0);
-
- //Gimmick
- mGimmick=gimmick;
-
- mSelectionMaxDimension = max_dim;
- mSelectionMinDimension = min_dim;
-
- // Create the views
- CreateTreeViews();
-
- // Bottom panel
- mBottomPanel = new wxPanel(mSplitter,-1);
-
- mbottom_sizer = new wxBoxSizer(wxVERTICAL); //HORIZONTAL);
-
-
- // Previewer
- mViewer = new WxViewer(mBottomPanel, wxID_ANY, wxT("Gimmick! Viewer"),wxDefaultPosition, wxDefaultSize );
- //pointers.push_back(new ImagePointerHolder(GetDefaultImage())
- pointers.push_back(boost::shared_ptr<creaImageIO::ImagePointerHolder>(new ImagePointerHolder(GetDefaultImage())));
-
- mViewer->SetImageVector(pointers);
- mViewer->StartPlayer();
-
-
- mbottom_sizer->Add(mViewer,1,wxGROW,1);
- // mViewer->Show();
-
- mText = new wxStaticText(mBottomPanel, wxID_ANY, wxT("Welcome to Gimmick!"));
- mbottom_sizer->Add(mText,0,wxGROW,0);
-
-
-
- mBottomPanel->SetSizer(mbottom_sizer);
-
- // Splitting
- int hsize = size.GetHeight();
-
- int top_minsize = 450;
- int bottom_minsize = 50;
-
- mSplitter->SetMinimumPaneSize( bottom_minsize );
- mSplitter->SplitHorizontally( mNotebook, mBottomPanel,
- top_minsize);
-
- msizer->Add( mSplitter, 1, wxGROW, 0);
-
- mProgressDialog=0;
- SetSizer( msizer );
- SetAutoLayout(true);
- Layout();
- //mListener=new Listener();
- //mListener->ConnectObserver(boost::bind( &WxGimmickView::OnDriveMount, this, _1 ) );
- //mListener->Create();
- // mListener->Run();
- // mListener->Pause();
-
- mConstructed = true;
- }
- //======================================================================
-
- //======================================================================
- /// Destructor
- WxGimmickView::~WxGimmickView()
- {
- // stop the viewer before application exit.
- mViewer->StopPlayer();
- GimmickDebugMessage(1,"WxGimmickView::~WxGimmickView"
- <<std::endl);
- delete mIcon;
- delete mViewer;
- //if(mListener->IsAlive()) { mListener->Delete(); }
- }
- //======================================================================
-
- //======================================================================
- /// Creates the tool bar
- void WxGimmickView::CreateToolBar()
- {
- long style = wxTB_HORIZONTAL | wxNO_BORDER | wxTB_TEXT;
- mToolBar = new wxToolBar(this,-1,wxDefaultPosition,wxDefaultSize,
- style);
-
- mToolAddFile = mToolBar->AddTool( TOOL_ADDFILES_ID,
- _T("Add file(s)"),
- mIcon->GetBitmap(Icon_page_down),
- _T("Add one or more file to database")
- );
- mToolAddDir = mToolBar->AddTool( TOOL_ADDDIR_ID,
- _T("Add folder"),
- mIcon->GetBitmap(Icon_folder_down),
- _T("Add the content of a folder to database")
- );
- mToolAddDatabase = mToolBar->AddTool( TOOL_ADDDATABASE_ID,
- _T("Open database"),
- mIcon->GetBitmap(Icon_database_add),
- _T("Open a local or distant database")
- );
- mToolRemove = mToolBar->AddTool( TOOL_REMOVE_ID,
- _T("Remove"),
- mIcon->GetBitmap(Icon_remove),
- _T("Remove selected items")
- );
- mToolSynchronize = mToolBar->AddTool( TOOL_SYNCHRONIZE_ID,
- _T("Synchronize"),
- mIcon->GetBitmap(Icon_synchronize),
- _T("Synchronizes the database with disk")
- );
- mToolHelp = mToolBar->AddTool( TOOL_HELP_ID,
- _T("Help"),
- mIcon->GetBitmap(Icon_help),
- _T("Open help window")
- );
- mToolSettings = mToolBar->AddTool( TOOL_SETTINGS_ID,
- _T("System settings"),
- mIcon->GetBitmap(Icon_settings),
- _T("Allows the modification of various system settings")
- );
- mToolTools = mToolBar->AddTool( TOOL_TOOLS_ID,
- _T("Tools"),
- mIcon->GetBitmap(Icon_tools),
- _T("Applies tools to images")
- );
- mToolAddFile = mToolBar->AddTool( TOOL_CREATEDB_ID,
- _T("Create database"),
- mIcon->GetBitmap(Icon_create_database),
- _T("Create DB from an Attributes Descriptor file")
- );
-#if defined(BUILD_PACS)
- mToolAddFile = mToolBar->AddTool( TOOL_PACS_ID,
- _T("PACS Connection,"),
- mIcon->GetBitmap(Icon_create_database),
- _T("Echo, Find and Get to a PACS")
- );
-#endif
- //const wxBitmap& bitmap1, const wxString& shortHelpString = "", wxItemKind kind = wxITEM_NORMAL)
-
- mToolBar->Realize();
- }
- //======================================================================
-
-
- //======================================================================
- /// Create the tree view for TreeHandler provided
- void WxGimmickView::CreateTreeView( TreeHandler* h)
- {
- std::string name(h->GetTree().GetAttribute("Name"));
- GimmickMessage(2,"Creating the tree view for '"<<
- name<<"'"<<std::endl);
- // Create the WxTreeView
- WxTreeView* view = new WxTreeView(h, this, mNotebook, -1);
-
- // TO DO : TEST THAT A VIEW WITH SAME NAME IS NOT
- // ALREADY IN THE MAP
- GetTreeViewMap()[name] = view;
-
- // Add Notebook page
- mNotebook->AddPage( view, crea::std2wx(name) );
-
- }
-
- //======================================================================
- void WxGimmickView::GetSelectedImages(std::vector<vtkImageData*>& s, int dim)
- {
- std::vector<std::string> files;
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetSelectedAsString(files);
- ReadImagesNotThreaded(s, files, dim);
- }
-
- //======================================================================
- void WxGimmickView::GetSelectedImagesInVector(std::vector<vtkImageData*>& s, int dim)
- {
- std::vector<std::string> files;
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetSelectedAsString(files);
- ReadImagesNotThreadedInVector(s, files, dim);
- }
- //======================================================================
-
- //======================================================================
- void WxGimmickView::GetSelectedFiles(std::vector<std::string>& s)
- {
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetSelectedAsString(s);
- }
- //======================================================================
-
- //======================================================================
- void WxGimmickView::GetImages(int dim,
- const std::vector<std::string>& files,
- std::vector<vtkImageData*>& s)
- {
- ReadImagesNotThreaded(s,files,dim);
- }
- //======================================================================
-
-
- //=================================================
- void WxGimmickView::CreateIconList()
- {
- // Size of the icons;
- int size = 16;
-
- wxIcon icons[20];
- // should correspond to Icon_xxx enum
- icons[Icon_accept] = wxIcon(accept_xpm);
- icons[Icon_add] = wxIcon(add_xpm);
- icons[Icon_folder_down] = wxIcon(folder_down_xpm);
- icons[Icon_page_down] = wxIcon(page_down_xpm);
- icons[Icon_remove] = wxIcon(remove_xpm);
- icons[Icon_database_add] = wxIcon(database_add_xpm);
- icons[Icon_help] = wxIcon(help_xpm);
- icons[Icon_synchronize] = wxIcon(synchronize_xpm);
- icons[Icon_create_database] = wxIcon(create_database_xpm);
- icons[Icon_settings] = wxIcon(settings_xpm);
- icons[Icon_tools] = wxIcon(tools_xpm);
-
- // unsigned int NbIcons = 8;
- // Make an image list containing small icons
- mIcon = new wxImageList(size,size,true);
-
- // Make all icons the same size = size of the first one
- int sizeOrig = icons[0].GetWidth();
- for ( size_t i = 0; i < icon_number; i++ )
- {
- if ( size == sizeOrig )
- {
- mIcon->Add(icons[i]);
- }
- else
- {
- mIcon->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
- }
- }
- }
- //=================================================
-
-
- //=================================================
- void WxGimmickView::OnAddFiles(wxCommandEvent& event)
- {
- mViewer->StopPlayer();
- long style = wxOPEN | wxFILE_MUST_EXIST | wxFD_MULTIPLE;
- std::string wc("*");
- wxFileDialog* FD = new wxFileDialog( 0,
- _T("Select file"),
- _T(""),
- _T(""),
- crea::std2wx(wc),
- style,
- wxDefaultPosition);
-
- if (FD->ShowModal()==wxID_OK)
- {
- wxBusyCursor busy;
-
- wxArrayString files;
- FD->GetPaths(files);
- unsigned int i;
- std::vector<std::string> filenames;
- for (i=0;i<files.GetCount();++i)
- {
- filenames.push_back(wx2std(files[i]));
- GimmickMessage(2,"Adding File "<<files[i]<<"."<<std::endl);
- }
-
- mProgressDialog =
- new wxProgressDialog(_T("Adding file(s)"),
- _T(""),
- 1000,
- this,
- wxPD_ELAPSED_TIME |
- // wxPD_ESTIMATED_TIME |
- // wxPD_REMAINING_TIME |
- wxPD_CAN_ABORT );
-
- // TO DO : select the current tree handler
- mGimmick->AddFiles(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),filenames);
-
- mProgressDialog->Pulse(_T("Updating view..."));
-
- UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
- delete mProgressDialog;
- DisplayAddSummary();
-
- }
- mViewer->StartPlayer();
- }
- //=================================================
-
- //=================================================
- void WxGimmickView::OnAddDir(wxCommandEvent& event)
- {
- mViewer->StopPlayer();
- std::string name = crea::wx2std(mNotebook->GetCurrentPage()->GetName());
- long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
- wxDirDialog* FD =
- new wxDirDialog( 0,
- _T("Select directory"),
- mCurrentDirectory,
- style);
-
- if (FD->ShowModal()==wxID_OK)
- {
- std::string dirname = wx2std (FD->GetPath());
- bool recurse = isNeedRecursive(dirname);
- if (recurse)
- {
- recurse = wxMessageBox(_T("Recurse into sub-directories ?"), _T("Scan directory"), wxYES_NO,this ) == wxYES ? true : false;
- }
-
- wxBusyCursor busy;
- wxString title(_T("Adding directory"));
- if (recurse)
- title = _T("Adding directory (recursive)");
- mProgressDialog =
- new wxProgressDialog(_T("Adding directory"),
- _T(""),
- NumberFilesToAdd(dirname,recurse),
- this,
- wxPD_ELAPSED_TIME |
- wxPD_SMOOTH |
- // wxPD_ESTIMATED_TIME |
- // wxPD_REMAINING_TIME |
- wxPD_CAN_ABORT );
-
- mCurrentDirectory = FD->GetPath();
- mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),dirname,recurse);
- mProgressDialog->Pulse(_T("Updating view..."));
-
- UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
- delete mProgressDialog;
- DisplayAddSummary();
- }
- mViewer->StartPlayer();
- delete FD;
- }
-
-
- //=================================================
- // Determines number of files potentially to add to database
- int WxGimmickView::NumberFilesToAdd(const std::string &dirpath, bool recursive)
- {
- int nb = 0;
- if ( !boost::filesystem::exists( dirpath ) ) return nb;
- boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
- for ( boost::filesystem::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
- {
- // If is directory & recurse : do recurse
- if ( boost::filesystem::is_directory(itr->status()) )
- {
- if (recursive)
- {
- nb += NumberFilesToAdd(itr->string(), recursive);
- }
- }
- else
- {
- nb++;
- }
- }
- return nb;
- }
-
- //=================================================
- // Test a directory to know if contains sub-directory to analyze
- bool WxGimmickView::isNeedRecursive(std::string i_name)
- {
- boost::filesystem::directory_iterator iter(i_name), end_iter;
- bool bfindir = false;
- for(; iter != end_iter; ++iter)
- {
- if(boost::filesystem::is_directory(*iter))
- {
- return true;
- }
- }
- return false;
- }
- //=================================================
-
- //=================================================
- void WxGimmickView::OnSelectionChange(const std::vector<tree::Node*>& sel, bool isSelection, int selection, bool needProcess)
- {
- GimmickDebugMessage(5,
- "WxGimmickView::OnSelectionChange"
- <<std::endl);
- wxBusyCursor busy;
- bool valid=true;
-
- if(sel.size()==0)
- {
- valid= ValidateSelected(NULL,
- mSelectionMinDimension,
- mSelectionMaxDimension );
- }
- else if(needProcess)
- {
- ResetExtent();
- std::vector<tree::Node*>::const_iterator i;
- for(i=sel.begin();i!=sel.end()&&valid;++i)
- {
- valid= ValidateSelected((*i),
- mSelectionMinDimension,
- mSelectionMaxDimension );
- }
- }
- else if(isSelection)
- {
- valid= ValidateSelected(sel.front(),
- mSelectionMinDimension,
- mSelectionMaxDimension );
- }
- else
- {
- ResetExtent();
- std::vector<tree::Node*>::const_iterator i;
- for(i=sel.begin();i!=sel.end()&&valid;++i)
- {
- valid= ValidateSelected((*i),
- mSelectionMinDimension,
- mSelectionMaxDimension );
- }
- }
- mText->SetLabel(crea::std2wx(GetMessage()));
- /*if(valid)
- {
- ReadImageThreaded(sel);
- }
- else
- {
- ClearSelection();
- }*/
- ReadImageThreaded(sel);
- }
-
- //==================================================
-
- //==================================================
- ///Reads Images (Threaded)
- void WxGimmickView::ReadImageThreaded(const std::vector<tree::Node*>& sel)
- {
- GimmickDebugMessage(5,
- "ReadImageThreaded"
- <<std::endl);
- int maxprio = GetMaximalPriority();
- int prio = maxprio + 2000;
-
- if(sel.size()>0)
- {
- //First load the selected images
- mCurImageItemToShow = sel.front();
- pointers.clear();
- int index = 0;
- std::vector<tree::Node*>::const_iterator selected;
- for(selected=sel.begin();selected!=sel.end();++selected)
- {
- GimmickDebugMessage(5,
- "Requesting image from selected "
- <<(*selected)->GetAttribute("FullFileName")
- <<std::endl);
- //ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
- boost::shared_ptr<ImagePointerHolder> ph(new ImagePointerHolder(GetDefaultImage()));
- pointers.push_back(ph);
- RequestReading(*selected,prio,index,ph);
- // AddEntryToMap(*selected);
- prio--;
- index++;
- }
- mViewer->SetImageVector(pointers);
- //Going up
- prio = maxprio + 20;
- std::vector<tree::Node*> up;
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetNodes(up,true);
- std::vector<tree::Node*>::iterator iterUp;
- for(iterUp=up.begin();iterUp!=up.end();++iterUp)
- {
- GimmickDebugMessage(5,
- "Requesting image from neighbors up "
- <<(*iterUp)->GetAttribute("FullFileName")
- <<std::endl);
-// ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
- boost::shared_ptr<ImagePointerHolder> ph(new ImagePointerHolder(GetDefaultImage()));
- RequestReading(*iterUp,prio,-1,ph);
- // AddEntryToMap(*iterUp);
- prio--;
- if (prio == maxprio) break;
- }
-
- //Going down
- prio = maxprio + 19;
- std::vector<tree::Node*> down;
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetNodes(down,false);
- std::vector<tree::Node*>::iterator iterDown;
- for(iterDown=down.begin();iterDown!=down.end();++iterDown)
- {
- GimmickDebugMessage(5,
- "Requesting image from neighbors down "
- <<(*iterDown)->GetAttribute("FullFileName")
- <<std::endl);
- //ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
- boost::shared_ptr<ImagePointerHolder> ph(new ImagePointerHolder(GetDefaultImage()));
- RequestReading(*iterDown,prio,-1,ph);
- // AddEntryToMap(*iterDown);
- prio--;
- if (prio == maxprio) break;
- }
- }
- else
- {
- pointers.clear();
- //ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
- boost::shared_ptr<ImagePointerHolder> ph(new ImagePointerHolder(GetDefaultImage()));
- pointers.push_back(ph);
- mViewer->SetImageVector(pointers);
- }
- }
-
- //==================================================
-
- //==================================================
-
-#if defined(WIN32)
- //==================================================
- void WxGimmickView::OnInternalIdle()
- {
- if (!mConstructed) return;
- static bool first_time = true;
- if (false)
- {
- first_time = false;
- }
- // GimmickMessage(1,"WxGimmickView : Refresh viewer"<<std::endl);
- // mViewer->StartPlayer();
- if(mViewer)
- {
- mViewer->RefreshIfNecessary();
- }
- }
-#else
- void WxGimmickView::UpdateWindowUI(long flags)
- {
- if(mViewer)
- {
- mViewer->RefreshIfNecessary();
- }
- }
-#endif
- //==================================================
-
- //==================================================
- void WxGimmickView::ClearSelection()
- {
- pointers.clear();
- pointers.push_back(boost::shared_ptr<creaImageIO::ImagePointerHolder>(new ImagePointerHolder(GetDefaultImage())));
- //pointers.push_back(new ImagePointerHolder(GetDefaultImage()));
- mViewer->SetImageVector(pointers);
- mViewer->RefreshIfNecessary();
- ResetExtent();
- }
-
- //=================================================
-
- //=================================================
- void WxGimmickView::OnRemove(wxCommandEvent& event)
- {
- //TODO Select current tree handler
- wxBusyCursor busy;
- std::string remove;
- mGimmick->GetSetting(SETTINGS_REMOVE_PATIENT_DISPLAY,remove);
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->RemoveSelected(remove);
- mGimmick->UpdateSetting(SETTINGS_REMOVE_PATIENT_DISPLAY,remove);
- ClearSelection();
- }
- //=================================================
-
-
- //=================================================
- void WxGimmickView::AddIgnoreFile(tree::Node* toRemove)
- {
- mGimmick->RemoveFile(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),toRemove);
- // GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->UpdateLevel(1);
- }
-
- //=================================================
- void WxGimmickView::CopyFiles(const std::vector<std::string>& filenames)
- {
- mGimmick->CopyFiles(filenames, crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())));
- wxMessageBox(std2wx("The selected files have been copied"),_T("Copy files"),wxOK,this);
- }
-
- //=================================================
- void WxGimmickView::AddDir(std::string dirName)
- {
- mProgressDialog = new wxProgressDialog(_T("Adding directory"),_T(""),1000,this,wxPD_ELAPSED_TIME |wxPD_CAN_ABORT );
- mCurrentDirectory = crea::std2wx(dirName);
- mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),dirName,true);
- mProgressDialog->Pulse(_T("Updating view..."));
-
- UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
- delete mProgressDialog;
- DisplayAddSummary();
- }
-
- //=================================================
- void WxGimmickView::OnSynchronize(wxCommandEvent& event)
- {
- wxBusyCursor busy;
- const wxString choices[] = { _T("Check database for files deletion and addition and give a report."),
- _T("Check database for files deletion, addition and attributes change. Then give a report."),
- _T("Repair database (remove deleted files and add new files)."),
- _T("Repair database (remove deleted files, add new files and reset changed attributes).") } ;
-
- wxSingleChoiceDialog dialog(this,
- _T("Select one of the following synchronization actions:\n")
- _T("Please note that, due to the heavy amount of operations required, this action might take a while."),
- _T("Synchronization Settings"),
- WXSIZEOF(choices), choices);
-
- //dialog.SetSelection(0);
-
- if (dialog.ShowModal() == wxID_OK)
- {
- wxBusyCursor busy;
- int sel=dialog.GetSelection();
- bool repair=false;
- bool checkAttributes=false;
- if(sel==2 || sel==3){repair=true;}
- if(sel==1 || sel==3){checkAttributes=true;}
- std::string mess=mGimmick->Synchronize(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),repair, checkAttributes);
- wxMessageBox(std2wx(mess),_T("Synchronization result"),wxOK,this);
- if(sel==2 || sel==3){
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->UpdateLevel(1);
- }
-
- }
- }
- //=================================================
-
- //=================================================
- void WxGimmickView::OnSettings(wxCommandEvent& event)
- {
- wxDialog* dial= new wxDialog (this,-1,_T("System Settings"),wxDefaultPosition, wxSize(450,220));
- wxBoxSizer *siz = new wxBoxSizer(wxVERTICAL);
- // Notebook
- wxNotebook* nb= new wxNotebook(dial, -1, wxDefaultPosition, wxDefaultSize, 0);
-
- siz->Add( nb,1,wxGROW ,0);
- CreateSettingsDialog(nb,dial);
- dial->SetSizer(siz);
- dial->ShowModal();
- }
-
- //=================================================
- void WxGimmickView::OnImportExport(wxCommandEvent &Event)
- {
- wxBusyCursor busy;
- // Test if one image is selected => export
- // if not =>import
- if (GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))])
- {
- ExportImages();
- }
- else
- {
- ImportImages();
- }
- }
-
- void WxGimmickView::ExportImages()
- {
- //Archive selection: name, emplacement
- //same process than copy local but to a zip
- // if settings are yes "always ask for descriptor addition", ask
- // if settings are yes, adding descriptor
- }
-
- void WxGimmickView::ImportImages()
- {
- //Find the *.zip
- //dezip
- // Contain a descriptor.text
- // create a new database, and add to database
- // if not, add to current database
- //
- }
-
- //=================================================
- //AndresDonadio
- void WxGimmickView::OnTools(wxCommandEvent& event)
- {
- mViewer->StopPlayer();
-
- wxDialog* dial = new wxDialog (this,-1,_T("Tools"),wxDefaultPosition, wxSize(550,350));
-
- wxSizer* buttonsSizer = dial->CreateSeparatedButtonSizer(wxOK|wxCANCEL);
- wxNotebook* nb= new wxNotebook(dial, -1, wxDefaultPosition, wxDefaultSize, 0);
- wxBoxSizer *dialSizer = new wxBoxSizer(wxVERTICAL);
- dialSizer->Add(nb,1,wxGROW,0);
- dialSizer->Add(buttonsSizer,0,wxGROW);
-
-#if defined(BUILD_BRUKER)
- //First page: Bruker Image Reader
- WxGimmickTools * gimmickTools = new WxGimmickTools(nb, mCurrentDirectory);
- nb->AddPage( gimmickTools, _T("Bruker Image Reader") );
-#endif
-
- dial->SetSizer(dialSizer, true);
- dial->Layout();
- dial->ShowModal();
-
- if (dial->GetReturnCode() == wxID_OK)
- {
-#if defined(BUILD_BRUKER)
- if (nb->GetSelection()==0)//Selection: Bruker Image Reader
- {
- std::string inputDir = crea::wx2std(gimmickTools->getInputDir());
- std::string outputDir = crea::wx2std(gimmickTools->getOutputDir());
-
- bool addToDB = gimmickTools->getAddToDBCheckBoxValue();
-
- if (inputDir.compare("")!=0 && outputDir.compare("")!=0)
- {
- if ( wxMessageBox(_T("Depending on the amount of Data the process can take between 1 and 5 minutes. Do you want to continue?"),
- _T("Please confirm"), wxICON_QUESTION | wxYES_NO) == wxYES )
- {
- Bruker2Dicom b2d;
- b2d.SetInputDirectory(inputDir);
- b2d.SetOutputDirectory(outputDir);
- b2d.SetConvertModeToDicom();
- b2d.verbose=false;
- b2d.Execute();
-
- if (addToDB)
- {
- mProgressDialog = new wxProgressDialog(_T("Adding directory"),_T(""),1000,this,wxPD_ELAPSED_TIME |wxPD_CAN_ABORT );
- mCurrentDirectory = gimmickTools->getOutputDir();
- mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),outputDir,true);
- mProgressDialog->Pulse(_T("Updating view..."));
-
- UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
- delete mProgressDialog;
- DisplayAddSummary();
- }
- }
- }
- else
- {
- wxMessageBox(_T("One or both of the directory fields are empty"),_T("Empty Fields"),wxOK,this);
- }
- }
- delete gimmickTools;
-#endif
- }
- mViewer->StartPlayer();
- }
-
- //=================================================
-
- void WxGimmickView::CreateSettingsDialog(wxNotebook* nb, wxDialog* dial)
- {
- //First page: Customization of configurations
- //Copy Path string
- std::string cp;
- mGimmick->GetSetting(SETTINGS_COPY_PATH,cp);
- //Database Path String
- std::string dp;
- mGimmick->GetSetting(SETTINGS_DBPATH,dp);
- //Syncronization Event String
- std::string se;
- mGimmick->GetSetting(SETTINGS_SYNC_EVENT,se);
- //Syncronization Frequency String
- std::string sf;
- mGimmick->GetSetting(SETTINGS_SYNC_FREQ,sf);
-
- WxCustomizeConfigPanel * customConfig=new WxCustomizeConfigPanel(nb,dial,this,cp,dp,se,sf);
-
- nb->AddPage( customConfig, crea::std2wx("Customize Configuration") );
-
- //Second page: Creation of Databases
- /*wxPanel* databaseCreation=new wxPanel(nb);
- nb->AddPage( databaseCreation, crea::std2wx("Create Database") );*/
-
- //Second page (temporary): Connection to PACS
- WxPACSConnectionPanel* pacs=new WxPACSConnectionPanel(nb,dial, this);
- nb->AddPage( pacs, crea::std2wx("Connect to PACS") );
-
- //Third page: CD/DVD Watch
- WxListenerPanel* cdWatch=new WxListenerPanel(nb,dial, this,true);//, mListener->IsPaused());
- nb->AddPage( cdWatch, crea::std2wx("CD/DVD") );
-
- //Fourth page: Selection of attributes to show
- std::vector<std::string> shown;
- std::vector<std::string> nShown;
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetAttributes(shown,nShown,1);
- int nLev=GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetNumberOfLevels();
- WxAttributeSelectionPanel* attSelection=new WxAttributeSelectionPanel(nb,dial,this,shown,nShown,nLev);
- nb->AddPage( attSelection, crea::std2wx("Selection of Attributes") );
- }
-
- //===================================================================
- void WxGimmickView::GetVisibleAttributes(std::vector<std::string>& shown,
- std::vector<std::string>& nShown, int level)
- {
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetAttributes(shown,nShown,level);
- }
-
- //===================================================================
- void WxGimmickView::OnAttributesChanged(const std::vector<std::string>& nShown, int level)
- {
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->SetNonVisibleAttributes(nShown,level);
- std::vector<std::string> n=nShown;
- GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->CreateCtrl(n,level);
- }
- //===================================================================
- void WxGimmickView::OnSaveSettingsCallback(const std::string& copyPath,
- const std::string& dbPath,
- const std::string& syncEvent,
- const std::string& syncFreq)
- {
- mGimmick->UpdateSetting(SETTINGS_COPY_PATH,copyPath);
- mGimmick->UpdateSetting(SETTINGS_DBPATH,dbPath);
- mGimmick->UpdateSetting(SETTINGS_SYNC_EVENT,syncEvent);
- mGimmick->UpdateSetting(SETTINGS_SYNC_FREQ,syncFreq);
- }
-
- //===================================================================
- void WxGimmickView::OnListenerCallback(const std::string& drive, bool addFiles, bool removeFiles)
- {
- mListener->SetMonitoredDrive(drive);
- mListener->SetAddFilesState(addFiles);
- mListener->SetRemoveFilesState(removeFiles);
- }
-
- //========================================================================
-
- void WxGimmickView::OnDriveMount(bool mount)
- {
- GimmickMessage(1, "Gimmick::OnDriveMount"<<std::endl);
- std::string drive;
- mListener->GetMonitoredDrive(drive);
-
- if(mount)
- {
- mViewer->StopPlayer();
- wxBusyCursor busy;
- wxString title(_T("Adding drive"));
- mProgressDialog =
- new wxProgressDialog(_T("Adding drive"),
- _T(""),
- 1000,
- this,
- wxPD_ELAPSED_TIME |
- // wxPD_ESTIMATED_TIME |
- // wxPD_REMAINING_TIME |
- wxPD_CAN_ABORT );
- mCurrentDirectory = crea::std2wx(drive);
- mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),drive,true);
- mProgressDialog->Pulse(_T("Updating view..."));
-
- UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
- delete mProgressDialog;
- DisplayAddSummary();
- mViewer->StartPlayer();
- }
- else
- {
- mGimmick->DeleteDrive(drive);
- UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
- }
- }
-
- //========================================================================
-
- void WxGimmickView::StartListeningThread()
- {
- mListener->Resume();
- }
-
- //========================================================================
-
- void WxGimmickView::StopListeningThread()
- {
- mListener->Pause();
- }
-
- //========================================================================
- void WxGimmickView::CreateEditFieldsDialog(tree::Node* node, std::vector<std::string> names, std::vector<std::string> keys)
- {
- wxDialog* dial= new wxDialog (this,-1,crea::std2wx("Edit Fields for node "+node->GetLabel()),wxDefaultPosition, wxSize(350,155));
- wxBoxSizer *siz = new wxBoxSizer(wxVERTICAL);
- WxEditFieldsPanel* ef = new WxEditFieldsPanel(dial, dial, this, node, names, keys);
-
- siz->Add( ef,1,wxGROW ,0);
- dial->SetSizer(siz);
- dial->ShowModal();
- }
-
- //========================================================================
- void WxGimmickView::DumpTags(std::string i_filename)
- {
- WxDumpPanel* pan= new WxDumpPanel (this,i_filename);
- pan->ShowModal();
- }
-
- //========================================================================
- void WxGimmickView::ExportToStorage(const std::vector<std::string> i_filenames)
- {
- std::vector<std::string> storages;
- Gimmick::TreeHandlerMapType::iterator it = mGimmick->GetTreeHandlerMap().begin();
- for(;it != mGimmick->GetTreeHandlerMap().end(); it++)
- {
- storages.push_back(it->first);
- }
-
- WxExportDlg* exp= new WxExportDlg(this,storages);
- if ( exp->ShowModal() ==ID_EXPORT_OK)
- {
- std::string storage = exp->GetStorage();
- mProgressDialog =
- new wxProgressDialog(_T("Adding file(s)"),
- _T(""),
- 1000,
- this,
- wxPD_ELAPSED_TIME |
- // wxPD_ESTIMATED_TIME |
- // wxPD_REMAINING_TIME |
- wxPD_CAN_ABORT );
- mGimmick->AddFiles(storage,i_filenames);
- mProgressDialog->Pulse(_T("Updating view..."));
- UpdateTreeViewLevel(storage,1);
- delete mProgressDialog;
- DisplayAddSummary();
- }
- }
-
-
-
- //========================================================================
- void WxGimmickView::OnFieldsEdited(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
- {
- mGimmick->EditField(node, crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())), name, key, val);
- UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
- }
-
- //=================================================
- /// AddProgress Gimmick callback
- void WxGimmickView::OnAddProgress( Gimmick::AddProgress& p)
- {
- char mess[200];
- sprintf(mess,"%i dirs : %i files :\n %i handled - %i added",
- p.GetNumberScannedDirs(),
- p.GetNumberScannedFiles(),
- p.GetNumberHandledFiles(),
- p.GetNumberAddedFiles());
- // std::cout << "OnAddProgress "<<mess<<std::endl;
- wxString s(wxString::From8BitData(mess));
- // std::cout << "Pulse"<<std::endl;
- if (!mProgressDialog->Pulse(s))
- {
- p.SetStop();
- }
- // std::cout << "OnAddProgress ok"<<std::endl;
- }
- //=================================================
-
- //=================================================
- void WxGimmickView::DisplayAddSummary()
- {
- const Gimmick::AddProgress& p = mGimmick->GetAddProgress();
- std::stringstream mess;
- mess << "Dirs \tscanned\t: " << p.GetNumberScannedDirs() << "\n";
- mess << "Files\tscanned\t: " << p.GetNumberScannedFiles() << "\n";
- mess << "Files\thandled\t: " << p.GetNumberHandledFiles() << "\n\n";
- mess << "Files\tadded \t: " << p.GetNumberAddedFiles() << "\n\n";
- wxMessageBox(std2wx(mess.str()),_T("Addition result"),wxOK,this);
- }
-
- ////////////////////////////////////////////////
- // Add a DB to application //
- // @param event : WxEvent //
- // @return : - //
- ////////////////////////////////////////////////
- void WxGimmickView::OnAddDB(wxCommandEvent& event)
- {
- //Select DB
- long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
- std::string wc("*.sqlite3*");
- wxFileDialog* FD = new wxFileDialog( 0,
- _T("Select file"),
- _T(""),
- _T(""),
- crea::std2wx(wc),
- style,
- wxDefaultPosition);
-
- if (FD->ShowModal()==wxID_OK)
- {
- wxBusyCursor busy;
- wxArrayString files;
- FD->GetPaths(files);
- std::stringstream st;
- for(int i = 0; i< files.size(); i++)
- {
- //get name of DB (file name)
- size_t pos = files[i].find_last_of(_T("\\"));
- std::string name = crea::wx2std(files[i].substr(pos+1));
- pos = name.find_last_of(".");
- name = name.substr(0,pos);
- //create TreeHandler
- mGimmick->addDB(name, crea::wx2std(files[i]));
- //create TreeView
- CreateSingleTreeView(name);
- }
- }
- }
- ////////////////////////////////////////////////////
- // Create a DB from an Attributes Descriptor files //
- // @param event : WxEvent //
- // @return : - //
- //////////////////////////////////////////////////
- void WxGimmickView::OnCreateDB(wxCommandEvent& event)
- {
- // PACSConnection("");
- WxDescriptorPanel * DescriptorPan = new WxDescriptorPanel(this, mGimmick->GetHomeDirectory());
- DescriptorPan->Layout();
- if ( DescriptorPan->ShowModal() == ID_DSCP_APPLY)
- {
- wxBusyCursor busy;
- std::string file(DescriptorPan->GetDescriptor());
- if (!file.empty())
- {
- size_t pos = file.find_last_of("\\");
- std::string name = file.substr(pos+1);
- std::string directory = file.substr(0,pos);
- pos = name.find_last_of(".");
- name = name.substr(0,pos);
- //get directory to store DB
- directory += "\\" + name + ".sqlite3";
- //create createDB
- mGimmick->createDB(name, file,directory);
- //create TreeHandler
- mGimmick->addDB(name, directory);
- //create TreeView
- CreateSingleTreeView(name);
- }
- }
- }
-
- //=================================================
-
- //=================================================
- BEGIN_EVENT_TABLE(WxGimmickView, wxPanel)
- EVT_TOOL(TOOL_CREATEDB_ID, WxGimmickView::OnCreateDB)
- EVT_TOOL(TOOL_ADDFILES_ID, WxGimmickView::OnAddFiles)
- EVT_TOOL(TOOL_ADDDIR_ID, WxGimmickView::OnAddDir)
- EVT_TOOL(TOOL_ADDDATABASE_ID, WxGimmickView::OnAddDB)
- EVT_TOOL(TOOL_REMOVE_ID, WxGimmickView::OnRemove)
- EVT_TOOL(TOOL_SYNCHRONIZE_ID, WxGimmickView::OnSynchronize)
- EVT_TOOL(TOOL_SETTINGS_ID, WxGimmickView::OnSettings)
- EVT_TOOL(TOOL_TOOLS_ID, WxGimmickView::OnTools)
- END_EVENT_TABLE()
- //=================================================
-
-} // EO namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOWxGimmickView_h_INCLUDED__
-#define __creaImageIOWxGimmickView_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-
-#include <creaImageIOGimmickView.h>
-#include <creaImageIOWxViewer.h>
-#include <creaImageIOWxGimmickTools.h>
-#include <creaImageIOListener.h>
-#include <creaWx.h>
-
-#include "wx/progdlg.h"
-
-#include "wx/wx.h"
-#include <wx/splitter.h>
-#include <wx/toolbar.h>
-#include <wx/tbarbase.h>
-#include <wx/notebook.h>
-
-namespace creaImageIO
-{
- /**
- * \ingroup View
- */
- //=====================================================================
-
- //=====================================================================
- /// Concrete derivative of GimmickView which implements a wxWidgets-based view
-
- class WxGimmickView : public wxPanel, virtual public GimmickView
- {
- public:
-
- typedef int EventType;
-
- /// Ctor
- WxGimmickView(boost::shared_ptr<Gimmick>,
- wxWindow *parent,
- const wxWindowID id,
- const wxPoint& pos, const wxSize& size,
- int min_dim = GIMMICK_2D_IMAGE_SELECTION,
- int max_dim = GIMMICK_3D_IMAGE_SELECTION,
- int number_of_threads = 0);
- /// Virtual destructor
- virtual ~WxGimmickView();
-
- /// Returns the selected files
- ///(overloaded from GimmickView)
- void GetSelectedFiles(std::vector<std::string>& s);
-
- /// Returns the selected Images so that they comply with the
- /// given parameter(4D) (overloaded from GimmickView)
- void GetSelectedImages(std::vector<vtkImageData*>& s, int dim);
- void GetSelectedImagesInVector(std::vector<vtkImageData*>& s, int dim);
-
- /// Returns the images indicated by the filenames in the vector
- /// so that they comply with the given parameter(dim)
- //(overloaded from GimmickView)
- void GetImages(int dim, const std::vector<std::string>& files,
- std::vector<vtkImageData*>& s);
-
- /// Callback called when a selection from a TreeView has changed
- //(overloaded from GimmickView)
- void OnSelectionChange(const std::vector<tree::Node*>& s,
- bool isSelection, int selection, bool mProcess);
- ///Stops the player
- void StopPlayer(){mViewer->StopPlayer();}
- ///Adds a file to ignore
- void AddIgnoreFile(tree::Node* toRemove);
- ///Resets the default image
- void ClearSelection();
- ///Copies selected files
- void CopyFiles(const std::vector<std::string>& filenames);
- ///Add selected files to the Database
- void AddDir(std::string dirName);
-
-
- ///Sends a request to read the currently selected node and the ones that surround it.
- void ReadImageThreaded(const std::vector<tree::Node*>& sel);
-
- ///Saves the settings to the file
- void OnSaveSettingsCallback(const std::string& copyPath,
- const std::string& dbPath,
- const std::string& syncEvent,
- const std::string& syncFreq);
-
- ///Changes listener state
- void OnListenerCallback(const std::string& drive, bool addFiles, bool removeFiles);
-
- ///Acts upon a drive mount
- void OnDriveMount(bool mount);
-
- ///Starts the listening thread on the CD/DVD drive
- void StartListeningThread();
-
- ///Stops the listening thread on the CD/DVD drive
- void StopListeningThread();
-
- ///Called upon when a field has been edited
- void OnFieldsEdited(tree::Node* node, const std::string& name, const std::string& key, const std::string& val);
-
- ///Called upon to return the visible attributes of the current tab
- void GetVisibleAttributes(std::vector<std::string>& shown,std::vector<std::string>& nShown, int level);
-
- ///Called when there has been a change in the visible attributes of a tree view
- void OnAttributesChanged(const std::vector<std::string>& nShown, int level);
-
- protected:
- /// Creates the tool bar
- void CreateToolBar();
-
- /// Create the tree view for TreeHandler provided
- /// (overloaded from GimmickView)
- void CreateTreeView( TreeHandler* );
-
-
- private:
- wxBoxSizer *mbottom_sizer;
- wxBoxSizer *msizer;
- /// Is set to true at the end of constructor
- /// (in order to lock callbacks from threaded objects or event
- /// before everything is ok)
- bool mConstructed;
- /// The ToolBar and the tools
- wxToolBar* mToolBar;
- wxToolBarToolBase* mToolAddFile;
- wxToolBarToolBase* mToolAddDir;
- wxToolBarToolBase* mToolRemove;
- wxToolBarToolBase* mToolAddDatabase;
- wxToolBarToolBase* mToolHelp;
- wxToolBarToolBase* mToolSynchronize;
- wxToolBarToolBase* mToolSettings;
- wxToolBarToolBase* mToolTools;
-
- wxSplitterWindow* mSplitter;
- wxPanel* mBottomPanel;
- wxStaticText * mText;
- wxNotebook* mNotebook;
-
- /// The list of icons
- wxImageList * mIcon;
- void CreateIconList();
-
- boost::shared_ptr<Gimmick> mGimmick;
-
- Listener* mListener;
-
- /// Callback for adding files
- void OnAddFiles(wxCommandEvent& event);
-
- /// Callback for adding dir
- void OnAddDir(wxCommandEvent& event);
-
- /// Callback for removing files
- void OnRemove(wxCommandEvent& event);
-
- /// Callback for synchronization
- void OnSynchronize(wxCommandEvent& event);
-
- /// Callback for settings edition
- void OnSettings(wxCommandEvent& event);
-
- /// Callback for settings edition
- void OnTools(wxCommandEvent& event);
-
- /// Callback for Import/Export images
- void OnImportExport(wxCommandEvent& event);
-
- // Import Images from an archive
- void ImportImages();
-
- //Export Images to an archive
- void ExportImages();
-
- ///Creates the settings dialog (the pages inside and the information)
- void CreateSettingsDialog(wxNotebook* nb, wxDialog* dial);
-
- /// Display a message box with the last addition statistics
- void DisplayAddSummary();
-
- /// Test a directory to know if contains sub-directory to analyze
- bool isNeedRecursive(std::string i_name);
-
- /// Determines number of files potentially to add to database
- int NumberFilesToAdd(const std::string &dirpath, bool recursive);
-
- /// AddProgress Gimmick callback
- void OnAddProgress( Gimmick::AddProgress& );
-
-#if defined(WIN32)
- /// Called upon to refresh the viewer once there are no actions to be done
- void OnInternalIdle();
-#else
- void UpdateWindowUI(long flags = wxUPDATE_UI_NONE);
-#endif
- /// callback to add a database
- void OnAddDB(wxCommandEvent& event);
-
- ///Create a DB from an Attributes Descriptor files
- void OnCreateDB(wxCommandEvent& event);
-
- std::string ExtractName(const std::string &i_name);
-
- ///Edits the fields of a given node
- void CreateEditFieldsDialog(tree::Node* node, std::vector<std::string> names, std::vector<std::string> keys);
-
- /// Display all Dicom Tags
- void DumpTags(const std::string i_filename);
-
- /// Export from Storage to Storage
- void ExportToStorage(const std::vector<std::string> i_filenames);
-
- /// Progress dialog
- wxProgressDialog* mProgressDialog;
-
- ///The selection's maximum dimension
- int mSelectionMaxDimension;
-
- ///The selection's minimum dimension
- int mSelectionMinDimension;
-
- ///Image previewer
- WxViewer* mViewer;
-
- ///Currently Displayed Node
- tree::Node* mCurImageItemToShow;
-
- //Pointer holders for images to be shown
- std::vector< boost::shared_ptr<ImagePointerHolder> > pointers;
-
- wxString mCurrentDirectory;
-
- DECLARE_EVENT_TABLE()
- };
- // EO class WxGimmickView
- //=====================================================================
-
-} // EO namespace creaImageIO
-
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-#include <creaImageIOWxListenerPanel.h>
-#include <creaImageIOSystem.h>
-
-namespace creaImageIO
-{
- // CTor
- WxListenerPanel::WxListenerPanel(wxWindow *parent, wxDialog* dial, WxGimmickView* view, bool stat)
- : wxPanel( parent,
- -1, wxDefaultPosition,
- wxDefaultSize,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- dialog(dial),
- mView(view)
- {
- GimmickDebugMessage(1,"WxListener::WxListener"
- <<std::endl);
- state=stat;
- wxStaticText * cp=new wxStaticText(this,-1,_T(" Drive to monitor: "), wxPoint(5,15));
- const wxString choices[] = { _T("D:"),
- _T("E:"),
- _T("F:"),
- _T("G:") };
- drives=new wxComboBox(this, -1,crea::std2wx("E:"),wxPoint(100, 10),wxDefaultSize,4,choices);
-
- addCheckBox = new wxCheckBox(this, -1, _T("Automatically add images to the database when CD/DVD is mounted?"), wxPoint(5,45) );
- addCheckBox->SetValue(true);
- removeCheckBox = new wxCheckBox(this, -1, _T("Automatically remove images from the database when CD/DVD is unmounted?"), wxPoint(5,75) );
- removeCheckBox->SetValue(true);
- Connect( addCheckBox->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, (wxObjectEventFunction) &WxListenerPanel::OnAdd );
- Connect( removeCheckBox->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, (wxObjectEventFunction) &WxListenerPanel::OnRemove );
- std::string name;
- if (state){name="Start Monitoring Drive";}
- else {name="Stop Monitoring Drive";}
- wxButton *start = new wxButton(this,wxID_ANY,crea::std2wx(name), wxPoint(5,110) );
- Connect( start->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxListenerPanel::OnChangeThreadState );
-
- wxButton *save = new wxButton(this,wxID_ANY,_T("Save Changes"), wxPoint(130,110) );
- Connect( save->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxListenerPanel::OnChangeListenState );
-
-
- //topsizer->Add( mView,1,wxGROW,0);
-
-// SetSizer( topsizer );
- Layout();
- }
-
- /// Destructor
- WxListenerPanel::~WxListenerPanel()
- {
- GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
- <<std::endl);
- }
-
- void WxListenerPanel::OnAdd(wxCommandEvent& event)
- {
- addFiles = addCheckBox->GetValue();
- }
-
- void WxListenerPanel::OnRemove(wxCommandEvent& event)
- {
- removeFiles = removeCheckBox->GetValue();
- }
-
- void WxListenerPanel::OnChangeListenState(wxCommandEvent& event)
- {
- mView->OnListenerCallback(crea::wx2std(drives->GetValue()),addFiles, removeFiles);
- dialog->Destroy();
- }
-
- void WxListenerPanel::OnChangeThreadState(wxCommandEvent& event)
- {
- if(state)
- {
- mView->StartListeningThread();
- }
- else
- {
- mView->StopListeningThread();
- }
- dialog->Destroy();
- }
-
-//======================================================================
-
-//======================================================================
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxListenerPanel_h_INCLUDED__
-#define __creaImageIOWxListenerPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <creaImageIOWxGimmickView.h>
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- class WxListenerPanel : public wxPanel
- {
- public:
- WxListenerPanel();
- WxListenerPanel(wxWindow *parent,
- wxDialog* dial,
- WxGimmickView* view,
- bool stat);
-
- ~WxListenerPanel();
- ///Saves the configuration
- void OnChangeListenState(wxCommandEvent& event);
- ///Changes the thread state(start/stop)
- void OnChangeThreadState(wxCommandEvent& event);
- ///Changes the state of the add boolean
- void OnAdd(wxCommandEvent& event);
- ///Changes the state of the remove boolean
- void OnRemove(wxCommandEvent& event);
-
-
- private :
- bool addFiles;
- bool removeFiles;
- bool state;
- wxCheckBox* addCheckBox;
- wxCheckBox* removeCheckBox;
- wxComboBox* drives;
- wxDialog* dialog;
- WxGimmickView* mView;
-
-
- }; // class WxListener
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
-
-
+++ /dev/null
-#include <creaImageIOWxPACSConnectionPanel.h>
-#include <creaImageIOPACSConnection.h>
-#include <creaImageIOSystem.h>
-
-namespace creaImageIO
-{
- // CTor
- WxPACSConnectionPanel::WxPACSConnectionPanel(wxWindow *parent, wxDialog* dial, WxGimmickView* view)
- : wxPanel( parent,
- -1, wxDefaultPosition,
- wxDefaultSize,
- wxRESIZE_BORDER |
- wxSYSTEM_MENU |
- wxCLOSE_BOX |
- wxMAXIMIZE_BOX |
- wxMINIMIZE_BOX |
- wxCAPTION
- ),
- dialog(dial),
- mView(view)
- {
- GimmickDebugMessage(1,"WxPACSConnectionPanel::WxPACSConnectionPanel"
- <<std::endl);
- wxStaticText * dicId=new wxStaticText(this,-1,_T(" DICOM Identification: "), wxPoint(5,5));
- wxStaticText * aet=new wxStaticText(this,-1,_T(" AETitle: "), wxPoint(5,25));
- aeTitle=new wxTextCtrl(this, wxID_ANY, _T("MyAeTitle"), wxPoint(75,25), wxSize(220,20));
-
- wxStaticText * pn=new wxStaticText(this,-1,_T(" Port Number: "), wxPoint(5,53));
- pNumber=new wxTextCtrl(this, wxID_ANY, _T("3306"), wxPoint(75,50), wxSize(220,20));
- wxStaticText * adv1=new wxStaticText(this,-1,_T(" (1 - 131072) "), wxPoint(300,53));
-
- wxStaticText * ad=new wxStaticText(this,-1,_T(" Address: "), wxPoint(5,80));
- address=new wxTextCtrl(this, wxID_ANY, _T("localhost"), wxPoint(75,75), wxSize(220,20));
-
- wxButton *query = new wxButton(this,wxID_ANY,_T("Query PACS Server"), wxPoint(5,110) );
- Connect( query->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxPACSConnectionPanel::OnQueryPACS );
-
- Layout();
- }
-
- /// Destructor
- WxPACSConnectionPanel::~WxPACSConnectionPanel()
- {
- GimmickDebugMessage(1,"WxPACSConnectionPanel::~WxPACSConnectionPanel"
- <<std::endl);
- }
-
- void WxPACSConnectionPanel::OnQueryPACS(wxCommandEvent& event)
- {
- PACSConnection* pc=new PACSConnection(crea::wx2std(aeTitle->GetValue()));
- //mView->OnListenerCallback(crea::wx2std(drives->GetValue()),addFiles, removeFiles);
- //dialog->Destroy();
- }
-
-//======================================================================
-
-//======================================================================
-
-} // EO namespace creaImageIO
-
-
+++ /dev/null
-#ifndef __creaImageIOWxPACSConnectionPanel_h_INCLUDED__
-#define __creaImageIOWxPACSConnectionPanel_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-#include <creaWx.h>
-#include <creaImageIOWxGimmickView.h>
-
-
-namespace creaImageIO
-{
- /**
- * \ingroup GUI
- */
- //=====================================================================
- //=====================================================================
- class WxPACSConnectionPanel : public wxPanel
- {
- public:
- WxPACSConnectionPanel();
- WxPACSConnectionPanel(wxWindow *parent,
- wxDialog* dial,
- WxGimmickView* view);
-
- ~WxPACSConnectionPanel();
- ///Queries the PACS
- void OnQueryPACS(wxCommandEvent& event);
-
- private :
- wxTextCtrl* aeTitle;
- wxTextCtrl* pNumber;
- wxTextCtrl* address;
- wxDialog* dialog;
- WxGimmickView* mView;
-
-
- }; // class WxPACSConnectionPanel
- //=====================================================================
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
-
-
+++ /dev/null
-#include <creaImageIOWxTreeView.h>
-#include <creaImageIOGimmickView.h>
-#include <creaImageIOSystem.h>
-#include <wx/splitter.h>
-#include <wx/gdicmn.h>
-#include <boost/date_time/gregorian/gregorian.hpp>
-#include <creaImageIOGimmick.h>
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-//=====================================================================
-namespace creaImageIO
-{
-
- //=====================================================================
-}
-//=====================================================================
-
-//=====================================================================
-///Comparing function for ordering algorithm. Takes parameters as strings.
-int wxCALLBACK CompareFunctionStrings(long item1, long item2, long sortData)
-{
- creaImageIO::ItemData* data1 = (creaImageIO::ItemData*)item1;
- creaImageIO::ItemData* data2 = (creaImageIO::ItemData*)item2;
-
- const std::string& s1(*(data1->attr));
- const std::string& s2(*(data2->attr));
- if(sortData==1)
- {
- // inverse the order
- if (s1 < s2)
- return 1;
- if (s1 > s2)
- return -1;
-
- return 0;
- }
- else
- {
- if (s1 < s2)
- return -1;
- if (s1 > s2)
- return 1;
-
- return 0;
-
- }
-}
-//=====================================================================
-
-//=====================================================================
-///Comparing function for ordering algorithm. Takes parameters as ints.
-int wxCALLBACK CompareFunctionInts(long item1, long item2, long sortData)
-{
- creaImageIO::ItemData* data1 = (creaImageIO::ItemData*)item1;
- creaImageIO::ItemData* data2 = (creaImageIO::ItemData*)item2;
-
- const std::string& s1(*(data1->attr));
- const std::string& s2(*(data2->attr));
-
- int val1=atoi(s1.c_str());
- int val2=atoi(s2.c_str());
-
- if(sortData==1)
- {
- // inverse the order
- if (val1 < val2)
- return 1;
- if (val1 > val2)
- return -1;
-
- return 0;
- }
- else
- {
- if (val1 < val2)
- return -1;
- if (val1 > val2)
- return 1;
-
- return 0;
-
- }
-
-}
-
-//=====================================================================
-
-
-//=====================================================================
-namespace creaImageIO
-{
- //=====================================================================
- // CTor
- WxTreeView::WxTreeView(TreeHandler* handler,
- GimmickView* gimmick,
- wxWindow* parent,
- const wxWindowID id)
- : wxPanel(parent,id),
- TreeView(handler, gimmick)
- {
- GimmickDebugMessage(1,"WxTreeView::WxTreeView"
- <<std::endl);
-
-
- // Split part below toolbar into notebook for views and panel
- // for preview, messages...
- // TO DO : Splitter
- // mSplitter = new wxSplitterWindow( this , -1);
-
- // Global sizer
- msizer = new wxBoxSizer(wxHORIZONTAL);
-
- int ctrl_style = wxLC_REPORT | wxLC_VRULES;
- int col_style = wxLIST_FORMAT_LEFT;
-
- // Creating the ListCtrl for the levels > 0 (not for Root level)
- for (int i = 0;
- i < handler->GetTree().GetNumberOfLevels() -1;
- ++i)
- {
- GimmickDebugMessage(5,"Creating view for level "<<i
- <<std::endl);
- LevelType level;
- level.SelectedUpToDate = true;
- level.SortColumn = 0;
-
- // If the first level : parent = this
- wxWindow* sparent = this;
- // else parent = last splitter
- if (i>0)
- sparent = mLevelList[i-1].wxSplitter;
-
- level.wxSplitter = new wxSplitterWindow( sparent , -1);
- if(i!=0)
- {
- level.wxSplitter->Show(false);
- }
- // level.wxSplitter->SetMinimumPaneSize(100);
-
- wxListCtrl* ctrl = new wxListCtrl(level.wxSplitter,
- i,
- wxDefaultPosition,
- wxDefaultSize,
- ctrl_style);
- level.wxCtrl = ctrl;
- level.wxSplitter->Initialize(ctrl);
-
- // Create the columns : one for each attribute of the level
- int col = 0;
- std::string title;
-
- tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = handler->GetTree().GetAttributeDescriptorList(i+1).begin();
- a != handler->GetTree().GetAttributeDescriptorList(i+1).end();
- ++a)
-
-{
-
- GimmickDebugMessage(5,"Creating column "<<col<<" : "
- <<a->GetName()
- <<std::endl);
-
- if(a->GetFlags()!=creaImageIO::tree::AttributeDescriptor::PRIVATE)
- {
-
- if(a->GetName()=="UNKNOWN")
- {
- title = "#";
- title += handler->GetTree().GetLevelDescriptor(i+1).GetName();
- if (title[title.size()-1]!='s')
- title += "s";
-
- }
- else
- {
- title=a->GetName();
- }
- std::string temp = a->GetKey();
- if (temp.compare("ID") != 0)
- {
-
- ctrl->InsertColumn(col,
- crea::std2wx(title),
- col_style);
- col++;
- }
- level.key.push_back(a->GetKey());
- }
-
- }
-
- mLevelList.push_back(level);
- }
-
-#if wxUSE_MENUS
-
- // Column Menu
- menu =new wxMenu;
- wxMenuItem* m1=menu->Append(wxID_ANY, _T("&Sort ascending"));
- wxMenuItem* m2=menu->Append(wxID_ANY, _T("&Sort descending"));
- wxMenuItem* m3=menu->Append(wxID_ANY, _T("&Filter"));
- mAscendingID=m1->GetId();
- mDescendingID=m2->GetId();
- mFilterID=m3->GetId();
- Connect( mAscendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
- Connect( mDescendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
- Connect( mFilterID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupFilter) );
-
-
- ////SubMenuItem EXPORT
- subExportMenu = new wxMenu;
- wxMenuItem *subExp1 = subExportMenu->Append(wxID_ANY, _T("&Export to Storage"));
- Connect( subExp1->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnExportToStorage) );
-
- //ItemMenu
- menuItem =new wxMenu;
- wxMenuItem* m1Item=menuItem->Append(wxID_ANY, _T("&Anonymize"));
- wxMenuItem* m2Item=menuItem->Append(wxID_ANY, _T("&Local Copy"));
- wxMenuItem* m3Item=menuItem->Append(wxID_ANY, _T("&Edit Fields"));
- wxMenuItem* m4Item=menuItem->Append(wxID_ANY, _T("&Display Dicom Tags"));
- menuItem->AppendSubMenu(subExportMenu, wxT("&Export"));
-
- mAnonymizingID=m1Item->GetId();
- mLocalCopyID=m2Item->GetId();
- mEditFieldID=m3Item->GetId();
- mDumpID=m4Item->GetId();
-
- //Connect( mAnonymizingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnAnonymize) );
- Connect( mLocalCopyID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnLocalCopy) );
- Connect( mEditFieldID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnEditField) );
- Connect( mDumpID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnDumpTags) );
-
-
-
-#endif // wxUSE_MENUS
- /// Initialize the first level splitter
-
- msizer->Add( mLevelList[0].wxSplitter ,1, wxGROW ,0);
- // mColumnSelected=1;
- mLastSelected=0;
- mLastLevel=0;
- // mDirection=true;
-
- mIgnoreSelectedChanged = false;
-
- //CreateColorPalette();
- UpdateLevel(1);
-
- SetSizer( msizer );
- SetAutoLayout(true);
- Layout();
-
- }
- //=====================================================================
-
- //=====================================================================
- /// Destructor
- WxTreeView::~WxTreeView()
- {
- GimmickDebugMessage(1,"WxTreeView::~WxTreeView"
- <<std::endl);
- delete menu;
- delete menuItem;
-
- }
- //=====================================================================
-
-
-
- //=====================================================================
- const std::vector<tree::Node*>& WxTreeView::GetSelected(int level)
- {
- std::vector<tree::Node*>& sel = mLevelList[0].Selected;
- // if (GetSelectedUpToDate(level))
- int l = level - 1;
- // the selection of upper level
- if(mLevelList.size() == level -1)
- sel = mLevelList.back().Selected;
- else
- sel= mLevelList[l].Selected;
- if (sel.size() > 0)
- {
- sel.clear();
- }
- if (level == 1)
- {
- sel.push_back(GetTreeHandler()->GetTree().GetTree());
- }
- else if (level < mLevelList.size()+2 )
- {
- long item = -1;
- for ( ;; )
- {
- item = GetCtrl(l-1)->GetNextItem(item,
- wxLIST_NEXT_ALL,
- wxLIST_STATE_SELECTED);
- if ( item == -1 )
- break;
- long adr = GetCtrl(l-1)->GetItemData(item);
- tree::Node* n = ((ItemData*)adr)->node;
- if(mLastSelected==item)
- {
- std::vector<tree::Node*>::iterator it;
- it = sel.begin();
- it = sel.insert ( it , n );
- }
- else
- {
-
- sel.push_back(n);
- }
-
- }
- /*int n = GetCtrl(l-1)->GetItemCount();
- for (int i = 0; i<n; i++)
- {
- std::cout<<GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED)<<std::endl;
- if ( GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED))
- {
- long adr = GetCtrl(l-1)->GetItemData(i);
- tree::Node* n = ((ItemData*)adr)->node;
- if(mLastSelected==i)
- {
- std::vector<tree::Node*>::iterator it;
- it = sel.begin();
- it = sel.insert ( it , n );
- }
- else
- {
-
- sel.push_back(n);
- }
- }
- }*/
- }
- else
- {
- // NOTHING
- }
-
- // return mLevelList[level-1].Selected;
- return sel;
- }
-
- //=====================================================================
-
- //=====================================================================
- ///Removes selected nodes on last selected level
- // NOT SPECIFIC
- void WxTreeView::RemoveSelected(std::string &i_save)
- {
- bool erase=false;
-
- unsigned int tempLevel = mLastLevel;
- mLastLevel+=1;
- const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
- // if no selection, no remove action.
- if(sel.size() != 0)
- {
-
- std::stringstream out;
- std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
- out<<"Delete ";
- out<<sel.size();
- if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
- {
- out<<" "<<levelName;
- out<<"s?";
- }
- else
- {
- out<<" "<<GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName()<<"?";
- }
- if (wxMessageBox(crea::std2wx(out.str()),
- _T("Remove Files"),
- wxYES_NO,this ) == wxYES)
- {
- erase = true;
- }
- if(erase)
- {
- GetGimmickView()->modifyValidationSignal(false);
- bool needRefresh=false;
- std::vector<tree::Node*>::const_iterator i;
- for (i=sel.begin(); i!=sel.end(); ++i)
- {
- GimmickMessage(1,
- "deleting '"
- <<(*i)->GetLabel()
- <<"'"<<mLastLevel
- <<std::endl);
- if((*i)->GetParent()->GetNumberOfChildren()<2)
- {
- needRefresh=true;
- }
- //tree::Node* n = new (tree::Node*)(*i);
- GetTreeHandler()->LoadChildren((*i),4);
- GetGimmickView()->AddIgnoreFile(*i);
- GetTreeHandler()->Remove(*i);
- }
-
- if(needRefresh && mLastLevel>1)
- {
- UpdateLevel(mLastLevel-2);
- }
- else if(mLastLevel>1)
- {
- UpdateLevel(mLastLevel-1);
- }
- else
- {
- UpdateLevel(mLastLevel);
- }
- }
- }
- else
- {
- // no need to incremente level
- mLastLevel = tempLevel;
- }
-
- if (erase && mLastLevel == 1 && i_save == "0")
- {
-
- RemoveAlertDlg *dial = new RemoveAlertDlg(this, crea::std2wx("Remove files"), wxSize(370,100));
- //dial->ShowModal();
- if (dial->ShowModal() == wxID_OK)
- {
- i_save = dial->isChecked() == false? "0" : "1";
- }
-
- }
- }
-
-
- //=====================================================================
- /// Updates a level of the view (adds or removes children, etc.)
- void WxTreeView::UpdateLevel( int level )
- {
- GimmickDebugMessage(1,
- GetTreeHandler()->GetTree().GetLabel()
- <<"WxTreeView::UpdateLevel(level "
- <<level
- <<")"
- <<std::endl);
-
- wxBusyCursor busy;
- RecursiveUpdateLevel(level);
- int i;
- for (i=0; i<level-1; i++)
- {
- if (!GetSplitter(i)->IsSplit())
- GetSplitter(i)->SplitVertically( GetCtrl(i), GetSplitter(i+1),
- 100 );
- }
- if (GetSplitter(i)->IsSplit()) GetSplitter(i)->Unsplit();
-
- }
- //=====================================================================
-
- //=====================================================================
- /// Recursive method called upon by UpdateLevel to refresh all windows
- void WxTreeView::RecursiveUpdateLevel( int level )
- {
- GimmickDebugMessage(1,
- GetTreeHandler()->GetTree().GetLabel()
- <<"WxTreeView::RecursiveUpdateLevel(level "
- <<level
- <<")"<<std::endl);
-
-
- const std::vector<tree::Node*>& sel(GetSelected(level));
-
- int l = level - 1;
-
- // to speed up inserting we hide the control temporarily
- GetCtrl(l)->Hide();
- GetCtrl(l)->DeleteAllItems();
-
- std::vector<tree::Node*>::const_iterator i;
-
- for (i=sel.begin(); i!=sel.end(); ++i)
- {
- GimmickDebugMessage(1,
- "adding children of '"
- <<(*i)->GetLabel()
- <<"'"
- <<std::endl);
- int _id=0;
-
- //Adds items and sets their attributes
-
- GetTreeHandler()->LoadChildren(*i,1);
- tree::Node::ChildrenListType::reverse_iterator j;
- for (j = (*i)->GetChildrenList().rbegin();
- j!= (*i)->GetChildrenList().rend();
- ++j)
- {
- GimmickDebugMessage(1,
- "adding children "
- <<(*j)->GetLabel()
- <<"'"
- <<std::endl);
-
- wxListItem item;
- item.SetMask(wxLIST_MASK_STATE |
- wxLIST_MASK_TEXT |
- // wxLIST_MASK_IMAGE |
- wxLIST_MASK_DATA |
- // wxLIST_MASK_WIDTH |
- wxLIST_MASK_FORMAT
- );
-
- ItemData* data = new ItemData();
- data->node = *j;
- data->id = _id;
-
- item.SetId(_id);
- item.SetData(data);
-
- _id++;
- GetCtrl(l)->InsertItem(item);
-
- //Setting attributes
- for (int k=0; k<GetCtrl(l)->GetColumnCount(); ++k)
- {
- std::string val;
- // Temporary correction : it works but no explanation about the problem FCY
-
- if(k==0 && level <3)
- {
- val = (*j)->GetAttribute("NumberOfChildren");
- }
- else
- val = (*j)->GetAttribute(mLevelList[l].key[k]);
- if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isDateEntry()) // Date
- {
- // std::cout << "["<<val<< "]" << std::endl;
- std::string valtmp(val);
- try
- {
- boost::gregorian::date d1(boost::gregorian::from_undelimited_string(val));
- val = to_iso_extended_string(d1);
- }
- catch (...)
- {
- val = valtmp;
- }
- // std::cout << "["<<val<< "]" << std::endl;
- }
- else if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isTimeEntry()) // Time
- {
- if ((val.size()>6) &&
- (val != "" || val != " "))
- val = val.substr(0,2) + " : "
- + val.substr(2,2) + " : "
- + val.substr(4,2);
- }
- else
- {
- if (val.size()==0) val = "?";
- }
- if (val.size()==0) val = "X";
- item.SetText( crea::std2wx(val));
- item.SetColumn(k);
-
- GetCtrl(l)->SetItem(item);
- }
- item.Clear();
-
- }
- }
-
- SortLevel(l);
- GetCtrl(l)->Show();
- }
- //=====================================================================
-
-
- //================================================================
- void WxTreeView::OnItemDeSelected(wxListEvent& event)
- {
- GimmickDebugMessage(1,
- GetTreeHandler()->GetTree().GetLabel()
- <<" WxTreeView::OnItemDeselected"<<std::endl);
- // retrieve the level
- wxObject* obj = event.GetEventObject();
- unsigned int level = 0;
- for (level = 0; level<mLevelList.size(); ++level)
- {
- if ( GetCtrl(level) == obj ) break;
- }
- SetSelectedUpToDate(level,false);
- // to allow a first selection in images TreeView
- if (level==mLevelList.size()-1)
- OnItemSelected(event);
- }
- //================================================================
-
- //================================================================
- void WxTreeView::OnItemSelected(wxListEvent& event)
- {
-
- GimmickDebugMessage(1,
- GetTreeHandler()->GetTree().GetLabel()
- <<" WxTreeView::OnItemSelected"<<std::endl);
-
- if (mIgnoreSelectedChanged)
- {
- GimmickDebugMessage(1,
- " mIgnoreSelectedChanged true: returning"
- <<std::endl);
- return;
- }
-
-
-
- wxListItem info;
- info.m_itemId = event.m_itemIndex;
- mLastSelected = event.m_itemIndex;
- // retrieve the level
- wxObject* obj = event.GetEventObject();
- unsigned int level = 0;
- for (level = 0; level<mLevelList.size(); ++level)
- {
- if ( GetCtrl(level) == obj ) break;
- }
- mLastLevel=level;
- GimmickDebugMessage(1,
- " Level "<<level+1
- <<std::endl);
-
- // Update the children level (if selection not at last level)
- if (level<mLevelList.size()-1)
- {
-
- UpdateLevel( level + 2 );
- // Reset the viewer setting the default image
- GetGimmickView()->ClearSelection();
- }
- // Select all images if the selection is at series level
- if (level==mLevelList.size()-2)
- SelectAll(level+1);
- // Validate selected images if the selection is at image level
- if (level==(mLevelList.size()-1)) //&&mProcess)
- {
- if(event.GetEventType()==wxEVT_COMMAND_LIST_ITEM_SELECTED)
- {
- ValidateSelectedImages (true);
- }
- else
- {
- ValidateSelectedImages (false);
- }
- }
-
- }
- //================================================================
-
- //================================================================
- void WxTreeView::SelectAll(int level)
- {
- long item = -1;
- // int level=mLevelList.size()-1;
- for ( ;; )
- {
- item = GetCtrl(level)->GetNextItem(item,
- wxLIST_NEXT_ALL);
- if ( item == -1 )
- break;
-
- if(item==(GetCtrl(level)->GetItemCount()-1))
- {
- mIgnoreSelectedChanged = false;//mProcess=true;
- }
- else
- {
- mIgnoreSelectedChanged = true;// mProcess=false;
- }
- GetCtrl(level)->SetItemState(item,wxLIST_STATE_SELECTED, wxLIST_MASK_STATE
- | wxLIST_MASK_TEXT |wxLIST_MASK_IMAGE | wxLIST_MASK_DATA | wxLIST_MASK_WIDTH | wxLIST_MASK_FORMAT);
- }
- }
-
- //================================================================
- //================================================================
-
- void WxTreeView::OnColClick(wxListEvent& event)
- {
- mColumnSelected = event.m_col;
- wxPoint clientpt;
- clientpt.x = wxGetMousePosition().x - this->GetScreenPosition().x;
- clientpt.y = wxGetMousePosition().y - this->GetScreenPosition().y;
- senderCtrl = event.GetEventObject();
- unsigned int level = 0;
- for (level = 0; level<mLevelList.size(); ++level)
- {
- if ( GetCtrl(level) == senderCtrl ) break;
- }
- PopupMenu(menu, clientpt);
-
- }
-
- //================================================================
- //================================================================
-
- void WxTreeView::OnItemMenu(wxListEvent &event)
- {
- wxPoint clientpt;
- clientpt.x = wxGetMousePosition().x - this->GetScreenPosition().x;
- clientpt.y = wxGetMousePosition().y - this->GetScreenPosition().y;
- senderCtrl = event.GetEventObject();
- unsigned int level = 0;
- for (level = 0; level<mLevelList.size(); ++level)
- {
- if ( GetCtrl(level) == senderCtrl ) break;
- }
- long* ptr=0;
- int flag;
- mLastRightLevel=level;
- mLastRightSelected=GetCtrl(level)->HitTest(wxPoint(0,clientpt.y-8),flag,ptr);
- PopupMenu(menuItem, clientpt);
-
- }
-
- //================================================================
- //================================================================
-
- void WxTreeView::OnPopupFilter(wxCommandEvent& event)
- {
- wxBusyCursor busy;
- GimmickDebugMessage(7,
- "WxTreeView::OnEndLabelEdit"
- <<std::endl);
- unsigned int level = 0;
- for (level = 0; level<mLevelList.size(); ++level)
- {
- if ( GetCtrl(level) == senderCtrl ) break;
- }
- std::string filter = crea::wx2std(wxGetTextFromUser(_T("Enter the filter to apply"), _T("Filter On Column")));
-
- std::string att;
-
- long it = -1;
- UpdateLevel(level+1);
-
- std::vector<long> items;
- bool in=false;
- int del=0;
- for ( ;; )
- {
- it = GetCtrl(level)->GetNextItem(it,
- wxLIST_NEXT_ALL);
- if ( it == -1 )
- break;
-
- long adr = GetCtrl(level)->GetItemData(it);
- tree::Node* nod = ((ItemData*)adr)->node;
- att=(*nod).GetAttribute(mLevelList[level].key[mColumnSelected]);
-
-
- if(att.find(filter)>900)
- {
-
- if(!in)
- {
- in=true;
- }
- else
- {
- del+=1;
- }
-
- items.push_back(it-del);
- }
-
- }
- std::vector<long>::iterator iter;
- for(iter=items.begin();iter!=items.end();++iter)
- {
- GetCtrl(level)->DeleteItem(*iter);
- }
- GetGimmickView()->ClearSelection();
- }
- //================================================================
-
- //================================================================
- void WxTreeView::OnPopupSort(wxCommandEvent& event)
- {
- wxBusyCursor busy;
- unsigned int level = 0;
- for (level = 0; level<mLevelList.size(); ++level)
- {
- if ( GetCtrl(level) == senderCtrl ) break;
- }
- mLevelList[level].SortColumn = mColumnSelected;
-
- if(event.GetId()==mAscendingID)
- {
- mLevelList[level].SortAscending = true;
- }
- else if(event.GetId()==mDescendingID)
- {
- mLevelList[level].SortAscending = false;
- }
-
- SortLevel(level);
- }
- //================================================================
-
- //================================================================
- void WxTreeView::OnLocalCopy(wxCommandEvent& event)
- {
- wxBusyCursor busy;
-
- unsigned int tempLevel = mLastLevel;
- mLastLevel+=1;
- const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
-
- if(sel.size() != 0)
- {
- bool copy=false;
- std::stringstream out;
- std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
- out<<"Copy ";
- out<<sel.size();
- if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
- {
- out<<" "<<levelName;
- out<<"s to .gimmick?";
- }
- else
- {
- out<<" "<<GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName()<<" to .gimmick?";
- }
- if (wxMessageBox(crea::std2wx(out.str()),
- _T("Remove Files"),
- wxYES_NO,this ) == wxYES)
- {
- copy = true;
- }
- if(copy)
- {
- std::vector<std::string> s;
- GetFilenamesAsString(sel,s);
- GetGimmickView()->CopyFiles(s);
- }
- }
- else
- {
- mLastLevel = tempLevel;
- }
-
-
- }
- //================================================================
-
- //================================================================
- void WxTreeView::OnEditField(wxCommandEvent& event)
- {
- if(mLastRightSelected!=-1)
- {
- tree::Node* node=((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node;
- tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- std::vector<std::string> names;
- std::vector<std::string> keys;
- for (a = GetTreeHandler()->GetTree().GetAttributeDescriptorList(mLastRightLevel+1).begin();
- a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(mLastRightLevel+1).end();
- ++a)
- {
- if(a->GetFlags()==creaImageIO::tree::AttributeDescriptor::EDITABLE)
- {
- names.push_back(a->GetName());
- keys.push_back(a->GetKey());
- }
- }
- GetGimmickView()->CreateEditFieldsDialog(node,names,keys);
- }
- }
-
- //================================================================
-
- //================================================================
-
- void WxTreeView::OnExportToStorage(wxCommandEvent &event)
- {
- std::vector<std::string> filesname;
- std::vector<tree::Node*> nodes;
- nodes.push_back(((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node);
- GetFilenamesAsString(nodes,filesname);
- GetGimmickView()->ExportToStorage(filesname);
- }
-
- //================================================================
-
- //================================================================
-
- void WxTreeView::OnDumpTags(wxCommandEvent &event)
- {
- if(mLastRightSelected!=-1)
- {
- tree::Node* node=((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node;
- tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- std::vector<std::string> names;
- std::vector<std::string> keys;
- for (a = GetTreeHandler()->GetTree().GetAttributeDescriptorList(mLastRightLevel+1).begin();
- a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(mLastRightLevel+1).end();
- ++a)
- {
- if(a->GetKey()=="FullFileName")
- {
- GetGimmickView()->DumpTags(node->GetAttribute("FullFileName"));
- return;
- }
- }
- }
- }
-
-
- //================================================================
-
- //================================================================
- void WxTreeView::SortLevel(int level)
- {
- GimmickDebugMessage(1,
- "WxTreeView::SortLevel("
- <<level<<")"
- <<std::endl);
- //Obtain the column name and the level that needs to be organized
-
- // int l = level - 1;
- //Sets the data for the items to be sorted
- // std::string att;
- unsigned int ty=0;
- int nbselected = 0;
- int n = GetCtrl(level)->GetItemCount();
- for (int i = 0; i < n; i++)
- {
-
- //Gets current item data
- ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(i);
-
- //Extracts the node and the type of attribute
- tree::Node* nod = data->node;
- if(i==0)
- {
- (*nod).GetAttributeDescriptor
- (mLevelList[level].key[mLevelList[level].SortColumn])
- .DecodeType( ty );
- }
- //Obtains the organizing attribute
- data->attr = & (*nod).GetAttribute
- (mLevelList[level].key[mLevelList[level].SortColumn]);
- //Selected ?
- data->selected = false;
- if (GetCtrl(level)->GetItemState(i,wxLIST_STATE_SELECTED)>0)
- {
- data->selected = true;
- nbselected++;
- }
-
- }
- GimmickDebugMessage(1,
- "WxTreeView::OnSort : "
- <<nbselected<<" selected before sorting"
- <<std::endl);
-
- mIgnoreSelectedChanged = true;
- //
- if (mLevelList[level].SortAscending)
- {
-
- if(ty==1)
- {
- GetCtrl(level)->SortItems(CompareFunctionInts, 0);
- }
- else
- {
- GetCtrl(level)->SortItems(CompareFunctionStrings, 0);
- }
-
- }
- else
- {
- if(ty==1)
- {
- GetCtrl(level)->SortItems(CompareFunctionInts, 1);
- }
- else
- {
- GetCtrl(level)->SortItems(CompareFunctionStrings, 1);
- }
- }
-
-
- // Reselects the unselected
- n = GetCtrl(level)->GetItemCount();
- int after = 0;
- for (int i = 0; i < n; i++)
- {
-
- //Gets current item data
- ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(i);
-
- // long item = -1;
- // for ( ;; )
- // {
- // item = GetCtrl(level)->GetNextItem(item,wxLIST_NEXT_ALL);
- // if ( item == -1 ) break;
- //Gets current item data
- // ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(item);
- // was selected ?
-
- if (data->selected)
- {
- nbselected--;
- if (nbselected==0)
- {
- // if it is the last one we must process the selection
- mIgnoreSelectedChanged = false;
- }
- GetCtrl(level)->SetItemState(i,
- wxLIST_STATE_SELECTED,
- wxLIST_MASK_STATE
- | wxLIST_MASK_TEXT
- | wxLIST_MASK_IMAGE
- | wxLIST_MASK_DATA
- | wxLIST_MASK_WIDTH
- | wxLIST_MASK_FORMAT);
- }
- if (GetCtrl(level)->GetItemState(i,wxLIST_STATE_SELECTED)>0)
- {
- after++;
- }
-
-
- }
- mIgnoreSelectedChanged = false;
- GimmickDebugMessage(1,
- "WxTreeView::SortLevel : "
- <<after<<" selected after sorting"
- <<std::endl);
-
- }
- //================================================================
-
-
- //================================================================
- void WxTreeView::ValidateSelectedImages(bool isSelection)
- {
- GimmickDebugMessage(7,
- "WxTreeView::ValidateSelectedImages"
- <<std::endl);
- const std::vector<tree::Node*>& sel(GetSelected(mLevelList.size()+1));
- GetGimmickView()->OnSelectionChange(sel,
- isSelection,(mLastSelected-1),
- !mIgnoreSelectedChanged);
-
- }
- //================================================================
-
-
- //================================================================
- void WxTreeView::GetNodes(std::vector<tree::Node*>& nodes, bool direction)
- {
- long item = mLastSelected;
- int level=mLevelList.size()-1;
- //Gets current item data
- long adr = GetCtrl(level)->GetItemData(item);
- //Extracts the node
- tree::Node* nod = ((ItemData*)adr)->node;
- for ( ;; )
- {
- if(direction)
- {
- item = GetCtrl(level)->GetNextItem(item,
- wxLIST_NEXT_ABOVE);
- }
- else
- {
- item = GetCtrl(level)->GetNextItem(item,
- wxLIST_NEXT_BELOW);
- }
- if ( item == -1 || item==0 )
- {
- break;
- }
- if(GetCtrl(level)->GetItemState(item, wxLIST_STATE_SELECTED)==0 )
- {
-
- adr = GetCtrl(level)->GetItemData(item);
- nod = ((ItemData*)adr)->node;
- nodes.push_back(nod);
- }
- }
-
- }
- //================================================================
- //=================================================
- void WxTreeView::OnKeyDown(wxListEvent &event)
- {
- if(event.GetKeyCode() == WXK_DELETE)
- {
- wxBusyCursor busy;
- std::string temp = "0";
- RemoveSelected(temp);
- GetGimmickView()->ClearSelection();
- }
-
- }
- //================================================================
-
- //================================================================
- // Should be in another place : not specific !
- void WxTreeView::GetSelectedAsString(std::vector<std::string>&s)
- {
- int level=mLevelList.size();
- const std::vector<tree::Node*>& sel=GetSelected(level+1);
- std::vector<tree::Node*>::const_iterator i;
-
- for (i=sel.begin(); i!=sel.end(); ++i)
- {
- std::string filename=(*i)->GetAttribute("FullFileName");
- s.push_back(filename);
- }
- }
-
- //================================================================
- void WxTreeView::GetFilenamesAsString(const std::vector<tree::Node*>& nodes, std::vector<std::string>&s)
- {
- std::vector<tree::Node*>::const_iterator i;
-
- for (i=nodes.begin(); i!=nodes.end(); ++i)
- {
- if((*i)->GetLevel()<mLevelList.size())
- {
- GetTreeHandler()->LoadChildren(*i,0);
- GetFilenamesAsString((*i)->GetChildrenList(),s);
- }
- else
- {
- std::string filename=(*i)->GetAttribute("FullFileName");
- s.push_back(filename);
- }
- }
- }
-
- //================================================================
-
- //================================================================
- void WxTreeView::GetAttributes(std::vector<std::string>& areShown, std::vector<std::string>& notShown, int level)
- {
- areShown.clear();
- notShown.clear();
- tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = GetTreeHandler()->GetTree().GetAttributeDescriptorList(level).begin();
- a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(level).end();
- ++a)
- {
- if(a->GetFlags()==creaImageIO::tree::AttributeDescriptor::EDITABLE && IsAttributeVisible(a->GetName(),level))
- {
- areShown.push_back(a->GetName());
- }
- }
- notShown=mLevelList[level-1].notShownAtts;
- }
-
- //================================================================
- void WxTreeView::SetNonVisibleAttributes(const std::vector<std::string>& notShown, int nlevel)
- {
- mLevelList[nlevel].notShownAtts=notShown;
- }
-
- //================================================================
- void WxTreeView::CreateCtrl(std::vector<std::string>& notShown, int nlevel)
- {
- int ctrl_style = wxLC_REPORT | wxLC_VRULES;
- int col_style = wxLIST_FORMAT_LEFT;
- LevelType level;
- mLevelList[nlevel].SelectedUpToDate = true;
- mLevelList[nlevel].SortColumn = 0;
- mLevelList[nlevel].key.clear();
-
- mLevelList[nlevel].wxCtrl = new wxListCtrl(mLevelList[nlevel].wxSplitter,
- nlevel,
- wxDefaultPosition,
- wxDefaultSize,
- ctrl_style);
- wxWindow* oldWin=mLevelList[nlevel].wxSplitter->GetWindow1();
- mLevelList[nlevel].wxSplitter->ReplaceWindow(oldWin,mLevelList[nlevel].wxCtrl);
- mLevelList[nlevel].wxSplitter->Initialize(mLevelList[nlevel].wxCtrl);
-
- // Create the columns : one for each attribute of the level
- int col = 0;
- std::string title;
-
- tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
- for (a = GetTreeHandler()->GetTree().GetAttributeDescriptorList(nlevel+1).begin();
- a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(nlevel+1).end();
- ++a)
-
- {
- if(a->GetFlags()!=creaImageIO::tree::AttributeDescriptor::PRIVATE && IsAttributeVisible(a->GetName(),nlevel+1))
- {
- title=a->GetName();
- std::string temp = a->GetKey();
- if (temp.compare("ID") != 0)
- {
- mLevelList[nlevel].wxCtrl->InsertColumn(col,
- crea::std2wx(title),
- col_style);
- col++;
- }
- mLevelList[nlevel].key.push_back(a->GetKey());
- }
-
- }
- oldWin->Destroy();
- UpdateLevel(1);
- }
-
- //================================================================
- bool WxTreeView::IsAttributeVisible(const std::string& val, int level)
- {
- std::vector<std::string> ns=mLevelList[level-1].notShownAtts;
- std::vector<std::string>::iterator it;
- bool found=false;
- for(it=ns.begin();it!=ns.end()&&!found;++it)
- {
- if(val.compare(*it)==0)
- {
- found=true;
- }
- }
-
- return !found;
- }
- //================================================================
- //================================================================
-
- RemoveAlertDlg::RemoveAlertDlg(wxWindow *parent,
- wxString title,
- const wxSize& size)
- : wxDialog( parent,
- wxID_ANY,
- title,
- wxDefaultPosition,
- size,
- wxDEFAULT_DIALOG_STYLE)
- {
- wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
-
- //std::string out("To reload deleted patient, you should synchronize your database before."); // JPR
- //wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY,crea::std2wx(out),wxDefaultPosition, wxSize(500,20));
- wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY,
- _T("To reload deleted patient, you should synchronize your database before."),
- wxDefaultPosition, wxSize(500,20));
- mcheck = new wxCheckBox(this, 5478, _T("Do not display this warning again!"));
- Connect( mcheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED , (wxObjectEventFunction) &RemoveAlertDlg::onCheck );
- wxSizer* buttonsSizer = this->CreateSeparatedButtonSizer(wxOK|wxCANCEL);
-
- topsizer->Add(text);
- topsizer->Add(mcheck,0,wxGROW);
- topsizer->Add(buttonsSizer,0,wxGROW);
- SetSizer(topsizer, true);
- mSave = false;
- Layout();
- }
- RemoveAlertDlg::~RemoveAlertDlg(){};
- bool RemoveAlertDlg::isChecked()
- {
- return mSave;
- }
- void RemoveAlertDlg::onCheck(wxCommandEvent &Event)
- {
- mSave = mcheck->IsChecked();
- }
-
-
- //================================================================
- //================================================================
- BEGIN_EVENT_TABLE(WxTreeView, wxPanel)
- /*
- EVT_SIZE(MyFrame::OnSize)
-
- EVT_MENU(LIST_QUIT, MyFrame::OnQuit)
- EVT_MENU(LIST_ABOUT, MyFrame::OnAbout)
- EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView)
- EVT_MENU(LIST_REPORT_VIEW, MyFrame::OnReportView)
- EVT_MENU(LIST_ICON_VIEW, MyFrame::OnIconView)
- EVT_MENU(LIST_ICON_TEXT_VIEW, MyFrame::OnIconTextView)
- EVT_MENU(LIST_SMALL_ICON_VIEW, MyFrame::OnSmallIconView)
- EVT_MENU(LIST_SMALL_ICON_TEXT_VIEW, MyFrame::OnSmallIconTextView)
- EVT_MENU(LIST_VIRTUAL_VIEW, MyFrame::OnVirtualView)
- EVT_MENU(LIST_SMALL_VIRTUAL_VIEW, MyFrame::OnSmallVirtualView)
-
- EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast)
- EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
- EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll)
- EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll)
- EVT_MENU(LIST_DELETE, MyFrame::OnDelete)
- EVT_MENU(LIST_ADD, MyFrame::OnAdd)
- EVT_MENU(LIST_EDIT, MyFrame::OnEdit)
- EVT_MENU(LIST_DELETE_ALL, MyFrame::OnDeleteAll)
- EVT_MENU(LIST_SORT, MyFrame::OnSort)
- EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour)
- EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
- EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
- EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo)
- EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo)
- EVT_MENU(LIST_FREEZE, MyFrame::OnFreeze)
- EVT_MENU(LIST_THAW, MyFrame::OnThaw)
- EVT_MENU(LIST_TOGGLE_LINES, MyFrame::OnToggleLines)
- EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric)
-
- EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateShowColInfo)
- EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel)
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl)
- EVT_LIST_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnBeginDrag)
- EVT_LIST_BEGIN_RDRAG(LIST_CTRL, MyListCtrl::OnBeginRDrag)
-
- EVT_LIST_BEGIN_LABEL_EDIT(-1, WxTreeView::OnBeginLabelEdit)
- EVT_LIST_END_LABEL_EDIT(-1, WxTreeView::OnEndLabelEdit)
-
- EVT_LIST_DELETE_ITEM(LIST_CTRL, MyListCtrl::OnDeleteItem)
- EVT_LIST_DELETE_ALL_ITEMS(LIST_CTRL, MyListCtrl::OnDeleteAllItems)
-#if WXWIN_COMPATIBILITY_2_4
- EVT_LIST_GET_INFO(LIST_CTRL, MyListCtrl::OnGetInfo)
- EVT_LIST_SET_INFO(LIST_CTRL, MyListCtrl::OnSetInfo)
-#endif
- */
- EVT_LIST_KEY_DOWN(-1, WxTreeView::OnKeyDown)
- EVT_LIST_ITEM_SELECTED(-1, WxTreeView::OnItemSelected)
- EVT_LIST_ITEM_RIGHT_CLICK(-1, WxTreeView::OnItemMenu)
- EVT_LIST_ITEM_DESELECTED(-1, WxTreeView::OnItemDeSelected)
- /*
- EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown)
- EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated)
- EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused)
-*/
- EVT_LIST_COL_RIGHT_CLICK(-1, WxTreeView::OnColClick)
-
- EVT_LIST_COL_CLICK(-1, WxTreeView::OnColClick)
-
- //EVT_LEFT_DOWN(WxTreeView::OnMouseClick)
- /*
- EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnColBeginDrag)
- EVT_LIST_COL_DRAGGING(LIST_CTRL, MyListCtrl::OnColDragging)
- EVT_LIST_COL_END_DRAG(LIST_CTRL, MyListCtrl::OnColEndDrag)
-
- EVT_LIST_CACHE_HINT(LIST_CTRL, MyListCtrl::OnCacheHint)
-
-#if USE_CONTEXT_MENU
- EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu)
-#endif
- EVT_CHAR(MyListCtrl::OnChar)
-
- EVT_RIGHT_DOWN(MyListCtrl::OnRightClick)
- */
-END_EVENT_TABLE()
-
-} // EO namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOWxTreeView_h_INCLUDED__
-#define __creaImageIOWxTreeView_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-
-#include <creaImageIOTreeView.h>
-#include <creaWx.h>
-
-#include <wx/listctrl.h>
-#include <wx/splitter.h>
-//#include <vector>
-const std::string empty_string("");
-namespace creaImageIO
-{
-
- //=====================================================================
- /// Data stored by the list items
- struct ItemData
- {
- ItemData() : node(0), id(-1), attr(&empty_string) {}
- // The corresponding Node
- tree::Node* node;
- // The id ?
- int id;
- // The pointer on the current attribute string to sort on
- const std::string* attr;
- // Was the item previously selected ?
- // Useful for reselecting the item after sort
- bool selected;
- };
- /**
- * \ingroup View
- */
- //=====================================================================
-
- //=====================================================================
- /// Abstract class that handles the view of a Tree through its TreeHandler
- class WxTreeView : public wxPanel, virtual public TreeView
- {
- public:
- /// Ctor
- WxTreeView(TreeHandler*, GimmickView*,
- wxWindow* parent, const wxWindowID id);
- /// Virtual destructor
- virtual ~WxTreeView();
-
-
- /// Updates the view of a level given the selected items of upper level
- virtual void UpdateLevel( int );
-
- ///Removes selected nodes on given level
- virtual void RemoveSelected(std::string &i_save);
-
- ///Returns the last selected level
- virtual unsigned int GetLastSelectedLevel(){return mLastLevel;}
-
- /// Callback for item selection
- void OnItemSelected(wxListEvent& event);
-
- /// Callback for item deselection
- void OnItemDeSelected(wxListEvent& event);
-
- /// Callback for column click
- void OnColClick(wxListEvent& event);
-
- /// Callback when the user needs the items sorted
- void OnPopupSort(wxCommandEvent& event);
-
- ///Callback when the user need the items filtered
- void OnPopupFilter(wxCommandEvent& event);
-
- ///Callback when the user needs the item copied to the local disk
- void OnLocalCopy(wxCommandEvent& event);
-
- ///Callback when the user needs to edit a field
- void OnEditField(wxCommandEvent& event);
-
- ///Callback when the user needs to display alll dicom tags for a file
- void OnDumpTags(wxCommandEvent &event);
-
- ///Callback when the user needs to transfer data from storage to storage
- void OnExportToStorage(wxCommandEvent &event);
-
- ///Callback on mouse click
- void OnMouseClick(wxMouseEvent& event);
-
- /// Displays a menu for items
- void OnItemMenu(wxListEvent &event);
-
- /// Gets the attributes that are being shown and the ones that have been blocked on a specific level
- void GetAttributes(std::vector<std::string>& areShown, std::vector<std::string>& notShown, int level);
-
- ///Sets the non visible attributes and refreshes the GUI
- void SetNonVisibleAttributes(const std::vector<std::string>& notShown, int level);
-
- ///Creates a new listctrl
- void CreateCtrl(std::vector<std::string>& notShown, int nlevel);
-
- ///Returns true if the attribute passed as a parameter is visible or not
- bool IsAttributeVisible(const std::string& val, int level);
-
- /// Actual processing of item selection/deselection
- /// Called by OnItemSelected and OnItemDeSelected
- // void ProcessItem
- private:
- wxBoxSizer *msizer;
- /// The struct holding the data for one level
- /// Holds the wx control and other data
- /// such as the vector of attribute keys corresponding to the columns
- struct LevelType
- {
- // The List Control
- wxListCtrl* wxCtrl;
- wxSplitterWindow* wxSplitter;
- std::vector<std::string> key;
- // The vector of currently selected nodes of the level
- std::vector<tree::Node*> Selected;
- // True iff the vector Selected is up to date
- bool SelectedUpToDate;
- // The column used for sorting
- unsigned int SortColumn;
- ///Boolean that defines the direction of the sort
- ///True is ascending order and false is descending
- bool SortAscending;
- //The vector of not shown attributes
- std::vector<std::string> notShownAtts;
- };
- /// The vector of levels : one for each level of the tree
- std::vector<LevelType> mLevelList;
-
- /// return the wxListCtrl of one level
- wxListCtrl* GetCtrl(int l) { return mLevelList[l].wxCtrl; }
- /// return the wxSplitter of one level
- wxSplitterWindow* GetSplitter(int l) { return mLevelList[l].wxSplitter; }
- //Returns the maximum number of levels
- int GetNumberOfLevels(){ return mLevelList.size(); }
- /// Gets the user selected data from the level passed as a parameter
- /// Updates the vector if necessary
- const std::vector<tree::Node*>& GetSelected(int level);
- /// Set the bool SelectedUpToDate for level l
- void SetSelectedUpToDate(int l, bool v) { mLevelList[l].SelectedUpToDate = v; }
- /// Get the bool SelectedUpToDate for level l
- bool GetSelectedUpToDate(int l) { return mLevelList[l].SelectedUpToDate; }
- ///Validates the selected images
- void ValidateSelectedImages(bool isSelection);
- ///Gets selected filenames
- void GetSelectedAsString(std::vector<std::string>&s);
- ///Gets the filenames of the given nodes and returns them on the given vector. Is recursive.
- void GetFilenamesAsString(const std::vector<tree::Node*>& nodes, std::vector<std::string>&s);
- /// Gets the next nodes on the list, be it up(true) or down(false).
- void GetNodes(std::vector<tree::Node*>& nodes, bool direction);
- /// Updates the view of a level given the selected items of upper level
- /// Recursive method
- virtual void RecursiveUpdateLevel( int );
- ///Selects all the elements of a level
- void SelectAll(int level);
- ///UnSelects all the elements of a level
- void UnSelectAll(int level);
-
- void OnKeyDown(wxListEvent &event);
- /// Sorts the level
- void SortLevel(int level);
-
- /// Currently Selected Column
- int mColumnSelected;
- ///The last selected item on the list (left click)
- long mLastSelected;
-
- ///The last selected item on the list (right click)
- long mLastRightSelected;
-
- ///The last selected level (by right click)
- int mLastRightLevel;
- ///The color map
- typedef std::map<tree::Node*,wxColour> ColorMap;
- typedef std::pair<tree::Node*,wxColour> NodeColorPair;
- ColorMap mColorMap;
- ///Initial color palette
- std::vector<std::string> mColorPalette;
-
- wxMenu* menu;
-
- wxObject* senderCtrl;
- int mAscendingID;
- int mDescendingID;
- int mFilterID;
- unsigned int mLastLevel;
-
- wxMenu* menuItem;
- wxMenu *subExportMenu;
- int mAnonymizingID;
- int mLocalCopyID;
- int mEditFieldID;
- int mDumpID;
- int mExportID;
- int mExport2StorageID;
-
- // If set to true then OnSelectedChanged returns immediately.
- // Used to do avoid useless process during multiple selections
- // or sorting
- bool mIgnoreSelectedChanged;
-
- DECLARE_EVENT_TABLE()
- };
- // EO class WxTreeView
- //=====================================================================
-
- class RemoveAlertDlg : public wxDialog
- {
- public:
- RemoveAlertDlg(wxWindow *parent,
- wxString title,
- const wxSize& size);
- ~RemoveAlertDlg();
-
- bool isChecked();
-
- private :
- void onCheck(wxCommandEvent &Event);
- bool mSave;
- wxCheckBox *mcheck;
-
- };
-
-
-} // EO namespace creaImageIO
-
-
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-
-#include <creaImageIOWxViewer.h>
-#include <creaImageIOSystem.h>
-#include <fstream>
-#include <vtkCamera.h>
-#include <vtkRenderer.h>
-#include <vtkImageData.h>
-#include <creawxVTKRenderWindowInteractor.h>
-#include <creaMessageManager.h>
-#include <stdio.h>
-#include <time.h>
-
-
-using namespace crea;
-
-namespace creaImageIO
-{
-
- //=====================================================================
-
- //=====================================================================
- class WxViewerPlayer: public wxThread
- {
- public:
- WxViewerPlayer(WxViewer* v) :
- mWxViewer(v)
- {}
-
- void* Entry();
- void OnExit();
-
- private:
-
- WxViewer* mWxViewer;
- };
-
- //=====================================================================
-
-
-
-
-
- //=====================================================================
- // CTor
- WxViewer::WxViewer(wxWindow *parent,
- wxWindowID id,
- wxString title,
- const wxPoint& pos,
- const wxSize& size)
- : wxPanel( parent,
- id,
- pos,
- size)
- {
- wxMutexLocker lock(mMutex);
- GimmickDebugMessage(6,"WxViewer::WxViewer"
- <<std::endl);
-
- mNeedRefresh = false;
- mLastImageShown = NULL;
-
- // previewer
- mInteractor = new crea::creawxVTKRenderWindowInteractor(this,-1);
- mInteractor->UseCaptureMouseOn();
-
- mViewer = vtkImageViewer2::New();
- mViewer->SetupInteractor ( mInteractor );
-
- mCurrent = 0;
- mPlayer = 0;
-
- // Grid to place checkbox and slider
- mflexSizer = new wxFlexGridSizer(1,2,1,1);
- //Slider
- mslide = new wxSlider(this,-1,0,0,1, wxDefaultPosition, wxSize(400,40), wxSL_HORIZONTAL | wxSL_LABELS);
- Connect( mslide->GetId(), wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &WxViewer::OnSlide );
- //CheckBox
- mcheck = new wxCheckBox(this,5123,crea::std2wx("Cine Loop"));
- Connect( mcheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED , (wxObjectEventFunction) &WxViewer::OnCineLoop );
- mcheck->SetValue(false);
- mflexSizer->Add(mcheck,0, wxFIXED_MINSIZE);
- mflexSizer-> Add( mslide,1,wxALIGN_CENTER | wxFIXED_MINSIZE );
-
- // Sizer for Previewer and GridSizer
- mtopSizer = new wxBoxSizer(wxVERTICAL);
- mtopSizer->Add(mflexSizer,0);
- mtopSizer-> Add( mInteractor ,1,wxGROW,0);
- SetSizer(mtopSizer,true);
-
- Update();
- Layout();
- }
- //=====================================================================
-
- //=====================================================================
- /// Destructor
- WxViewer::~WxViewer()
- {
- wxMutexLocker lock(mMutex);
- GimmickDebugMessage(6,"WxViewer::~WxViewer"
- <<std::endl);
- // TO DO : desallocate cleanly
- if(mPlayer)
- {
- mPlayer->Pause();
- mPlayer->Delete();
- mPlayer = 0;
- }
- delete mInteractor;
- //delete mslide;
- //delete mflexSizer;
- }
- //=====================================================================
-
- //================================================================
- void WxViewer::SetImageVector(std::vector<boost::shared_ptr<ImagePointerHolder> >& pointers)
- {
- wxMutexLocker lock(mMutex);
- GimmickDebugMessage(6,"WxViewer::SetImageVector"<<std::endl);
- imagePointers=pointers;
-
- mslide->SetMax(pointers.size());
- // Refresh don't work, TO MODIFY
- mslide->Refresh();
- mslide->ClearTicks();
- mslide->Hide();
- mslide->Show();
- StartPlayer();
- }
-
- //================================================================
-
- void WxViewer::ShowNextImage()
- {
-
-
- mMutex.Unlock();
- wxMutexLocker lock(mMutex);
-
-
- GimmickMessage(2,"WxViewer::ShowNextImage() "
- <<mCurrent+1<<"/"
- <<imagePointers.size()<<std::endl);
-
- if(imagePointers.size()>0)
- {
- if (mCurrent<imagePointers.size())
- {
- boost::shared_ptr<ImagePointerHolder> iph = imagePointers[mCurrent];
- //ImagePointerHolder* iph= imagePointers[mCurrent];
- vtkImageData* currIm=iph->Get();
- ShowImage(currIm);
- if ( currIm != mLastImageShown )
- {
- mNeedRefresh = true;
- mLastImageShown = currIm;
- }
- mCurrent++;
- }
- else
- {
- mCurrent = 0;
- //ImagePointerHolder* iph=imagePointers[mCurrent];
- boost::shared_ptr<ImagePointerHolder> iph = imagePointers[mCurrent];
- vtkImageData* currIm=iph->Get();
- ShowImage(currIm);
- if ( currIm != mLastImageShown )
- {
- mNeedRefresh = true;
- mLastImageShown = currIm;
- }
- mCurrent++;
- }
- }
- }
- //================================================================
-
- //=====================================================================
- void WxViewer::ShowImage(vtkImageData* im)
- {
- GimmickDebugMessage(6,"WxViewer::ShowImage"
- <<std::endl);
- if (im==0) return;
-
- mViewer->SetInput(im);
-
- mViewer->SetSlice( 0 );
-
- int x1,x2,y1,y2,z1,z2;
- double spx,spy,spz;
- im->Update();
-
-//std::cout << "in WxViewer::ShowImage PrintSelf() =";
-//im->PrintSelf(std::cout, vtkIndent(2));
-
- im->GetSpacing(spx,spy,spz);
- //im->GetExtent (x1,x2,y1,y2,z1,z2); // JPR
- im->GetWholeExtent (x1,x2,y1,y2,z1,z2);
-/*
-std::cout << "in WxViewer::ShowImage GetWholeExtent ext =";
- std::cout << " [x1]=" << x1;
- std::cout << " [x2]=" << x2;
- std::cout << " [y1]=" << y1;
- std::cout << " [y2]=" << y2;
- std::cout << " [z1]=" << z1;
- std::cout << " [z2]=" << z2;
-std::cout << std::endl;
-*/
- if ((x1!=mx1) ||
- (x2!=mx2) ||
- (y1!=my1) ||
- (y2!=my2) ||
- (z1!=mz1) ||
- (z2!=mz2) ||
- (spx!=mspx) ||
- (spy!=mspy) ||
- (spz!=mspz)
- )
- {
- mx1 = x1;
- mx2 = x2;
- my1 = y1;
- my2 = y2;
- mz1 = z1;
- mz2 = z2;
- mspx = spx;
- mspy = spy;
- mspz = spz;
-
- double *range = im->GetScalarRange();
- mViewer->SetColorWindow(range[1] - range[0]);
- mViewer->SetColorLevel(0.5 * (range[1] + range[0]));
-
- mViewer->GetRenderer()->ResetCamera();
- double bounds[6];
-
- mViewer->GetRenderer()->ComputeVisiblePropBounds(bounds);
-
- mViewer->GetRenderer()->ResetCameraClippingRange(bounds);
- mViewer->GetRenderer()->SetBackground(0.1,0.1,0.2);
- }
- }
- //================================================================
-
- //================================================================
- bool WxViewer::RefreshIfNecessary()
- {
- if (mNeedRefresh)
- {
- GimmickDebugMessage(10,"WxViewer : Refreshing"<<std::endl);
-
- mInteractor->Render();
- mNeedRefresh = false;
- return true;
- }
- return false;
- }
- //================================================================
-
- //==================================================
- void WxViewer::StopPlayer()
- {
- wxMutexLocker lock(mMutex);
- if (mPlayer==0 ) return;
- mPlayer->Delete();
- mPlayer=0;
- }
- //================================================================
-
- //==================================================
- void WxViewer::StartPlayer()
- {
- if(mcheck->IsChecked())
- {
- // wxMutexLocker lock(mMutex);
- if (mPlayer != 0) return;
- mPlayer = new WxViewerPlayer(this);
- mPlayer->Create();
- mPlayer->Run();
- }
- else
- {
- ShowNextImage();
- }
- }
-
- //================================================================
-
- //==================================================
-
- void WxViewer::OnCineLoop(wxCommandEvent &Event)
- {
- if(!mcheck->IsChecked())
- {
- mPlayer->Pause();
- mPlayer->Delete();
- mPlayer = 0;
- }
- StartPlayer();
- }
-
- //================================================================
-
- //==================================================
-
- void WxViewer::OnSlide(wxCommandEvent &Event)
- {
- mCurrent = mslide->GetValue();
- StartPlayer();
- }
- //================================================================
-
- //==================================================
-
- void WxViewer::SetValue()
- {
- mslide->SetValue(mCurrent);
- }
-
- // BEGIN_EVENT_TABLE(WxGimmickFrame, wxDialog)
- // END_EVENT_TABLE()
- //================================================================
-
-//========================================================================
-//========================================================================
-//========================================================================
-//========================================================================
-//========================================================================
-//========================================================================
-//========================================================================
-//========================================================================
-
- void* WxViewerPlayer::Entry()
- {
-
- GimmickDebugMessage(6,"WxViewerPlayer::Entry()"<<std::endl);
-
- while(!TestDestroy())
- {
-
- mWxViewer->ShowNextImage();
- mWxViewer->SetValue();
- ::wxWakeUpIdle();
- clock_t endwait;
- endwait = clock () + 0.2 * CLOCKS_PER_SEC ;
- while (clock() < endwait ) {}
-
- }
- return 0;
- }
-
- //=====================================================================
-
- //=====================================================================
- void WxViewerPlayer::OnExit()
- {
- GimmickDebugMessage(6,"WxViewerPlayer::OnExit() "<<std::endl);
- }
-
-
-} // EO namespace creaImageIO
-
+++ /dev/null
-#ifndef __creaImageIOWxViewer_h_INCLUDED__
-#define __creaImageIOWxViewer_h_INCLUDED__
-
-#ifdef USE_WXWIDGETS
-
-// wx
-#include <creaWx.h>
-#include <wx/image.h>
-#include <wx/imaglist.h>
-#include <wx/splitter.h>
-
-#include <creaImageIOSystem.h>
-#include <creaImageIOImagePointerHolder.h>
-
-// For image preview
-// vtk and wxvtk classes
-#include "creawxVTKRenderWindowInteractor.h"
-#include "vtkImageViewer2.h"
-
-namespace creaImageIO
-{
-
- class WxViewerPlayer;
-
- class WxViewer : public wxPanel
- {
-
- public:
- /// Ctors
- WxViewer();
- WxViewer(wxWindow *parent,
- const wxWindowID id,
- wxString title,
- const wxPoint& pos,
- const wxSize& size);
- /// Dtor
- virtual ~WxViewer();
- /// Shows the next image in the image vector
- void ShowNextImage();
- ///Starts the image player
- void StartPlayer();
- ///Stops the image player
- void StopPlayer();
- ///Refreshes the interface if the current image shown has changed
- bool RefreshIfNecessary();
- ///Sets a new image vector to be read
- void SetImageVector(std::vector<boost::shared_ptr<ImagePointerHolder> > &pointers);
-
- /// Set value of slider control
- void SetValue();
-
- private:
-
- /// Event to resume or start cine loop
- void OnCineLoop(wxCommandEvent &Event);
-
- /// Event to change displayed frames with slide control
- void OnSlide(wxCommandEvent &Event);
-
-
- ///Shows the image passed as parameter
- void ShowImage(vtkImageData* im);
- /// Previewer
- vtkImageViewer2* mViewer;
-
- ///Slider
- wxSlider *mslide ;
-
- ///CheckBox to cine loop
- wxCheckBox *mcheck;
-
- /// Associated wxvtk interactor
- crea::creawxVTKRenderWindowInteractor *mInteractor;
-
- /// Current extent
- int mx1,mx2,my1,my2,mz1,mz2;
- /// Current spacing
- double mspx,mspy,mspz;
- /// Current image shown
- int mCurrent;
- ///The threaded movie player
- WxViewerPlayer* mPlayer;
- /// The mutex
- wxMutex mMutex;
- /// Boolean that declares if the player needs to be refreshed
- bool mNeedRefresh;
- ///Last image shown
- vtkImageData* mLastImageShown;
- ///The vectors of images to be shown
- std::vector< boost::shared_ptr<ImagePointerHolder> > imagePointers;
-
- /// Sizers to preview images
- wxFlexGridSizer *mflexSizer;
- wxBoxSizer *mtopSizer;
-
- };
-
-}
-
-#endif // USE_WIDGETS
-// EOF
-#endif
+++ /dev/null
-<level>
-Root
-O Name Name 4
-<level>
-Patient
-O NumberOfChildren #Series
-D 0x0010 0x0010 4
-D 0x0010 0x0040 3
-D 0x0010 0x0030 3
-D 0x0010 0x0020 2
-<level>
-Series
-O NumberOfChildren #Images
-D 0x0008 0x0060 4
-D 0x0008 0x1030 3
-D 0x0008 0x103E 3
-D 0x0008 0x0080 3
-#D 0x0008 0x0081 3
-#D 0x0008 0x1010 3
-#D 0x0008 0x1048 3
-#D 0x0008 0x1050 3
-D 0x0018 0x1030 3
-D 0x0020 0x0010 3
-D 0x0008 0x0020 3
-D 0x0008 0x0030 3
-D 0x0008 0x0050 3
-#D 0x0008 0x0005 3
-D 0x0008 0x0021 3
-D 0x0008 0x0031 3
-D 0x0020 0x000D 3
-D 0x0020 0x000E 2
-<level>
-Image
-D 0x0020 0x0013 3
-D 0x0028 0x0010 3
-D 0x0028 0x0011 3
-D 0x0028 0x0008 3
-#D 0x0028 0x0103 3
-D 0x0020 0x0032 3
-D 0x0020 0x0037 3
-D 0x0020 0x1041 3
-D 0x0028 0x0030 3
-#D 0x0028 0x0100 3
-#D 0x0028 0x0101 3
-#D 0x0008 0x0008 3
-D 0x0008 0x0023 3
-D 0x0008 0x0033 3
-D 0x0020 0x4000 3
-#D 0x0004 0x1500 4
-#D 0x0004 0x1501 4
-#D 0x0028 0x1052 3
-#D 0x0028 0x1053 3
-#D 0x0050 0x0004 3
-#D 0x0020 0x0052 3
-#D 0x0008 0x0016 3
-O FullFileName Full_file_name 2
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Architecture</title>
-</head>
-
-<body>
-
-<h1 id="head-854b062d360d04ce4f5012114afa9ff5f11f21ba">Architecture</h1>
-<span class="anchor" id="line-6"></span><span class="anchor" id="line-7"></span>
-<p class="line867"></p>
-<h2 id="head-230b785b2112730d4f8aaffcda83ccd28c9c8d83">Generalities</h2>
-<span class="anchor" id="line-8"></span><span class="anchor" id="line-9"></span>
-<ul>
- <li>cvs : creatis/creaImageIO <span class="anchor" id="line-10"></span>
- <ul>
- <li style="list-style-type: none;">
- <p class="line862">cvs co -D
- :PROTOCOL:USERNAME@cvs.creatis.insa-lyon.fr:/cvs/creatis creaImageIO
- <span class="anchor" id="line-11"></span></p>
- </li>
- </ul>
- </li>
- <li>09/02/09 : <span class="anchor" id="line-12"></span>
- <ul>
- <li>new sources in src2 : create a lib called creaImageIO2
- <span class="anchor" id="line-13"></span></li>
- <li>command line app : appli/gimmick <span class="anchor" id="line-14">
- </span></li>
- <li>cmake option : BUILD_V2 to build the new version
- <span class="anchor" id="line-15"></span></li>
- </ul>
- </li>
- <li>All C++ files begin with creaImageIO <span class="anchor" id="line-16">
- </span></li>
- <li>All creaImageIO classes are in a namespace creaImageIO
- <span class="anchor" id="line-17"></span><span class="anchor" id="line-18">
- </span></li>
-</ul>
-<p class="line867"></p>
-<h2 id="head-fd2930d25892babc425be6c8bf5e10dd28f776bb">General stucture</h2>
-<span class="anchor" id="line-19"></span><span class="anchor" id="line-20">
-</span>
-<ul>
- <li>The main data structure : attributed tree
- <span class="anchor" id="line-21"></span>
- <ul>
- <li>all related files are of the form : creaImageIOTree
- <span class="anchor" id="line-22"></span></li>
- <li>all related classes are in a namespace : creaImageIO::tree
- <span class="anchor" id="line-23"></span></li>
- </ul>
- </li>
- <li>
- <p class="line862">The abstract 'Model' : <a class="nonexistent">TreeHandler</a>
- = manages a data source (read-only; read/write)
- <span class="anchor" id="line-24"></span></p>
- <ul>
- <li>
- <p class="line862">Concrete models : now SQLiteTreeHandler; future
- IRodsTreeHandler, <a class="nonexistent">FavoritesTreeHandler</a>?
- <span class="anchor" id="line-25"></span></p>
- </li>
- </ul>
- </li>
- <li>
- <p class="line862">The controller 'Gimmick' : controls different
- <a class="nonexistent">TreeHandlers</a>: <span class="anchor" id="line-26">
- </span></p>
- <ul>
- <li>Local database handler <span class="anchor" id="line-27"></span>
- </li>
- <li>Favorites handler <span class="anchor" id="line-28"></span></li>
- <li>Other which are open on user demand
- <span class="anchor" id="line-29"></span></li>
- </ul>
- </li>
- <li>The Views: <span class="anchor" id="line-30"></span>
- <ul>
- <li>
- <p class="line862">Abstract <a class="nonexistent">GimmickView</a> :
- Dialog <span class="anchor" id="line-31"></span></p>
- </li>
- <li>
- <p class="line862">Concrete <a class="nonexistent">GimmickView</a> : now
- <a class="nonexistent">WxGimmickView</a>; future QGimmickView ?
- <span class="anchor" id="line-32"></span></p>
- </li>
- <li>
- <p class="line862">Do we need to have abstract classes for
- <a class="nonexistent">GimmickView</a> components ?
- <span class="anchor" id="line-33"></span></p>
- <ul>
- <li>
- <p class="line891"><a class="nonexistent">TreeView</a> : is
- associated with a <a class="nonexistent">TreeHandler</a> to
- visualize its Tree <span class="anchor" id="line-34"></span></p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">AttributeView</a> :
- visualizes a set of attributes (only one for a
- <a class="nonexistent">GimmickView</a>)
- <span class="anchor" id="line-35"></span></p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">ImageView</a> : preview of
- images <span class="anchor" id="line-36"></span>
- <span class="anchor" id="line-37"></span>
- <span class="anchor" id="line-38"></span></p>
- </li>
- </ul>
- </li>
- </ul>
- </li>
-</ul>
-<p class="line867"></p>
-<h2 id="head-b16e3563d729255863452b289e971da6a51d945b">Classes</h2>
-<span class="anchor" id="line-39"></span><span class="anchor" id="line-40">
-</span>
-<p class="line867"></p>
-<h3 id="head-4b6a5f3be677d7dfd21607ab2394efda67858131">Data structure:
-Attributed tree</h3>
-<span class="anchor" id="line-41"></span><span class="anchor" id="line-42">
-</span>
-<p class="line874">in namespace creaImageIO::tree
-<span class="anchor" id="line-43"></span><span class="anchor" id="line-44">
-</span></p>
-<ul>
- <li>Tree <span class="anchor" id="line-45"></span>
- <ul>
- <li>Attributed tree structure <span class="anchor" id="line-46"></span>
- </li>
- <li>inherits Node <span class="anchor" id="line-47"></span></li>
- <li>
- <p class="line862">holds a vector of root <a class="nonexistent">
- TreeNode</a> <span class="anchor" id="line-48"></span></p>
- </li>
- </ul>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">TreeData</a>
- <span class="anchor" id="line-49"></span></p>
- <ul>
- <li>Abstract class to store user data on a tree
- <span class="anchor" id="line-50"></span></li>
- </ul>
- </li>
- <li>Node <span class="anchor" id="line-51"></span>
- <ul>
- <li>belong to a Tree, <span class="anchor" id="line-52"></span></li>
- <li>holds a pointer on parent Node, <span class="anchor" id="line-53">
- </span></li>
- <li>holds a vector of children Node <span class="anchor" id="line-54">
- </span></li>
- </ul>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">NodeData</a>
- <span class="anchor" id="line-55"></span></p>
- <ul>
- <li>Abstract class to store user data on a tree node
- <span class="anchor" id="line-56"></span></li>
- </ul>
- </li>
- <li>Descriptor <span class="anchor" id="line-57"></span>
- <ul>
- <li>Descriptor of the structure a tree (number of levels, descriptors of
- each level, ...) <span class="anchor" id="line-58"></span></li>
- <li>
- <p class="line862">holds a vector of <a class="nonexistent">
- LevelDescriptor</a> <span class="anchor" id="line-59"></span></p>
- </li>
- </ul>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">LevelDescriptor</a>
- <span class="anchor" id="line-60"></span></p>
- <ul>
- <li>
- <p class="line862">holds a vector of <a class="nonexistent">
- TreeAttributeDescriptor</a> <span class="anchor" id="line-61"></span>
- </p>
- </li>
- </ul>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">AttributeDescriptor</a>
- <span class="anchor" id="line-62"></span></p>
- <ul>
- <li>stores name, dicom group/elem, flags
- <span class="anchor" id="line-63"></span></li>
- </ul>
- </li>
- <li>Comparator <span class="anchor" id="line-64"></span>
- <ul>
- <li>Abstract definition of a comparator of Node
- <span class="anchor" id="line-65"></span></li>
- <li>
- <p class="line862">Comparison is done by operator()(Node* const &, Node*
- const &) <span class="anchor" id="line-66"></span></p>
- </li>
- </ul>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">ComparatorWithOrder</a>
- <span class="anchor" id="line-67"></span></p>
- <ul>
- <li>Abstract Comparator whose order can be reversed
- <span class="anchor" id="line-68"></span></li>
- <li>
- <p class="line862">Concrete comparison is done by method compare(Node*
- const &, Node* const &) <span class="anchor" id="line-69"></span></p>
- </li>
- </ul>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">LexicographicalComparator</a>
- <span class="anchor" id="line-70"></span></p>
- <ul>
- <li>A Comparator which stores a vector of Comparators and which performs
- lexicographical comparison <span class="anchor" id="line-71"></span>
- </li>
- </ul>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">IntComparator</a> : Compares the
- values of a given Attribute of the Nodes which is decoded as an int value
- <span class="anchor" id="line-72"></span></p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">FloatComparator</a> : Compares the
- values of a given Attribute of the Nodes which is decoded as a float value
- <span class="anchor" id="line-73"></span></p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">StringComparator</a> : Compares
- the values of a given Attribute of the Nodes which is decoded as a string
- value <span class="anchor" id="line-74"></span>
- <span class="anchor" id="line-75"></span><span class="anchor" id="line-76">
- </span></p>
- </li>
-</ul>
-<p class="line867"></p>
-<h3 id="head-df11fea98849928d47fd0fca777300beeb1de441">Models : TreeHandler and
-descendants</h3>
-<span class="anchor" id="line-77"></span><span class="anchor" id="line-78">
-</span>
-<ul>
- <li>
- <p class="line891"><a class="nonexistent">TreeHandler</a> : Abstract class
- which 'handles' a Tree structure. <span class="anchor" id="line-79"></span>
- </p>
- <ul>
- <li style="list-style-type: none;">Can:
- <span class="anchor" id="line-80"></span>Load the children of a given
- Node <span class="anchor" id="line-81"></span>
- <span class="anchor" id="line-82"></span></li>
- </ul>
- </li>
- <li class="gap">
- <p class="line862">SQLiteTreeHandler : Concrete <a class="nonexistent">
- TreeHandler</a> which manages a tree stored in a sqlite database
- <span class="anchor" id="line-83"></span></p>
- </li>
- <li>CppSQLite3.h / CppSQLite3.cpp : C++ interface to sqlite db
- <span class="anchor" id="line-84"></span></li>
-</ul>
-<p class="line874">... <span class="anchor" id="line-85"></span>
-<span class="anchor" id="line-86"></span></p>
-<ul>
- <li>
- <p class="line891"><a class="nonexistent">ImageFinder</a> : Parses (recursively)
- a part of a filesystem to look for known images and load their attributes in
- order to add the images to a Tree (submission via a <a class="nonexistent">
- TreeHandler</a>::<a class="nonexistent">AddBranch</a>)
- <span class="anchor" id="line-87"></span><span class="anchor" id="line-88">
- </span><span class="anchor" id="line-89"></span></p>
- </li>
-</ul>
-<p class="line867"></p>
-<h3 id="head-5d6e60823befe28469fe2d44ec8a889c06ea3b72">Image handling</h3>
-<span class="anchor" id="line-90"></span><span class="anchor" id="line-91">
-</span>
-<ul>
- <li>creaImageIOImageReader.h/cpp : <span class="anchor" id="line-92"></span>
- <ul>
- <li>
- <p class="line891"><a class="nonexistent">SpecificImageReader</a>
- <span class="anchor" id="line-93"></span></p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">ImageReader</a>
- <span class="anchor" id="line-94"></span></p>
- </li>
- </ul>
- </li>
- <li>creaImageIOMultiThreadImageReader.h/cpp
- <span class="anchor" id="line-95"></span></li>
- <li>creaImageIOIndexedHeap.h/txx <span class="anchor" id="line-96"></span>
- <span class="anchor" id="line-97"></span></li>
-</ul>
-<p class="line867"></p>
-<h3 id="head-6b69e886af29f9ef5bb7eb8b646980dd2963c2cf">Controller</h3>
-<span class="anchor" id="line-98"></span><span class="anchor" id="line-99">
-</span>
-<ul>
- <li>Gimmick <span class="anchor" id="line-100"></span>
- <span class="anchor" id="line-101"></span></li>
-</ul>
-<p class="line867"></p>
-<h3 id="head-4e100fce838267c2c7182a13a0137ed08ed1c75a">Views</h3>
-<span class="anchor" id="line-102"></span><span class="anchor" id="line-103">
-</span>
-<ul>
- <li>
- <p class="line891"><a class="nonexistent">GimmickView</a> : Abstract
- <span class="anchor" id="line-104"></span></p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">WxGimmickView</a>
- <span class="anchor" id="line-105"></span></p>
- <ul>
- <li>
- <p class="line891"><a class="nonexistent">WxTreeVie</a>w</p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">WxAttributeView</a>
- <span class="anchor" id="line-107"></span></p>
- </li>
- <li>
- <p class="line891"><a class="nonexistent">WxImageView</a>
- <span class="anchor" id="line-108"></span></p>
- </li>
- </ul>
- </li>
- <li>QGimmickView <span class="anchor" id="line-109"></span>
- <ul>
- <li>... </li>
- </ul>
- </li>
-</ul>
-
-</body>
-
-</html>
+++ /dev/null
-
-
-MACRO(CREA_BUILD_DOXYGEN_DOC NAME INPUT DOC_RELATIVE_INSTALL_PATH PREDEFINED)
-
- #--------------------------------------------------------------------------
- SET(USE_DOXYGEN ON CACHE BOOL "" FORCE)
-
- # Name
- SET(DOXYGEN_PROJECT_NAME "${NAME}")
-
- # Inputs
- STRING(REGEX REPLACE ";" " " DOXYGEN_INPUT "${INPUT}")
-
- # Output dirs
- SET(DOXYGEN_HTML_OUTPUT ".")
- SET(DOXYGEN_OUTPUT ${PROJECT_BINARY_DIR}/${DOC_RELATIVE_INSTALL_PATH})
- IF(NOT IS_DIRECTORY ${DOXYGEN_OUTPUT}/${DOXYGEN_HTML_OUTPUT})
- FILE(MAKE_DIRECTORY ${DOXYGEN_OUTPUT}/${DOXYGEN_HTML_OUTPUT})
- ENDIF(NOT IS_DIRECTORY ${DOXYGEN_OUTPUT}/${DOXYGEN_HTML_OUTPUT})
-
- # Doc exclude
- SET(DOXYGEN_EXCLUDE "CppSQLite3.h;CppSQLite3.cpp")
- STRING(REGEX REPLACE ";" " " DOXYGEN_EXCLUDE "${DOXYGEN_EXCLUDE}")
-
- # Log file name
- SET(DOXYGEN_LOGFILE "${CMAKE_CURRENT_BINARY_DIR}/doxygen.log")
-
- # Predefined symbols
- STRING(REGEX REPLACE ";" " " DOXYGEN_DOC_PREDEFINED "${PREDEFINED}")
-
- #---------------------------------------------------------------------------
- # DOT verification
- IF(DOT)
- GET_FILENAME_COMPONENT(DOXYGEN_DOT_PATH ${DOT} PATH)
- SET(DOXYGEN_HAVE_DOT "YES")
- ELSE(DOT)
- SET(DOXYGEN_DOT_PATH "")
- SET(DOXYGEN_HAVE_DOT "NO")
- ENDIF(DOT)
-
- #---------------------------------------------------------------------------
- # Create file and project
- CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.txt.in
- ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.txt
- @ONLY IMMEDIATE
- )
-
-
- ADD_CUSTOM_COMMAND(
- OUTPUT ${DOXYGEN_OUTPUT}/${DOXYGEN_HTML_OUTPUT}/index.html
- COMMAND
- ${DOXYGEN}
- ARGS
- ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.txt
- # DEPENDS bbtk bbi
- )
-
- ADD_CUSTOM_TARGET(doxygen_${NAME} ALL
- DEPENDS ${DOXYGEN_OUTPUT}/${DOXYGEN_HTML_OUTPUT}/index.html
- )
-
-# INSTALL(
-# DIRECTORY
-# ${DOXYGEN_OUTPUT}/${DOXYGEN_HTML_OUTPUT}
-# DESTINATION
-# ${BBTK_DOXYGEN_INSTALL_PATH}/${DOC_RELATIVE_INSTALL_PATH}
-# )
- #--------------------------------------------------------------------------
-
-ENDMACRO(CREA_BUILD_DOXYGEN_DOC)
-
-
-
-
-FILE(GLOB PAGES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.htm")
-#MESSAGE(STATUS "DOXYGEN HTML PAGES = ${PAGES}")
-FOREACH(PAGE ${PAGES})
- CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/${PAGE}
- ${PROJECT_BINARY_DIR}/doxygen/${PAGE}
- IMMEDIATE
- )
-#MESSAGE(STATUS "COPYING ${PAGE} TO ${PROJECT_BINARY_DIR}/doxygen/${PAGE}")
-ENDFOREACH(PAGE)
-
-
-FILE(GLOB IMAGES_PAGE RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.png" "*.jpg")
-FOREACH(IMAGE_PAGE ${IMAGES_PAGE})
- CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/${IMAGE_PAGE}
- ${PROJECT_BINARY_DIR}/doxygen/${IMAGE_PAGE}
- COPYONLY
- )
-ENDFOREACH(IMAGE_PAGE)
-
-
-
-CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/DoxyMainPage.txt.in
- ${CMAKE_CURRENT_BINARY_DIR}/DoxyMainPage.txt
- @ONLY IMMEDIATE
- )
-
-SET(INPUT
- ${CMAKE_CURRENT_BINARY_DIR}/DoxyMainPage.txt
- ${PROJECT_SOURCE_DIR}/src2
- ${PROJECT_SOURCE_DIR}/appli/gimmick
- ${PROJECT_SOURCE_DIR}/appli/wxGimmick
- ${PROJECT_SOURCE_DIR}/appli/TestWxGimmickReaderDialog
- )
-
-SET(DOXYGEN_DOC_PREDEFINED USE_WXWIDGETS)
-
-CREA_BUILD_DOXYGEN_DOC(
- ${CMAKE_PROJECT_NAME}_lib
- "${INPUT}"
- "doxygen"
- "${CREA_DEFINITIONS}"
- )
-
-#MESSAGE("DOX : ${CREA_DEFINITIONS}")
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>Class Diagram</strong></p>
-<img src="ClassDiagram.png" width="789" height="326" />
-
-</body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>Component Diagram</strong></p>
-<img src="ComponentDiagram.png"/>
-
-</body>
-
-</html>
+++ /dev/null
-/**
- * \mainpage creaImageIO documentation
-
-\htmlonly
-<H2>Architecture Description (v2)</H2>
-<br>
-<a href="Architecture.htm"> Architecture </a>
-<br>
-
-<H2>Diagrams of the architecture</H2>
-<br>
-<a href="ClassDiagram.htm"> Class Diagram </a>
-<br>
-<a href="ComponentDiagram.htm"> Component Diagram </a>
-<br>
-<a href="LayerDiagram.htm"> Layer Diagram </a>
-<br>
-
-<H2>Sequence Diagrams</H2>
-<br>
-<a href="SeqAddFile.htm"> On "Add Files" to a database </a>
-<br>
-<a href="SeqAddDir.htm"> On "Add Directories" to a database </a>
-<br>
-<a href="SeqRemove.htm"> On "Remove Files" from database </a>
-<br>
-<a href="SeqCreateDB.htm"> On "Create a database" </a>
-<br>
-<a href="SeqSelChanged.htm"> On "Selection has changed" </a>
-<br>
-<a href="SeqGetImages.htm"> On "Get Selected Images as VTK structures" </a>
-<br>
-
-\endhtmlonly
-
-
-
-
-
-
- */
\ No newline at end of file
+++ /dev/null
-# Doxyfile 1.5.5
-
-# 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 = @DOXYGEN_PROJECT_NAME@
-
-# 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 = @PROJECT_VERSION@
-
-# 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 = @DOXYGEN_OUTPUT@
-
-# 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, 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, Slovak, Slovene, Spanish, Swedish,
-# and Ukrainian.
-
-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 =
-
-# 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 = YES
-
-# 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 is your file systems
-# 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 = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-# DETAILS_AT_TOP = NO
-
-# 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 = YES
-
-# 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
-
-# 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 make 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
-
-# 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
-
-#---------------------------------------------------------------------------
-# 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 = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# 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 = YES
-
-# 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 namespace 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 = NO
-
-# 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 = NO
-
-# 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 = YES
-
-# 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 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_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
-
-# 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 define 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 defines 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 = 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 <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> 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 =
-
-#---------------------------------------------------------------------------
-# 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 = YES
-
-# 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
-
-# This WARN_NO_PARAMDOC option can be abled 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 = @DOXYGEN_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 = @DOXYGEN_INPUT@
-
-# 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++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
-
-FILE_PATTERNS = *.h \
- *.cxx \
- *.txx
-
-# 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 = YES
-
-# 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 = @DOXYGEN_EXCLUDE@
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem 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 =
-
-# 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 = *.cxx
-
-# 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 <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> 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, INPUT_FILTER
-# is applied to all files.
-
-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
-
-#---------------------------------------------------------------------------
-# 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 = YES
-
-# 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 (the default)
-# 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 (the default)
-# 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 documentstion.
-
-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 =
-
-#---------------------------------------------------------------------------
-# 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 = @DOXYGEN_HTML_OUTPUT@
-
-# 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 =
-
-# 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 =
-
-# 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 =
-
-# 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 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_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.
-
-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
-
-# 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_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 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
-
-# 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 [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag 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 (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = YES
-
-# 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
-
-#---------------------------------------------------------------------------
-# 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.
-
-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 = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, 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 = NO
-
-# 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 = NO
-
-# 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
-
-#---------------------------------------------------------------------------
-# 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 = YES
-
-# 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 = @DOXYGEN_DOC_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.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and 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 =
-
-# 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 =
-
-# 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 is superseded by the HAVE_DOT option below. This is only a
-# fallback. 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 = @DOXYGEN_HAVE_DOT@
-
-# 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 = YES
-
-# 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 = YES
-
-# 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 = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will 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, jpg, or gif
-# 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 = "@DOXYGEN_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 MAX_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 = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is enabled by default, which results in a transparent
-# background. 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 = NO
-
-# 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
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Layer Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>Currently implemented Layer Architecture (includes GUI less applications and wxWidgets derived applications)</strong></p>
-<img src="LayerDiagram.jpg"/>
-
-</body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>Adding a Directory</strong></p>
-<img src="SeqAddDir.png"/>
-
-</body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>Adding a File</strong></p>
-<img src="SeqAddFile.png"/>
-
-</body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>Creating a Database</strong></p>
-<img src="SeqCreateDB.png"/>
-
-</body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>On Get Images</strong></p>
-<img src="SeqGetImages.png"/>
-
-</body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>Remove a file</strong></p>
-<img src="SeqRemove.png"/>
-
-</body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-<meta http-equiv="Content-Language" content="es-co" />
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Class Diagram</title>
-<style type="text/css">
-.style1 {
- font-size: x-large;
-}
-</style>
-</head>
-
-<body>
-
-<p class="style1"><strong>On Selection Changed</strong></p>
-<img src="SeqSelChanged.png"/>
-
-</body>
-
-</html>
+++ /dev/null
-/* XPM */
-static const char * accept_xpm[] = {
-"48 48 773 2",
-" c None",
-". c #D8DBD9",
-"+ c #D4D5D4",
-"@ c #D4D3D3",
-"# c #D6D5D5",
-"$ c #D5D4D4",
-"% c #D3D2D2",
-"& c #D3D4D2",
-"* c #D6D9D7",
-"= c #D5D6D5",
-"- c #DBDBDB",
-"; c #E5E4E4",
-"> c #ECECEC",
-", c #F2F2F2",
-"' c #F5F5F5",
-") c #F7F7F7",
-"! c #F8F7F7",
-"~ c #F6F6F6",
-"{ c #F5F4F4",
-"] c #F0F0F0",
-"^ c #EAE9E9",
-"/ c #E1E1E1",
-"( c #D7D7D7",
-"_ c #D0D1D0",
-": c #D9D9D9",
-"< c #E7E7E7",
-"[ c #F3F3F3",
-"} c #FAFAFA",
-"| c #FDFDFD",
-"1 c #F3F9F4",
-"2 c #E0F0E2",
-"3 c #FCFCFC",
-"4 c #F8F8F8",
-"5 c #EFEFEF",
-"6 c #E2E1E1",
-"7 c #D3D3D2",
-"8 c #DADADA",
-"9 c #F9F9F9",
-"0 c #FEFEFE",
-"a c #FCFDFC",
-"b c #D7EBDC",
-"c c #99CEAA",
-"d c #5CB17B",
-"e c #28994F",
-"f c #078938",
-"g c #008536",
-"h c #E6E5E5",
-"i c #D6D7D6",
-"j c #E8E7E7",
-"k c #F2F8F3",
-"l c #A6D5B4",
-"m c #41A564",
-"n c #0C8C3E",
-"o c #008736",
-"p c #038938",
-"q c #048939",
-"r c #058A3A",
-"s c #008735",
-"t c #F2F8F4",
-"u c #E0DFDF",
-"v c #CDCFCD",
-"w c #DCDDDC",
-"x c #F2F1F1",
-"y c #A9D7B6",
-"z c #2E9D56",
-"A c #008836",
-"B c #018937",
-"C c #0F9042",
-"D c #1C964C",
-"E c #269B54",
-"F c #2B9E59",
-"G c #2FA05B",
-"H c #30A15D",
-"I c #A9D6B6",
-"J c #D3D4D3",
-"K c #E1E0E0",
-"L c #DFF0E3",
-"M c #44A866",
-"N c #008936",
-"O c #088E3C",
-"P c #1C984C",
-"Q c #2DA15A",
-"R c #32A35E",
-"S c #31A45D",
-"T c #32A45E",
-"U c #31A35D",
-"V c #2DA05A",
-"W c #F1F1F1",
-"X c #D7D6D6",
-"Y c #E4E3E3",
-"Z c #B3DBBE",
-"` c #1C9749",
-" . c #008A36",
-".. c #058E3A",
-"+. c #1B994B",
-"@. c #2EA25B",
-"#. c #31A55D",
-"$. c #32A55E",
-"%. c #31A65D",
-"&. c #32A65E",
-"*. c #32A75E",
-"=. c #1C9649",
-"-. c #F3F2F2",
-";. c #D9D9D8",
-">. c #E2E2E2",
-",. c #A1D4AF",
-"'. c #0B903C",
-"). c #008C36",
-"!. c #0D9340",
-"~. c #2AA157",
-"{. c #31A75D",
-"]. c #31A85D",
-"^. c #31A95D",
-"/. c #31AA5D",
-"(. c #2AA057",
-"_. c #0B903D",
-":. c #A0D3B0",
-"<. c #DFDFDF",
-"[. c #A0D4AF",
-"}. c #018D36",
-"|. c #018E37",
-"1. c #169847",
-"2. c #30A55C",
-"3. c #32A75D",
-"4. c #32A95D",
-"5. c #32AA5D",
-"6. c #31AA5C",
-"7. c #32AB5D",
-"8. c #33AB5D",
-"9. c #34AC5D",
-"0. c #35AC5D",
-"a. c #36AC5D",
-"b. c #37AC5C",
-"c. c #37AC5D",
-"d. c #35AC5C",
-"e. c #32AB5C",
-"f. c #38AC62",
-"g. c #36AA61",
-"h. c #30A45C",
-"i. c #DADBDA",
-"j. c #F4F4F4",
-"k. c #B3DCBF",
-"l. c #0B923C",
-"m. c #018F37",
-"n. c #189B4A",
-"o. c #30A75C",
-"p. c #37AD5D",
-"q. c #3CAD5C",
-"r. c #40AE5D",
-"s. c #43AE5D",
-"t. c #46AF5C",
-"u. c #47B05D",
-"v. c #48B05D",
-"w. c #48B05C",
-"x. c #47AF5C",
-"y. c #45AF5D",
-"z. c #42AE5D",
-"A. c #3EAE5C",
-"B. c #3AAD5D",
-"C. c #39AE5F",
-"D. c #A8DCBA",
-"E. c #B0DEC0",
-"F. c #3BAE65",
-"G. c #189A4A",
-"H. c #ECEBEB",
-"I. c #1D9B49",
-"J. c #009036",
-"K. c #169C47",
-"L. c #30A95C",
-"M. c #33AC5C",
-"N. c #37AD5C",
-"O. c #3EAD5C",
-"P. c #44AF5C",
-"Q. c #49B05C",
-"R. c #4CB05C",
-"S. c #4EB15C",
-"T. c #4FB25C",
-"U. c #51B25C",
-"V. c #52B35C",
-"W. c #53B35C",
-"X. c #51B35C",
-"Y. c #50B25C",
-"Z. c #4DB15C",
-"`. c #4BB05C",
-" + c #8ECE9C",
-".+ c #BCE3CA",
-"++ c #3CB065",
-"@+ c #30A85C",
-"#+ c #169B47",
-"$+ c #008F36",
-"%+ c #1C9A49",
-"&+ c #FBFBFB",
-"*+ c #45AD66",
-"=+ c #009236",
-"-+ c #0D9A40",
-";+ c #30AA5B",
-">+ c #33AC5D",
-",+ c #43AE5C",
-"'+ c #49B05D",
-")+ c #56B45B",
-"!+ c #58B45C",
-"~+ c #5AB55C",
-"{+ c #5BB65B",
-"]+ c #5CB65C",
-"^+ c #5DB65C",
-"/+ c #5DB75B",
-"(+ c #5DB75C",
-"_+ c #5CB65B",
-":+ c #5BB65C",
-"<+ c #59B55C",
-"[+ c #57B45B",
-"}+ c #7DC583",
-"|+ c #F6FBF7",
-"1+ c #FFFFFF",
-"2+ c #D1ECDA",
-"3+ c #47B36B",
-"4+ c #30A95B",
-"5+ c #0D9940",
-"6+ c #009136",
-"7+ c #44AC66",
-"8+ c #A9DAB6",
-"9+ c #009336",
-"0+ c #059739",
-"a+ c #2AA856",
-"b+ c #39AD5D",
-"c+ c #4AB05D",
-"d+ c #56B45C",
-"e+ c #5CB75C",
-"f+ c #5EB75B",
-"g+ c #60B85B",
-"h+ c #62B95B",
-"i+ c #63B95B",
-"j+ c #64BA5B",
-"k+ c #65BA5B",
-"l+ c #61B95B",
-"m+ c #6FBF6B",
-"n+ c #EAF6EA",
-"o+ c #D8EEDF",
-"p+ c #58B974",
-"q+ c #2AA756",
-"r+ c #A9D9B6",
-"s+ c #E1E1E0",
-"t+ c #F2F9F3",
-"u+ c #2EA755",
-"v+ c #009635",
-"w+ c #1EA34A",
-"x+ c #3FAE5C",
-"y+ c #5FB75B",
-"z+ c #66BB5A",
-"A+ c #68BC5A",
-"B+ c #69BC5A",
-"C+ c #6BBD5A",
-"D+ c #6CBD5A",
-"E+ c #6CBD5B",
-"F+ c #6CBE5B",
-"G+ c #6ABD5A",
-"H+ c #6CBE5F",
-"I+ c #CFEACB",
-"J+ c #B7E0C5",
-"K+ c #3AAA58",
-"L+ c #3AAD5C",
-"M+ c #1CA24A",
-"N+ c #009535",
-"O+ c #2EA656",
-"P+ c #A5D9B3",
-"Q+ c #009634",
-"R+ c #109C3B",
-"S+ c #42AE5A",
-"T+ c #4CB15C",
-"U+ c #57B45C",
-"V+ c #5FB85B",
-"W+ c #69BC5B",
-"X+ c #6BBD5B",
-"Y+ c #6DBE5B",
-"Z+ c #6FBF5C",
-"`+ c #71BF5D",
-" @ c #72C05E",
-".@ c #73C05F",
-"+@ c #74C05F",
-"@@ c #72BF5E",
-"#@ c #AFDBA4",
-"$@ c #E7F5ED",
-"%@ c #29A35C",
-"&@ c #31A551",
-"*@ c #4AB05C",
-"=@ c #3DAD5A",
-"-@ c #0C9B3B",
-";@ c #A5D9B4",
-">@ c #42B163",
-",@ c #109B34",
-"'@ c #33A74B",
-")@ c #54B35C",
-"!@ c #66BB5B",
-"~@ c #6ABD5B",
-"{@ c #70BF5D",
-"]@ c #74C060",
-"^@ c #75C161",
-"/@ c #76C162",
-"(@ c #78C163",
-"_@ c #78C263",
-":@ c #79C264",
-"<@ c #92CE81",
-"[@ c #F5FBF4",
-"}@ c #FBFDFC",
-"|@ c #53B57D",
-"1@ c #25A04A",
-"2@ c #52B25C",
-"3@ c #2FA64B",
-"4@ c #0B9A34",
-"5@ c #40B063",
-"6@ c #E6E6E5",
-"7@ c #D8EEDB",
-"8@ c #1B9E3C",
-"9@ c #52B02E",
-"0@ c #4EB158",
-"a@ c #65BB5B",
-"b@ c #77C162",
-"c@ c #7BC366",
-"d@ c #7DC467",
-"e@ c #7EC468",
-"f@ c #7FC469",
-"g@ c #80C46A",
-"h@ c #7FC46A",
-"i@ c #82C66D",
-"j@ c #E5F3E0",
-"k@ c #FEFFFE",
-"l@ c #91D0AC",
-"m@ c #159A44",
-"n@ c #5DB759",
-"o@ c #5AB55B",
-"p@ c #4BB058",
-"q@ c #4CAE2F",
-"r@ c #149D3D",
-"s@ c #D7EEDC",
-"t@ c #EFEEEE",
-"u@ c #A1D6A9",
-"v@ c #26A033",
-"w@ c #7CC034",
-"x@ c #75C056",
-"y@ c #67BC5A",
-"z@ c #76C161",
-"A@ c #81C56B",
-"B@ c #83C66D",
-"C@ c #84C66D",
-"D@ c #84C76E",
-"E@ c #83C66C",
-"F@ c #84C76D",
-"G@ c #C4E4B9",
-"H@ c #C6E6D4",
-"I@ c #129949",
-"J@ c #5EB757",
-"K@ c #61B85B",
-"L@ c #73BF56",
-"M@ c #76BE35",
-"N@ c #219E33",
-"O@ c #9ED5A9",
-"P@ c #F6F5F5",
-"Q@ c #6FC079",
-"R@ c #3CA830",
-"S@ c #8BC63D",
-"T@ c #94CC50",
-"U@ c #6EBE5B",
-"V@ c #75C160",
-"W@ c #7DC468",
-"X@ c #7EC469",
-"Y@ c #82C56A",
-"Z@ c #7DC364",
-"`@ c #79C05E",
-" # c #76BF5A",
-".# c #75BE57",
-"+# c #75BD57",
-"@# c #91CB7A",
-"## c #F8FCF7",
-"$# c #ECF7F1",
-"%# c #31A663",
-"&# c #47AE53",
-"*# c #67BB5B",
-"=# c #68BB5A",
-"-# c #86C43E",
-";# c #37A631",
-"># c #6DBF7A",
-",# c #47AD4E",
-"'# c #51AF2E",
-")# c #93CA45",
-"!# c #9CCF4F",
-"~# c #88C853",
-"{# c #6EBE5C",
-"]# c #7AC265",
-"^# c #97D086",
-"/# c #CBE7C2",
-"(# c #86C772",
-"_# c #7EC364",
-":# c #76BE5A",
-"<# c #73BD54",
-"[# c #74BD54",
-"}# c #75BD55",
-"|# c #76BE56",
-"1# c #77BE56",
-"2# c #77BE57",
-"3# c #7ABF5B",
-"4# c #DCEED3",
-"5# c #6CC090",
-"6# c #2BA24D",
-"7# c #7AC266",
-"8# c #71C05E",
-"9# c #87C753",
-"0# c #8EC846",
-"a# c #4CAD2F",
-"b# c #44AC4E",
-"c# c #D7DAD7",
-"d# c #E3E3E3",
-"e# c #33A436",
-"f# c #62B52E",
-"g# c #97CC4A",
-"h# c #9BCE4E",
-"i# c #9BCE4F",
-"j# c #83C659",
-"k# c #D9EDD3",
-"l# c #D6EDD5",
-"m# c #7CC161",
-"n# c #74BC54",
-"o# c #76BD56",
-"p# c #79BE57",
-"q# c #7BBF59",
-"r# c #7CBF5A",
-"s# c #7EC15B",
-"t# c #7FC15B",
-"u# c #7FC15C",
-"v# c #B5DBA1",
-"w# c #FEFEFD",
-"x# c #BBE2CC",
-"y# c #109743",
-"z# c #76C168",
-"A# c #82C56C",
-"B# c #82C558",
-"C# c #94CB4A",
-"D# c #5CB32F",
-"E# c #2FA236",
-"F# c #F5FAF4",
-"G# c #35A533",
-"H# c #6BB92D",
-"I# c #99CD4C",
-"J# c #9ACE4F",
-"K# c #84C661",
-"L# c #80C56A",
-"M# c #9FD38E",
-"N# c #FDFEFD",
-"O# c #D9EED7",
-"P# c #87C56C",
-"Q# c #7DC05B",
-"R# c #80C15C",
-"S# c #82C25E",
-"T# c #84C35F",
-"U# c #85C460",
-"V# c #86C460",
-"W# c #93CA71",
-"X# c #F6FBF3",
-"Y# c #EAF6EF",
-"Z# c #2BA35E",
-"`# c #4DAE4C",
-" $ c #75BE59",
-".$ c #81C569",
-"+$ c #82C66C",
-"@$ c #82C55F",
-"#$ c #97CC4D",
-"$$ c #66B72F",
-"%$ c #31A334",
-"&$ c #E4E4E4",
-"*$ c #E5F3E2",
-"=$ c #3AA733",
-"-$ c #70BB2D",
-";$ c #9ACE4E",
-">$ c #99CE51",
-",$ c #8CCA6A",
-"'$ c #DCEFD5",
-")$ c #E4F3E2",
-"!$ c #91CA75",
-"~$ c #87C561",
-"{$ c #89C662",
-"]$ c #8BC763",
-"^$ c #8DC864",
-"/$ c #8EC966",
-"($ c #D2E9C2",
-"_$ c #FEFFFF",
-":$ c #6FC192",
-"<$ c #29A047",
-"[$ c #72BC54",
-"}$ c #7EC466",
-"|$ c #89C866",
-"1$ c #98CD4E",
-"2$ c #6BB92F",
-"3$ c #37A633",
-"4$ c #E6F3E2",
-"5$ c #40AA32",
-"6$ c #72BB2D",
-"7$ c #B3DA7A",
-"8$ c #EFF8EE",
-"9$ c #9ED182",
-"0$ c #91CA66",
-"a$ c #93CB67",
-"b$ c #95CB69",
-"c$ c #AED88C",
-"d$ c #FCFDFA",
-"e$ c #B7E0C9",
-"f$ c #179A47",
-"g$ c #75BD5B",
-"h$ c #7EC05B",
-"i$ c #7ABE58",
-"j$ c #78BE43",
-"k$ c #90C940",
-"l$ c #98CD4F",
-"m$ c #6CBA2F",
-"n$ c #3DA833",
-"o$ c #E3E2E2",
-"p$ c #45AC32",
-"q$ c #99CD4D",
-"r$ c #94CA41",
-"s$ c #DDEEC4",
-"t$ c #F1F8F0",
-"u$ c #AED892",
-"v$ c #9BCE6C",
-"w$ c #9FD071",
-"x$ c #E6F3DA",
-"y$ c #F2F9F5",
-"z$ c #28A25B",
-"A$ c #5CB557",
-"B$ c #80C159",
-"C$ c #7EC03D",
-"D$ c #82C025",
-"E$ c #84C226",
-"F$ c #93CA40",
-"G$ c #6AB92E",
-"H$ c #42AB32",
-"I$ c #4EB036",
-"J$ c #6CBA2E",
-"K$ c #9BCF4F",
-"L$ c #97CC47",
-"M$ c #85C227",
-"N$ c #A3D160",
-"O$ c #F4FAF1",
-"P$ c #F5FAF5",
-"Q$ c #B8DD9D",
-"R$ c #C2E1A2",
-"S$ c #7AC69B",
-"T$ c #33A54C",
-"U$ c #91CA67",
-"V$ c #8FC965",
-"W$ c #88C550",
-"X$ c #83C12F",
-"Y$ c #83C124",
-"Z$ c #82C023",
-"`$ c #95CB4A",
-" % c #67B82F",
-".% c #4BAE35",
-"+% c #D5D5D4",
-"@% c #E9E9E9",
-"#% c #FBFAFA",
-"$% c #67BA50",
-"%% c #66B730",
-"&% c #9ACD4C",
-"*% c #88C42D",
-"=% c #97CC57",
-"-% c #F3F9EF",
-";% c #F6FBF4",
-">% c #CFEADB",
-",% c #159A4A",
-"'% c #8BC864",
-")% c #92C953",
-"!% c #87C334",
-"~% c #90C946",
-"{% c #61B631",
-"]% c #64B94E",
-"^% c #DADCD9",
-"/% c #8ECC7C",
-"(% c #60B636",
-"_% c #8DC73D",
-":% c #90C83A",
-"<% c #9ACD5A",
-"[% c #F0F8EA",
-"}% c #FAFDFB",
-"|% c #4BB176",
-"1% c #48AC37",
-"2% c #86C22C",
-"3% c #88C53F",
-"4% c #5DB435",
-"5% c #8DCB7C",
-"6% c #B8DFAC",
-"7% c #5EB53E",
-"8% c #82C235",
-"9% c #98CD4A",
-"0% c #85C228",
-"a% c #98CD57",
-"b% c #F0F8EC",
-"c% c #A9DABE",
-"d% c #1C9B3C",
-"e% c #7CBE25",
-"f% c #7CC036",
-"g% c #5BB43C",
-"h% c #B7DEAB",
-"i% c #E2F1DD",
-"j% c #66B84B",
-"k% c #73BC31",
-"l% c #8CC636",
-"m% c #93CA4C",
-"n% c #EEF7E9",
-"o% c #F1F9F5",
-"p% c #209F53",
-"q% c #5FB42B",
-"r% c #8AC537",
-"s% c #6EBA32",
-"t% c #63B748",
-"u% c #E2F1DC",
-"v% c #E4E4E3",
-"w% c #FDFDFC",
-"x% c #86C770",
-"y% c #6CBA3E",
-"z% c #7FBF25",
-"A% c #96CB50",
-"B% c #EBF5E4",
-"C% c #FDFEFE",
-"D% c #2EA234",
-"E% c #80C024",
-"F% c #82C024",
-"G% c #7ABE26",
-"H% c #68B83D",
-"I% c #84C66F",
-"J% c #D6D6D5",
-"K% c #C6E4BA",
-"L% c #6BBA4C",
-"M% c #79BD2A",
-"N% c #95CB4D",
-"O% c #EBF6E6",
-"P% c #D8EEE2",
-"Q% c #159A48",
-"R% c #73BB27",
-"S% c #80BF24",
-"T% c #73BB2C",
-"U% c #68B94A",
-"V% c #C4E4BA",
-"W% c #F6FAF4",
-"X% c #84C56A",
-"Y% c #75BC41",
-"Z% c #7EBF25",
-"`% c #8FC843",
-" & c #E9F5E3",
-".& c #58B780",
-"+& c #42A930",
-"@& c #7ABD26",
-"#& c #71BB41",
-"$& c #81C469",
-"%& c #DAD9D9",
-"&& c #F7F6F6",
-"*& c #CBE6BE",
-"=& c #76BD54",
-"-& c #7ABE31",
-";& c #81C024",
-">& c #92C948",
-",& c #E6F3DD",
-"'& c #C0E4D0",
-")& c #1A9B41",
-"!& c #78BD25",
-"~& c #7EBF24",
-"{& c #75BC32",
-"]& c #74BC52",
-"^& c #C9E5BE",
-"/& c #98CE7D",
-"(& c #7DC050",
-"_& c #7CBE28",
-":& c #91C845",
-"<& c #E5F3DE",
-"[& c #3EAC6D",
-"}& c #4EAE2E",
-"|& c #77BD29",
-"1& c #79BE4F",
-"2& c #95CC7C",
-"3& c #ECF5E7",
-"4& c #8CC86B",
-"5& c #80C149",
-"6& c #7DBF25",
-"7& c #8CC63C",
-"8& c #E3F2DB",
-"9& c #AADABF",
-"0& c #1C9B38",
-"a& c #7DBF24",
-"b& c #7CC049",
-"c& c #8AC669",
-"d& c #EBF5E7",
-"e& c #D5EBC9",
-"f& c #8BC765",
-"g& c #82C243",
-"h& c #8EC740",
-"i& c #D1EACA",
-"j& c #2EA560",
-"k& c #5EB32B",
-"l& c #7BBE26",
-"m& c #7EC144",
-"n& c #89C564",
-"o& c #D4EAC9",
-"p& c #D8D8D6",
-"q& c #E9E9E8",
-"r& c #CEE7BE",
-"s& c #8FC964",
-"t& c #86C445",
-"u& c #7DBF2F",
-"v& c #3DA731",
-"w& c #82C346",
-"x& c #8CC863",
-"y& c #CDE6BD",
-"z& c #DDDDDC",
-"A& c #D1E8BF",
-"B& c #99CE6D",
-"C& c #8EC851",
-"D& c #7DBF29",
-"E& c #7FBF24",
-"F& c #7ABE2A",
-"G& c #8AC650",
-"H& c #97CD6C",
-"I& c #D0E8BF",
-"J& c #EEEEED",
-"K& c #DBEDCC",
-"L& c #A5D37A",
-"M& c #97CC5F",
-"N& c #81C135",
-"O& c #7CBE26",
-"P& c #7FC136",
-"Q& c #95CB5F",
-"R& c #A3D278",
-"S& c #DAEDCC",
-"T& c #EFF7E9",
-"U& c #B3DA8E",
-"V& c #9FD06D",
-"W& c #90C951",
-"X& c #7EC02D",
-"Y& c #7DBE25",
-"Z& c #7BBF2E",
-"`& c #B2DA8D",
-" * c #D9ECC7",
-".* c #AED884",
-"+* c #A2D26F",
-"@* c #93CA55",
-"#* c #85C33A",
-"$* c #7DBF28",
-"%* c #7BBE29",
-"&* c #83C33B",
-"** c #91CA56",
-"=* c #ADD784",
-"-* c #D8ECC7",
-";* c #E0E0DF",
-">* c #F8FBF5",
-",* c #D9EDC7",
-"'* c #B6DB8F",
-")* c #A8D476",
-"!* c #A2D16A",
-"~* c #97CC5A",
-"{* c #8EC84A",
-"]* c #87C43E",
-"^* c #82C236",
-"/* c #80C132",
-"(* c #8DC84A",
-"_* c #A1D16A",
-":* c #A7D475",
-"<* c #B5DB8F",
-"[* c #DCDCDA",
-"}* c #ECF5E3",
-"|* c #D5EABF",
-"1* c #C2E1A0",
-"2* c #AED77F",
-"3* c #A7D473",
-"4* c #AAD575",
-"5* c #AAD574",
-"6* c #ADD77F",
-"7* c #EEF6E7",
-"8* c #E6E6E6",
-" . + @ # $ % & * ",
-" = - ; > , ' ) ! ! ~ { ] ^ / ( _ ",
-" : < [ } | | | | 1 2 2 1 | | | 3 4 5 6 7 ",
-" 8 > 9 0 a b c d e f g g g g f e d c b a | ' h % ",
-" i j 4 | k l m n o o o p q r r q p o o s n m l t 3 [ u v ",
-" w x 3 | y z s A B C D E F G H H G F E D C B A s z I | } ^ J ",
-" K 4 0 L M N N O P Q R R S T T S T T S T R U V P O N A M L | W X ",
-" Y 9 | Z ` ...+.@.S #.$.$.%.&.&.%.*.&.%.$.$.#.$.S @.+... .=.Z | -.;. ",
-" >.9 | ,.'.).!.~.#.%.{.{.].^.^././././././.^.^.].{.%.#.S (.!.)._.:.| -.X ",
-" <.9 | [.}.|.1.2.3.].4.5.6.7.8.9.0.a.b.c.a.d.9.8.e.5.5.f.g.*.h.1.|.}.[.| W J ",
-" i.j.0 k.l.m.n.o.^.5.e.9.p.q.r.s.t.u.v.w.v.v.x.y.z.A.B.C.D.E.F.4.o.G.|.l.k.| ^ v ",
-" H.| L I.J.K.L./.M.N.O.P.Q.R.S.T.U.V.W.W.W.W.X.Y.T.Z.`. +a 0 .+++/.@+#+$+%+L } u ",
-" u &+| *+=+-+;+>+B.,+'+Z.Y.W.)+!+~+{+]+^+/+(+^+_+:+<+[+}+|+1+0 1+2+3+7.4+5+6+7+| [ % ",
-" , | 8+9+0+a+b+s.c+S.V.d+<+e+f+g+h+i+j+j+k+j+j+j+h+l+m+n+1+1+0 1+1+o+p+a.q+0+=+r+3 h ",
-" s+3 t+u+v+w+x+Q.S.W.[+{+y+l+j+z+A+B+C+D+E+F+F+D+C+G+H+I+0 0 0 0 0 0 0 J+K+L+M+N+O+t+' 7 ",
-" 5 0 P+Q+R+S+T+V.U+]+V+i+z+W+X+Y+Z+`+ @.@.@+@+@.@.@@@#@0 1+1+1+0 1+1+$@%@&@*@=@-@v+;@| 6 ",
-" <.9 a >@,@'@S.)@~+V+i+!@~@Y+{@ @]@^@/@(@_@:@:@:@:@_@<@[@0 1+1+1+0 1+}@|@1@[+2@T+3@4@5@a 5 _ ",
-" 6@| 7@8@9@0@d+_+l+a@W+Y+`+.@^@b@:@c@d@e@f@g@h@g@h@i@j@1+0 1+1+1+0 k@l@m@n@V+o@)@p@q@r@s@4 ( ",
-" t@| u@v@w@x@f+h+y@E+{@.@z@_@c@e@g@A@B@C@D@C@B@E@F@G@0 0 0 0 0 0 0 H@I@J@~@z+K@{+L@M@N@O@3 / ",
-" P@| Q@R@S@T@B+B+U@ @V@:@W@X@A@B@F@Y@Z@`@ #.#+#+#@###1+1+0 1+1+1+$#%#&#]@{@E+*#=#T@-#;#>#| ^ ",
-"< 9 | ,#'#)#!#~#{#.@z@]#^#/#(#F@_#:#<#[#}#|#1#2#3#4#0 1+1+0 1+1+1+5#6#7#_@V@8#Y+9#!#0#a#b#| ] c#",
-"d#3 | e#f#g#h#i#j#b@c@h@k#0 l#m#n#o#p#q#r#s#t#u#v#w#0 0 0 0 0 0 x#y#z#A#e@]#z@B#i#h#C#D#E#| { & ",
-"6 3 F#G#H#I#!#!#J#K#L#M#N#1+0 O#P#Q#R#S#T#U#V#W#X#1+0 1+1+0 1+Y#Z#`# $.$+$f@@$J#!#!##$$$%$F#~ % ",
-"&$| *$=$-$;$!#!#h#>$,$'$0 1+0 1+)$!$~${$]$^$/$($1+1+0 1+1+0 _$:$<$2#n#[$}$|$>$h#!#!#1$2$3$)$! $ ",
-"; 3 4$5$6$;$h#h#h#h#7$N#0 0 0 0 0 8$9$0$a$b$c$d$0 0 0 0 0 0 e$f$g$h$i$}#j$k$h#h#h#h#l$m$n$*$! # ",
-"o$3 F#p$-$q$!#!#h#r$s$1+0 1+0 1+1+0 t$u$v$w$x$0 1+1+0 1+1+y$z$A${$T#B$C$D$E$F$h#!#!##$G$H$F#) @ ",
-"; 3 | I$J$g#!#K$L$M$N$O$0 1+0 1+1+0 1+P$Q$R$N#0 1+1+0 1+0 S$T$U$V$W$X$Y$Z$Y$M$L$K$!#`$ %.%| ' +%",
-"@%#%| $%%%)#h#&%*%Z$Z$=%-%0 0 0 0 0 0 0 a ;%0 0 0 0 0 0 >%,%'%)%!%Z$Z$Z$Z$Z$Z$*%&%h#~%{%]%| , ^%",
-" ) | /%(%_%h#:%Y$Y$Y$Y$<%[%0 1+1+0 1+1+0 1+1+0 1+1+0 }%|%1%2%Y$Y$Z$Y$Y$Z$Y$Y$Y$:%h#3%4%5%| > ",
-" , | 6%7%8%9%0%Z$Y$Y$Y$Z$a%b%1+1+0 1+1+0 1+1+0 1+1+0 c%d%e%Y$Y$Y$Z$Y$Y$Z$Y$Y$Z$0%g#f%g%h%| ; ",
-" ^ | i%j%k%l%Z$Z$Z$Z$Z$Z$Z$m%n%0 0 0 0 0 0 0 0 0 0 o%p%q%Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$r%s%t%u%} - ",
-" v%&+w%x%y%z%Y$Z$Y$Y$Y$Z$Y$Z$A%B%0 1+1+0 1+1+0 1+C%S$D%E%Z$Y$Y$Y$Z$Y$Y$Z$Y$Y$Z$F%G%H%I%w%[ J% ",
-" j.0 K%L%M%F%Z$Y$Y$Y$Z$Y$Z$Y$N%O%1+1+0 1+1+0 1+P%Q%R%Y$Z$Y$Y$Y$Z$Y$Y$Z$Y$Y$Z$S%T%U%V%0 < ",
-" < | W%X%Y%Z%Z$Z$Z$Z$Z$Z$Z$Z$Z$`% &0 0 0 0 0 N#.&+&Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$F%@&#&$&W%9 %& ",
-" &&0 *&=&-&;&Y$Y$Y$Z$Y$Z$Y$Y$Z$>&,&0 1+1+0 '&)&!&Y$Y$Z$Y$Y$Y$Z$Y$Y$Z$Y$Y$~&{&]&^&| > ",
-" < | | /&(&_&Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$:&<&0 0 0 [&}&Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$;&|&1&2&| 4 8 ",
-" -.| 3&4&5&6&F%Y$Z$Y$Z$Y$Y$Z$Y$Y$7&8&1+9&0&a&Z$Y$Y$Z$Y$Y$Y$Z$Y$Y$Z$;&G%b&c&d&3 j ",
-" v%9 0 e&f&g&Z%F%Z$Y$Z$Y$Y$Z$Y$Y$Z$h&i&j&k&Y$Z$Y$Y$Z$Y$Y$Y$Z$Y$Y$;&l&m&n&o&0 x p& ",
-" q&3 | r&s&t&6&Z$Y$Z$Y$Y$Z$Y$Y$Z$Y$u&v&F%Y$Z$Y$Y$Z$Y$Y$Y$Z$Y$;&@&w&x&y&| 4 z& ",
-" > 3 | A&B&C&D&;&Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$Z$E&F&G&H&I&| 9 K ",
-" J&3 | K&L&M&N&Z%F%Y$Z$Y$Y$Z$Y$Y$Z$Y$Y$Z$Y$Y$Z$Y$F%;&O&P&Q&R&S&| 9 Y ",
-" > 3 0 T&U&V&W&X&~&;&Y$Y$Z$Y$Y$Z$Y$Y$Z$Y$Y$Z$;&Y&Z&C&V&`&T&0 9 >. ",
-" @%9 | | *.*+*@*#*$*~&S%;&;&F%F%;&;&E&Y&%*&***+*=*-*| | j.;* ",
-" v%-.| 0 >*,*'*)*!*~*{*]*^*/*/*^*-#(*~*_*:*<*,*>*| &+H.[* ",
-" < &&| 0 | }*|*1*2*3*4*4*4*5*3*6*1*|*}*| 0 3 , u ",
-" < j.&+| | | | | >*7*7*>*| | | | | 9 5 6 ",
-" &$^ , ) #%3 3 3 | 3 3 9 P@t@8*u ",
-" @%; o$; &$6 d#< "};
+++ /dev/null
-/* XPM */
-static const char * add_xpm[] = {
-"48 48 636 2",
-" c None",
-". c #D8DBD9",
-"+ c #D4D5D4",
-"@ c #D4D3D3",
-"# c #D6D5D5",
-"$ c #D5D4D4",
-"% c #D3D2D2",
-"& c #D3D4D2",
-"* c #D6D9D7",
-"= c #D5D6D5",
-"- c #DBDBDB",
-"; c #E5E4E4",
-"> c #ECECEC",
-", c #F2F2F2",
-"' c #F5F5F5",
-") c #F7F7F7",
-"! c #F8F7F7",
-"~ c #F6F6F6",
-"{ c #F5F4F4",
-"] c #F0F0F0",
-"^ c #EAE9E9",
-"/ c #E1E1E1",
-"( c #D7D7D7",
-"_ c #D0D1D0",
-": c #D9D9D9",
-"< c #E7E7E7",
-"[ c #F3F3F3",
-"} c #FAFAFA",
-"| c #FDFDFD",
-"1 c #F3F9F4",
-"2 c #E0F0E2",
-"3 c #FCFCFC",
-"4 c #F8F8F8",
-"5 c #EFEFEF",
-"6 c #E2E1E1",
-"7 c #D3D3D2",
-"8 c #DADADA",
-"9 c #F9F9F9",
-"0 c #FEFEFE",
-"a c #FCFDFC",
-"b c #D7EBDC",
-"c c #99CEAA",
-"d c #5CB17B",
-"e c #28994F",
-"f c #078938",
-"g c #008536",
-"h c #E6E5E5",
-"i c #D6D7D6",
-"j c #E8E7E7",
-"k c #F2F8F3",
-"l c #A6D5B4",
-"m c #41A564",
-"n c #0C8C3E",
-"o c #008736",
-"p c #038938",
-"q c #048939",
-"r c #058A3A",
-"s c #008735",
-"t c #F2F8F4",
-"u c #E0DFDF",
-"v c #CDCFCD",
-"w c #DCDDDC",
-"x c #F2F1F1",
-"y c #A9D7B6",
-"z c #2E9D56",
-"A c #008836",
-"B c #018937",
-"C c #0F9042",
-"D c #1C964C",
-"E c #269B54",
-"F c #2B9E59",
-"G c #2FA05B",
-"H c #30A15D",
-"I c #A9D6B6",
-"J c #D3D4D3",
-"K c #E1E0E0",
-"L c #DFF0E3",
-"M c #44A866",
-"N c #008936",
-"O c #088E3C",
-"P c #1C984C",
-"Q c #2DA15A",
-"R c #32A35E",
-"S c #31A45D",
-"T c #32A45E",
-"U c #31A35D",
-"V c #2DA05A",
-"W c #F1F1F1",
-"X c #D7D6D6",
-"Y c #E4E3E3",
-"Z c #B3DBBE",
-"` c #1C9749",
-" . c #008A36",
-".. c #058E3A",
-"+. c #1B994B",
-"@. c #2EA25B",
-"#. c #31A55D",
-"$. c #32A55E",
-"%. c #31A65D",
-"&. c #32A65E",
-"*. c #32A75E",
-"=. c #1C9649",
-"-. c #F3F2F2",
-";. c #D9D9D8",
-">. c #E2E2E2",
-",. c #A1D4AF",
-"'. c #0B903C",
-"). c #008C36",
-"!. c #0D9340",
-"~. c #2AA157",
-"{. c #31A75D",
-"]. c #31A85D",
-"^. c #31A95D",
-"/. c #31AA5D",
-"(. c #2AA057",
-"_. c #0B903D",
-":. c #A0D3B0",
-"<. c #DFDFDF",
-"[. c #A0D4AF",
-"}. c #018D36",
-"|. c #018E37",
-"1. c #169847",
-"2. c #30A55C",
-"3. c #32A75D",
-"4. c #32A95D",
-"5. c #32AA5D",
-"6. c #31AA5C",
-"7. c #32AB5D",
-"8. c #33AB5D",
-"9. c #6DC38B",
-"0. c #B2DFC2",
-"a. c #5BBA80",
-"b. c #23A454",
-"c. c #32AB5C",
-"d. c #30A45C",
-"e. c #DADBDA",
-"f. c #F4F4F4",
-"g. c #B3DCBF",
-"h. c #0B923C",
-"i. c #018F37",
-"j. c #189B4A",
-"k. c #30A75C",
-"l. c #34AC5D",
-"m. c #37AD5D",
-"n. c #3CAD5C",
-"o. c #40AE5D",
-"p. c #43AE5D",
-"q. c #9AD3A6",
-"r. c #FFFFFF",
-"s. c #73C395",
-"t. c #23A04E",
-"u. c #3EAE5C",
-"v. c #3AAD5D",
-"w. c #36AC5D",
-"x. c #33AC5D",
-"y. c #189A4A",
-"z. c #ECEBEB",
-"A. c #1D9B49",
-"B. c #009036",
-"C. c #169C47",
-"D. c #30A95C",
-"E. c #33AC5C",
-"F. c #37AD5C",
-"G. c #3EAD5C",
-"H. c #44AF5C",
-"I. c #49B05C",
-"J. c #4CB05C",
-"K. c #4EB15C",
-"L. c #4FB25C",
-"M. c #A0D5A6",
-"N. c #2AA24E",
-"O. c #4DB15C",
-"P. c #4BB05C",
-"Q. c #47AF5C",
-"R. c #42AE5C",
-"S. c #3BAD5C",
-"T. c #35AC5C",
-"U. c #30A85C",
-"V. c #169B47",
-"W. c #008F36",
-"X. c #1C9A49",
-"Y. c #FBFBFB",
-"Z. c #45AD66",
-"`. c #009236",
-" + c #0D9A40",
-".+ c #30AA5B",
-"++ c #43AE5C",
-"@+ c #49B05D",
-"#+ c #50B25C",
-"$+ c #53B35C",
-"%+ c #56B45B",
-"&+ c #58B45C",
-"*+ c #5AB55C",
-"=+ c #A5D7A6",
-"-+ c #2FA44D",
-";+ c #57B45B",
-">+ c #55B35C",
-",+ c #52B35C",
-"'+ c #4CB15C",
-")+ c #47AF5D",
-"!+ c #37AC5C",
-"~+ c #30A95B",
-"{+ c #0D9940",
-"]+ c #009136",
-"^+ c #44AC66",
-"/+ c #A9DAB6",
-"(+ c #009336",
-"_+ c #059739",
-":+ c #2AA856",
-"<+ c #39AD5D",
-"[+ c #4AB05D",
-"}+ c #56B45C",
-"|+ c #59B55C",
-"1+ c #5CB75C",
-"2+ c #5EB75B",
-"3+ c #60B85B",
-"4+ c #62B95B",
-"5+ c #AAD9A5",
-"6+ c #33A64D",
-"7+ c #5BB65C",
-"8+ c #58B55C",
-"9+ c #51B25C",
-"0+ c #3FAE5D",
-"a+ c #2AA756",
-"b+ c #A9D9B6",
-"c+ c #E1E1E0",
-"d+ c #F2F9F3",
-"e+ c #2EA755",
-"f+ c #009635",
-"g+ c #1EA34A",
-"h+ c #3FAE5C",
-"i+ c #5BB65B",
-"j+ c #5FB75B",
-"k+ c #61B95B",
-"l+ c #64BA5B",
-"m+ c #66BB5A",
-"n+ c #68BC5A",
-"o+ c #69BC5A",
-"p+ c #AEDBA5",
-"q+ c #37A84D",
-"r+ c #67BB5A",
-"s+ c #65BB5B",
-"t+ c #63B95B",
-"u+ c #5AB55B",
-"v+ c #55B45C",
-"w+ c #46AF5C",
-"x+ c #3AAD5C",
-"y+ c #1CA24A",
-"z+ c #009535",
-"A+ c #2EA656",
-"B+ c #A5D9B3",
-"C+ c #009634",
-"D+ c #109C3B",
-"E+ c #42AE5A",
-"F+ c #57B45C",
-"G+ c #5CB65C",
-"H+ c #5FB85B",
-"I+ c #69BC5B",
-"J+ c #6BBD5B",
-"K+ c #6DBE5B",
-"L+ c #6FBF5C",
-"M+ c #71BF5D",
-"N+ c #B2DDA7",
-"O+ c #3CA94E",
-"P+ c #6FBE5C",
-"Q+ c #6ABD5B",
-"R+ c #68BC5B",
-"S+ c #65BA5B",
-"T+ c #5EB85B",
-"U+ c #4AB05C",
-"V+ c #3DAD5A",
-"W+ c #0C9B3B",
-"X+ c #A5D9B4",
-"Y+ c #42B163",
-"Z+ c #109B34",
-"`+ c #33A74B",
-" @ c #54B35C",
-".@ c #66BB5B",
-"+@ c #70BF5D",
-"@@ c #72C05E",
-"#@ c #74C060",
-"$@ c #75C161",
-"%@ c #76C162",
-"&@ c #B5DDAA",
-"*@ c #3FAA50",
-"=@ c #75C060",
-"-@ c #74C05F",
-";@ c #72BF5E",
-">@ c #6CBD5B",
-",@ c #5DB75C",
-"'@ c #52B25C",
-")@ c #2FA64B",
-"!@ c #0B9A34",
-"~@ c #40B063",
-"{@ c #E6E6E5",
-"]@ c #D8EEDB",
-"^@ c #1B9E3C",
-"/@ c #52B02E",
-"(@ c #4EB158",
-"_@ c #5CB65B",
-":@ c #73C05F",
-"<@ c #77C162",
-"[@ c #79C264",
-"}@ c #7BC366",
-"|@ c #7DC467",
-"1@ c #B8DFAD",
-"2@ c #42AC53",
-"3@ c #7AC365",
-"4@ c #75C160",
-"5@ c #63BA5B",
-"6@ c #4BB058",
-"7@ c #4CAE2F",
-"8@ c #149D3D",
-"9@ c #D7EEDC",
-"0@ c #EFEEEE",
-"a@ c #A1D6A9",
-"b@ c #26A033",
-"c@ c #7CC034",
-"d@ c #75C056",
-"e@ c #67BC5A",
-"f@ c #76C161",
-"g@ c #78C263",
-"h@ c #7EC468",
-"i@ c #80C46A",
-"j@ c #81C56B",
-"k@ c #83C66D",
-"l@ c #BCE0AF",
-"m@ c #45AD56",
-"n@ c #7FC469",
-"o@ c #7DC367",
-"p@ c #6EBE5B",
-"q@ c #61B85B",
-"r@ c #73BF56",
-"s@ c #76BE35",
-"t@ c #219E33",
-"u@ c #9ED5A9",
-"v@ c #F6F5F5",
-"w@ c #6FC079",
-"x@ c #3CA830",
-"y@ c #8BC63D",
-"z@ c #94CC50",
-"A@ c #7EC469",
-"B@ c #84C76D",
-"C@ c #82C56A",
-"D@ c #7DC364",
-"E@ c #B6DDA8",
-"F@ c #43AC52",
-"G@ c #81C569",
-"H@ c #83C66C",
-"I@ c #80C56B",
-"J@ c #7DC468",
-"K@ c #7AC265",
-"L@ c #67BB5B",
-"M@ c #68BB5A",
-"N@ c #86C43E",
-"O@ c #37A631",
-"P@ c #6DBF7A",
-"Q@ c #47AD4E",
-"R@ c #51AF2E",
-"S@ c #93CA45",
-"T@ c #9CCF4F",
-"U@ c #88C853",
-"V@ c #6EBE5C",
-"W@ c #9AD28C",
-"X@ c #AFDBA7",
-"Y@ c #AEDBA8",
-"Z@ c #B0DBA9",
-"`@ c #B1DCAB",
-" # c #B2DCAC",
-".# c #B4DDAD",
-"+# c #B3DDAC",
-"@# c #AFDAA6",
-"## c #ABD8A1",
-"$# c #ABD8A0",
-"%# c #D1EACB",
-"&# c #B3DEC5",
-"*# c #91CE9B",
-"=# c #AEDAA6",
-"-# c #B3DDAB",
-";# c #B1DCAA",
-"># c #AFDBA9",
-",# c #ADDBA7",
-"'# c #ACDAA6",
-")# c #81C884",
-"!# c #4CB152",
-"~# c #87C753",
-"{# c #8EC846",
-"]# c #4CAD2F",
-"^# c #44AC4E",
-"/# c #D7DAD7",
-"(# c #E3E3E3",
-"_# c #33A436",
-":# c #62B52E",
-"<# c #97CC4A",
-"[# c #9BCE4E",
-"}# c #9BCE4F",
-"|# c #83C659",
-"1# c #CBE7C3",
-"2# c #9ED5B6",
-"3# c #34A645",
-"4# c #94CB4A",
-"5# c #5CB32F",
-"6# c #2FA236",
-"7# c #F5FAF4",
-"8# c #35A533",
-"9# c #6BB92D",
-"0# c #99CD4C",
-"a# c #9ACE4F",
-"b# c #D3EAC1",
-"c# c #39A744",
-"d# c #97CC4D",
-"e# c #66B72F",
-"f# c #31A334",
-"g# c #E4E4E4",
-"h# c #E5F3E2",
-"i# c #3AA733",
-"j# c #70BB2D",
-"k# c #9ACE4E",
-"l# c #D9EDBD",
-"m# c #98CD4E",
-"n# c #6BB92F",
-"o# c #37A633",
-"p# c #E4F3E2",
-"q# c #E6F3E2",
-"r# c #40AA32",
-"s# c #72BB2D",
-"t# c #D9ECBC",
-"u# c #98CD4F",
-"v# c #6CBA2F",
-"w# c #3DA833",
-"x# c #E3E2E2",
-"y# c #45AC32",
-"z# c #99CD4D",
-"A# c #D9ECBB",
-"B# c #6AB92E",
-"C# c #42AB32",
-"D# c #4EB036",
-"E# c #6CBA2E",
-"F# c #9BCF4F",
-"G# c #97CC47",
-"H# c #D2E8B0",
-"I# c #38A743",
-"J# c #95CB4A",
-"K# c #67B82F",
-"L# c #4BAE35",
-"M# c #D5D5D4",
-"N# c #E9E9E9",
-"O# c #FBFAFA",
-"P# c #67BA50",
-"Q# c #66B730",
-"R# c #9ACD4C",
-"S# c #88C42D",
-"T# c #A6D362",
-"U# c #B6DB88",
-"V# c #B2DA89",
-"W# c #B3DA8A",
-"X# c #B8DD97",
-"Y# c #BFE0A9",
-"Z# c #C1E1AE",
-"`# c #DDEFD3",
-" $ c #9DD3A2",
-".$ c #BFE0A8",
-"+$ c #B7DD96",
-"@$ c #8AC867",
-"#$ c #61B532",
-"$$ c #90C946",
-"%$ c #61B631",
-"&$ c #64B94E",
-"*$ c #DADCD9",
-"=$ c #8ECC7C",
-"-$ c #60B636",
-";$ c #8DC73D",
-">$ c #90C83A",
-",$ c #83C124",
-"'$ c #82C023",
-")$ c #86C22C",
-"!$ c #8EC741",
-"~$ c #98CC59",
-"{$ c #CAE5AB",
-"]$ c #4FB048",
-"^$ c #8EC740",
-"/$ c #88C53F",
-"($ c #5DB435",
-"_$ c #8DCB7C",
-":$ c #B8DFAC",
-"<$ c #5EB53E",
-"[$ c #82C235",
-"}$ c #98CD4A",
-"|$ c #85C228",
-"1$ c #84C128",
-"2$ c #BDDE8E",
-"3$ c #45AA30",
-"4$ c #7CC036",
-"5$ c #5BB43C",
-"6$ c #B7DEAB",
-"7$ c #E2F1DD",
-"8$ c #66B84B",
-"9$ c #73BC31",
-"0$ c #8CC636",
-"a$ c #BBDD87",
-"b$ c #45AA2F",
-"c$ c #8AC537",
-"d$ c #6EBA32",
-"e$ c #63B748",
-"f$ c #E2F1DC",
-"g$ c #E4E4E3",
-"h$ c #FDFDFC",
-"i$ c #86C770",
-"j$ c #6CBA3E",
-"k$ c #7FBF25",
-"l$ c #82C024",
-"m$ c #7ABE26",
-"n$ c #68B83D",
-"o$ c #84C66F",
-"p$ c #D6D6D5",
-"q$ c #C6E4BA",
-"r$ c #6BBA4C",
-"s$ c #79BD2A",
-"t$ c #80BF24",
-"u$ c #73BB2C",
-"v$ c #68B94A",
-"w$ c #C4E4BA",
-"x$ c #F6FAF4",
-"y$ c #84C56A",
-"z$ c #75BC41",
-"A$ c #7EBF25",
-"B$ c #7ABD26",
-"C$ c #71BB41",
-"D$ c #81C469",
-"E$ c #DAD9D9",
-"F$ c #F7F6F6",
-"G$ c #CBE6BE",
-"H$ c #76BD54",
-"I$ c #7ABE31",
-"J$ c #81C024",
-"K$ c #7EBF24",
-"L$ c #75BC32",
-"M$ c #74BC52",
-"N$ c #C9E5BE",
-"O$ c #98CE7D",
-"P$ c #7DC050",
-"Q$ c #7CBE28",
-"R$ c #77BD29",
-"S$ c #79BE4F",
-"T$ c #95CC7C",
-"U$ c #ECF5E7",
-"V$ c #8CC86B",
-"W$ c #80C149",
-"X$ c #7DBF25",
-"Y$ c #7CC049",
-"Z$ c #8AC669",
-"`$ c #EBF5E7",
-" % c #D5EBC9",
-".% c #8BC765",
-"+% c #82C243",
-"@% c #7BBE26",
-"#% c #7EC144",
-"$% c #89C564",
-"%% c #D4EAC9",
-"&% c #D8D8D6",
-"*% c #E9E9E8",
-"=% c #CEE7BE",
-"-% c #8FC964",
-";% c #86C445",
-">% c #A6D262",
-",% c #D0E7AC",
-"'% c #79C26B",
-")% c #5CB22B",
-"!% c #82C346",
-"~% c #8CC863",
-"{% c #CDE6BD",
-"]% c #DDDDDC",
-"^% c #D1E8BF",
-"/% c #99CE6D",
-"(% c #8EC851",
-"_% c #7DBF29",
-":% c #7FBF24",
-"<% c #7ABE2A",
-"[% c #8AC650",
-"}% c #97CD6C",
-"|% c #D0E8BF",
-"1% c #EEEEED",
-"2% c #DBEDCC",
-"3% c #A5D37A",
-"4% c #97CC5F",
-"5% c #81C135",
-"6% c #7CBE26",
-"7% c #7FC136",
-"8% c #95CB5F",
-"9% c #A3D278",
-"0% c #DAEDCC",
-"a% c #EFF7E9",
-"b% c #B3DA8E",
-"c% c #9FD06D",
-"d% c #90C951",
-"e% c #7EC02D",
-"f% c #7DBE25",
-"g% c #7BBF2E",
-"h% c #B2DA8D",
-"i% c #D9ECC7",
-"j% c #AED884",
-"k% c #A2D26F",
-"l% c #93CA55",
-"m% c #85C33A",
-"n% c #7DBF28",
-"o% c #7BBE29",
-"p% c #83C33B",
-"q% c #91CA56",
-"r% c #ADD784",
-"s% c #D8ECC7",
-"t% c #E0E0DF",
-"u% c #F8FBF5",
-"v% c #D9EDC7",
-"w% c #B6DB8F",
-"x% c #A8D476",
-"y% c #A2D16A",
-"z% c #97CC5A",
-"A% c #8EC84A",
-"B% c #87C43E",
-"C% c #82C236",
-"D% c #80C132",
-"E% c #8DC84A",
-"F% c #A1D16A",
-"G% c #A7D475",
-"H% c #B5DB8F",
-"I% c #DCDCDA",
-"J% c #ECF5E3",
-"K% c #D5EABF",
-"L% c #C2E1A0",
-"M% c #AED77F",
-"N% c #A7D473",
-"O% c #AAD575",
-"P% c #AAD574",
-"Q% c #ADD77F",
-"R% c #EEF6E7",
-"S% c #E6E6E6",
-" . + @ # $ % & * ",
-" = - ; > , ' ) ! ! ~ { ] ^ / ( _ ",
-" : < [ } | | | | 1 2 2 1 | | | 3 4 5 6 7 ",
-" 8 > 9 0 a b c d e f g g g g f e d c b a | ' h % ",
-" i j 4 | k l m n o o o p q r r q p o o s n m l t 3 [ u v ",
-" w x 3 | y z s A B C D E F G H H G F E D C B A s z I | } ^ J ",
-" K 4 0 L M N N O P Q R R S T T S T T S T R U V P O N A M L | W X ",
-" Y 9 | Z ` ...+.@.S #.$.$.%.&.&.%.*.&.%.$.$.#.$.S @.+... .=.Z | -.;. ",
-" >.9 | ,.'.).!.~.#.%.{.{.].^.^././././././.^.^.].{.%.#.S (.!.)._.:.| -.X ",
-" <.9 | [.}.|.1.2.3.].4.5.6.7.8.9.0.0.0.0.0.0.a.b.c.5.5.4.].*.d.1.|.}.[.| W J ",
-" e.f.0 g.h.i.j.k.^.5.c.l.m.n.o.p.q.r.r.0 r.r.0 s.t.u.v.w.x.7.5.4.k.y.|.h.g.| ^ v ",
-" z.| L A.B.C.D./.E.F.G.H.I.J.K.L.M.0 0 0 0 0 0 s.N.O.P.Q.R.S.T.c./.U.V.W.X.L } u ",
-" u Y.| Z.`. +.+x.v.++@+O.#+$+%+&+*+=+r.r.0 r.r.0 s.-+;+>+,+L.'+)+o.!+7.~+{+]+^+| [ % ",
-" , | /+(+_+:+<+p.[+K.,+}+|+1+2+3+4+5+r.r.0 r.r.0 s.6+3+2+7+8+>+9+O.Q.0+w.a+_+`.b+3 h ",
-" c+3 d+e+f+g+h+I.K.$+;+i+j+k+l+m+n+o+p+0 0 0 0 0 0 s.q+r+s+t+3+2+u+v+9+'+w+x+y+z+A+d+' 7 ",
-" 5 0 B+C+D+E+'+,+F+G+H+t+m+I+J+K+L+M+N+r.r.0 r.r.0 s.O+P+K+Q+R+S+4+T+u+v+#+U+V+W+f+X+| 6 ",
-" <.9 a Y+Z+`+K. @*+H+t+.@Q+K++@@@#@$@%@&@r.r.0 r.r.0 s.*@=@-@;@L+>@I+S+k+,@8+'@'+)@!@~@a 5 _ ",
-" {@| ]@^@/@(@}+_@k+s+I+K+M+:@$@<@[@}@|@1@r.r.0 r.r.0 s.2@3@[@<@4@@@L+>@n+5@H+u+ @6@7@8@9@4 ( ",
-" 0@| a@b@c@d@2+4+e@>@+@:@f@g@}@h@i@j@k@l@0 0 0 0 0 0 s.m@j@n@o@3@<@4@@@p@Q+m+q@i+r@s@t@u@3 / ",
-" v@| w@x@y@z@o+o+p@@@4@g@}@A@j@k@B@C@D@E@r.r.0 r.r.0 s.F@G@k@H@I@J@K@<@#@+@>@L@M@z@N@O@P@| ^ ",
-"< 9 | Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#@###$#%#r.r.0 r.r.0 &#*###=#-#+# #;#>#,#'#)#!#~#T@{#]#^#| ] /#",
-"(#3 | _#:#<#[#}#|#1#0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2#3#}#[#4#5#6#| { & ",
-"6 3 7#8#9#0#T@T@a#b#r.r.0 r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.r.0 r.r.0 r.2#c#T@T@d#e#f#7#~ % ",
-"g#| h#i#j#k#T@T@[#l#r.r.0 r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.r.0 r.r.0 r.2#c#T@T@m#n#o#p#! $ ",
-"; 3 q#r#s#k#[#[#[#t#0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2#c#[#[#u#v#w#h#! # ",
-"x#3 7#y#j#z#T@T@[#A#r.r.0 r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.r.0 r.r.0 r.2#c#T@T@d#B#C#7#) @ ",
-"; 3 | D#E#<#T@F#G#H#r.r.0 r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.0 r.r.r.0 r.r.0 r.2#I#F#T@J#K#L#| ' M#",
-"N#O#| P#Q#S@[#R#S#T#U#V#V#V#V#W#X#Y#Z#Z#`#0 0 0 0 0 0 &# $Z#.$+$W#V#V#V#V#V#@$#$R#[#$$%$&$| , *$",
-" ) | =$-$;$[#>$,$,$,$,$'$,$'$,$,$)$!$~${$r.r.0 r.r.0 s.]$^$)$,$,$'$,$,$'$,$,$,$>$[#/$($_$| > ",
-" , | :$<$[$}$|$'$,$,$,$'$,$'$,$,$'$,$1$2$r.r.0 r.r.0 s.3$'$,$,$,$'$,$,$'$,$,$'$|$<#4$5$6$| ; ",
-" ^ | 7$8$9$0$'$'$'$'$'$'$'$'$'$'$'$'$'$a$0 0 0 0 0 0 s.b$'$'$'$'$'$'$'$'$'$'$'$'$c$d$e$f$} - ",
-" g$Y.h$i$j$k$,$'$,$,$,$'$,$'$,$,$'$,$,$a$r.r.0 r.r.0 s.b$'$,$,$,$'$,$,$'$,$,$'$l$m$n$o$h$[ p$ ",
-" f.0 q$r$s$l$'$,$,$,$'$,$'$,$,$'$,$,$a$r.r.0 r.r.0 s.b$'$,$,$,$'$,$,$'$,$,$'$t$u$v$w$0 < ",
-" < | x$y$z$A$'$'$'$'$'$'$'$'$'$'$'$'$a$0 0 0 0 0 0 s.b$'$'$'$'$'$'$'$'$'$'$l$B$C$D$x$9 E$ ",
-" F$0 G$H$I$J$,$,$,$'$,$'$,$,$'$,$,$a$r.r.0 r.r.0 s.b$'$,$,$,$'$,$,$'$,$,$K$L$M$N$| > ",
-" < | | O$P$Q$'$'$'$'$'$'$'$'$'$'$'$a$0 0 0 0 0 0 s.b$'$'$'$'$'$'$'$'$'$J$R$S$T$| 4 8 ",
-" -.| U$V$W$X$l$,$'$,$'$,$,$'$,$,$a$r.r.0 r.r.0 s.b$'$,$,$,$'$,$,$'$J$m$Y$Z$`$3 j ",
-" g$9 0 %.%+%A$l$'$,$'$,$,$'$,$,$a$r.r.0 r.r.0 s.b$'$,$,$,$'$,$,$J$@%#%$%%%0 x &% ",
-" *%3 | =%-%;%X$'$,$'$,$,$'$,$,$>%,%,%,%,%,%,%'%)%'$,$,$,$'$,$J$B$!%~%{%| 4 ]% ",
-" > 3 | ^%/%(%_%J$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$'$:%<%[%}%|%| 9 K ",
-" 1%3 | 2%3%4%5%A$l$,$'$,$,$'$,$,$'$,$,$'$,$,$'$,$l$J$6%7%8%9%0%| 9 Y ",
-" > 3 0 a%b%c%d%e%K$J$,$,$'$,$,$'$,$,$'$,$,$'$J$f%g%(%c%h%a%0 9 >. ",
-" N#9 | | i%j%k%l%m%n%K$t$J$J$l$l$J$J$:%f%o%p%q%k%r%s%| | f.t% ",
-" g$-.| 0 u%v%w%x%y%z%A%B%C%D%D%C%N@E%z%F%G%H%v%u%| Y.z.I% ",
-" < F$| 0 | J%K%L%M%N%O%O%O%P%N%Q%L%K%J%| 0 3 , u ",
-" < f.Y.| | | | | u%R%R%u%| | | | | 9 5 6 ",
-" g#^ , ) O#3 3 3 | 3 3 9 v@0@S%u ",
-" N#; x#; g#6 (#< "};
+++ /dev/null
-/* XPM */
-static const char * create_database_xpm[] = {
-"48 48 816 2",
-" c None",
-". c #BAC3C7",
-"+ c #B4BDC2",
-"@ c #B1BABF",
-"# c #B5BEC3",
-"$ c #BAC2C6",
-"% c #BDC5C9",
-"& c #BAC2C7",
-"* c #B6BFC3",
-"= c #B2BBC0",
-"- c #ABB5BA",
-"; c #B8C1C7",
-"> c #AEB8BE",
-", c #C8CFD3",
-"' c #D9DDE0",
-") c #E7EAEC",
-"! c #E9ECED",
-"~ c #E6E9EB",
-"{ c #DDE1E4",
-"] c #D1D7DA",
-"^ c #C8CFD2",
-"/ c #C4CBCF",
-"( c #C0C8CC",
-"_ c #BEC6CB",
-": c #C0C7CC",
-"< c #C2CACE",
-"[ c #C5CCD0",
-"} c #CCD2D6",
-"| c #D7DDE0",
-"1 c #E3E7E9",
-"2 c #E8EBED",
-"3 c #DDE1E3",
-"4 c #C9D0D3",
-"5 c #ACB6BC",
-"6 c #B2BBC1",
-"7 c #EEF0F2",
-"8 c #D7DCDF",
-"9 c #B8C0C5",
-"0 c #A1ADB3",
-"a c #A2AEB4",
-"b c #A6B1B8",
-"c c #C1C9CE",
-"d c #C8D0D4",
-"e c #C8D0D6",
-"f c #C6CFD5",
-"g c #C0CBD2",
-"h c #BBC6CE",
-"i c #B4C1C9",
-"j c #ACBAC2",
-"k c #A2B1BA",
-"l c #99A9B2",
-"m c #92A2AC",
-"n c #94A3AC",
-"o c #9BA8AF",
-"p c #ADB8BE",
-"q c #CFD5D9",
-"r c #EAEDEF",
-"s c #E0E4E6",
-"t c #B9C2C7",
-"u c #B8C1C6",
-"v c #EEF0F1",
-"w c #D6DBDF",
-"x c #A8B3B9",
-"y c #9AA8B0",
-"z c #B4BEC6",
-"A c #CED6DC",
-"B c #E6EBEF",
-"C c #ECF0F3",
-"D c #F0F3F5",
-"E c #F3F6F7",
-"F c #F3F6F8",
-"G c #F1F4F6",
-"H c #EDF1F4",
-"I c #E9EEF1",
-"J c #E3E9EE",
-"K c #DFE6EB",
-"L c #D9E2E8",
-"M c #D4DEE5",
-"N c #D0DBE2",
-"O c #CBD7DF",
-"P c #C5D3DC",
-"Q c #BFCFD9",
-"R c #B9CAD5",
-"S c #B4C7D2",
-"T c #AEC1CF",
-"U c #A3B7C4",
-"V c #96A8B5",
-"W c #899BA6",
-"X c #C8CFD4",
-"Y c #F0F2F3",
-"Z c #BCC4C8",
-"` c #CED4D8",
-" . c #EBEEEF",
-".. c #A6B2B8",
-"+. c #ABB8C0",
-"@. c #CCD6DD",
-"#. c #D8E1E7",
-"$. c #E0E6EB",
-"%. c #E4EAEE",
-"&. c #EAEFF2",
-"*. c #EEF1F4",
-"=. c #F8F9FA",
-"-. c #F9FAFB",
-";. c #F4F6F8",
-">. c #EEF2F5",
-",. c #EBEFF2",
-"'. c #E4EAEF",
-"). c #E0E7EC",
-"!. c #DAE3E8",
-"~. c #C6D3DD",
-"{. c #B5C7D3",
-"]. c #AFC2CF",
-"^. c #ABBFCD",
-"/. c #A8BCCB",
-"(. c #A5B9C8",
-"_. c #9FB4C1",
-":. c #91A5B1",
-"<. c #94A4AD",
-"[. c #DDE2E5",
-"}. c #D8DDDF",
-"|. c #FCFCFC",
-"1. c #B0BBC2",
-"2. c #C2CED6",
-"3. c #CFDAE2",
-"4. c #EFF2F5",
-"5. c #A2B7C5",
-"6. c #9EB4C2",
-"7. c #99AFBD",
-"8. c #8FA2AD",
-"9. c #FCFCFD",
-"0. c #FDFDFD",
-"a. c #D0DAE1",
-"b. c #CAD7DF",
-"c. c #EDF0F3",
-"d. c #E0E6EC",
-"e. c #A7BCCB",
-"f. c #A4BAC8",
-"g. c #A1B7C5",
-"h. c #9DB4C2",
-"i. c #9AB1C0",
-"j. c #FAFBFB",
-"k. c #D5DEE3",
-"l. c #C1CED4",
-"m. c #F5F8F9",
-"n. c #D5DFE5",
-"o. c #CED9E1",
-"p. c #D3DDE4",
-"q. c #D6E0E6",
-"r. c #DCE4EA",
-"s. c #E2E8ED",
-"t. c #E5EBEF",
-"u. c #EDF1F3",
-"v. c #E6ECEF",
-"w. c #DDE5EA",
-"x. c #D7E1E7",
-"y. c #D3DDE5",
-"z. c #CAD6DE",
-"A. c #C4D2DC",
-"B. c #BECED8",
-"C. c #B8C9D5",
-"D. c #B4C6D2",
-"E. c #A7BBCA",
-"F. c #A4B9C8",
-"G. c #A8BCC9",
-"H. c #E3E9ED",
-"I. c #E8EDF1",
-"J. c #628293",
-"K. c #ADBEC8",
-"L. c #F4F6F7",
-"M. c #ECF1F4",
-"N. c #D5DFE6",
-"O. c #D2DCE3",
-"P. c #CCD8E0",
-"Q. c #C9D5DE",
-"R. c #C2D1DB",
-"S. c #BCCCD7",
-"T. c #B7C9D4",
-"U. c #B2C4D1",
-"V. c #ADC0CE",
-"W. c #AABECC",
-"X. c #A6BBCA",
-"Y. c #B0C2CE",
-"Z. c #F5F7F9",
-"`. c #DDE5EB",
-" + c #AABDCB",
-".+ c #5E7F91",
-"++ c #628394",
-"@+ c #728FA0",
-"#+ c #AABCC6",
-"$+ c #E1E7EB",
-"%+ c #F7F9FA",
-"&+ c #F0F3F6",
-"*+ c #E6EBF0",
-"=+ c #E5EAEF",
-"-+ c #DBE4E9",
-";+ c #C0D0D9",
-">+ c #BACBD6",
-",+ c #B6C8D3",
-"'+ c #B7C8D4",
-")+ c #C8D5DE",
-"!+ c #DAE3E9",
-"~+ c #E3EAEE",
-"{+ c #C3D2DB",
-"]+ c #ADC1CE",
-"^+ c #A4B9C7",
-"/+ c #668698",
-"(+ c #6A899B",
-"_+ c #7391A1",
-":+ c #87A1B0",
-"<+ c #ABBDC8",
-"[+ c #CFD9E0",
-"}+ c #E7ECEF",
-"|+ c #F2F5F7",
-"1+ c #F3F5F7",
-"2+ c #EFF3F5",
-"3+ c #EBF0F3",
-"4+ c #E9EEF2",
-"5+ c #F6F8FA",
-"6+ c #DFE7EC",
-"7+ c #658697",
-"8+ c #6E8D9E",
-"9+ c #7291A2",
-"0+ c #7794A6",
-"a+ c #7B98A9",
-"b+ c #829DAE",
-"c+ c #91AAB9",
-"d+ c #AFC2CD",
-"e+ c #BECDD6",
-"f+ c #E6ECF0",
-"g+ c #FBFCFC",
-"h+ c #D2DDE4",
-"i+ c #BACBD5",
-"j+ c #819DAE",
-"k+ c #88A3B3",
-"l+ c #8EA7B7",
-"m+ c #93ACBB",
-"n+ c #99B0BF",
-"o+ c #A0B6C4",
-"p+ c #A6BBC9",
-"q+ c #ACBFCE",
-"r+ c #C1D0DA",
-"s+ c #FAFBFC",
-"t+ c #D8E2E8",
-"u+ c #93ABBB",
-"v+ c #A6BAC9",
-"w+ c #D6DFE6",
-"x+ c #728D9D",
-"y+ c #7693A3",
-"z+ c #6E8D9F",
-"A+ c #B6C5CF",
-"B+ c #AAB5BB",
-"C+ c #CAD1D5",
-"D+ c #788D99",
-"E+ c #698594",
-"F+ c #7390A1",
-"G+ c #D9E0E6",
-"H+ c #B4C0C8",
-"I+ c #9EACB5",
-"J+ c #C2CACF",
-"K+ c #ECEFF0",
-"L+ c #EBEDEF",
-"M+ c #909EA5",
-"N+ c #607580",
-"O+ c #4B6370",
-"P+ c #47606D",
-"Q+ c #526C7A",
-"R+ c #5F7988",
-"S+ c #6C8695",
-"T+ c #7B94A3",
-"U+ c #859EAD",
-"V+ c #8FA6B5",
-"W+ c #9AB0BE",
-"X+ c #A3B8C7",
-"Y+ c #DCE4E9",
-"Z+ c #E0E6EA",
-"`+ c #DEE4E7",
-" @ c #DBE0E3",
-".@ c #CDD4D8",
-"+@ c #ADB9BF",
-"@@ c #8D9DA6",
-"#@ c #6E828D",
-"$@ c #4B6471",
-"%@ c #49626E",
-"&@ c #5C727D",
-"*@ c #819199",
-"=@ c #DDE2E4",
-"-@ c #D4D9DC",
-";@ c #8F9EA6",
-">@ c #5C7380",
-",@ c #576F7C",
-"'@ c #57707D",
-")@ c #58717E",
-"!@ c #5B7481",
-"~@ c #5E7784",
-"{@ c #607986",
-"]@ c #627A88",
-"^@ c #667E8B",
-"/@ c #6A818E",
-"(@ c #6A818D",
-"_@ c #687F8B",
-":@ c #677E8A",
-"<@ c #657C89",
-"[@ c #617985",
-"}@ c #5C7481",
-"|@ c #5A727E",
-"1@ c #768993",
-"2@ c #FEFEFE",
-"3@ c #889AA4",
-"4@ c #687F8C",
-"5@ c #728793",
-"6@ c #F9FAFA",
-"7@ c #D4DEDD",
-"8@ c #C6D1D8",
-"9@ c #E7EBED",
-"0@ c #94A5AF",
-"a@ c #7E929E",
-"b@ c #8295A1",
-"c@ c #ADB6BD",
-"d@ c #BEC5C9",
-"e@ c #C6CBCF",
-"f@ c #BDC4C8",
-"g@ c #CED2D5",
-"h@ c #E9EBEC",
-"i@ c #ABC1C0",
-"j@ c #648395",
-"k@ c #B4C3CC",
-"l@ c #EDF0F2",
-"m@ c #D2D9DE",
-"n@ c #A7B5BE",
-"o@ c #97A8B3",
-"p@ c #93A5B0",
-"q@ c #9AA9B3",
-"r@ c #BCC5CA",
-"s@ c #E3E4E6",
-"t@ c #F3F4F4",
-"u@ c #E5F1E8",
-"v@ c #D4EADB",
-"w@ c #B9DDC3",
-"x@ c #B7DCC1",
-"y@ c #D2E8D9",
-"z@ c #E2EFE5",
-"A@ c #EFF1F0",
-"B@ c #E2E3E3",
-"C@ c #C7D1CB",
-"D@ c #7B97A6",
-"E@ c #B2C2CB",
-"F@ c #E9EEF0",
-"G@ c #D7DEE3",
-"H@ c #C1CDD4",
-"I@ c #AFBEC8",
-"J@ c #A4B5C1",
-"K@ c #A3B4BF",
-"L@ c #A3B4C0",
-"M@ c #BBC5CC",
-"N@ c #E9EAEB",
-"O@ c #F5F9F5",
-"P@ c #A2D3B1",
-"Q@ c #48A86C",
-"R@ c #128F41",
-"S@ c #018636",
-"T@ c #008636",
-"U@ c #0F8D3F",
-"V@ c #43A567",
-"W@ c #98CEA9",
-"X@ c #EEF3EF",
-"Y@ c #E5E4E4",
-"Z@ c #6F8E9F",
-"`@ c #8AA4B2",
-" # c #B0C1CC",
-".# c #F2F4F6",
-"+# c #E8EDF0",
-"@# c #DBE2E8",
-"## c #D6DEE4",
-"$# c #D3DCE3",
-"%# c #D2DBE2",
-"&# c #D1DAE1",
-"*# c #D5DEE4",
-"=# c #D8E0E5",
-"-# c #F7F8F7",
-";# c #B0DABC",
-"># c #21974D",
-",# c #038A38",
-"'# c #109142",
-")# c #20994F",
-"!# c #2A9F57",
-"~# c #2FA15C",
-"{# c #30A25C",
-"]# c #2CA059",
-"^# c #249B53",
-"/# c #169447",
-"(# c #078B3B",
-"_# c #199346",
-":# c #A4D4B2",
-"<# c #EFF0EF",
-"[# c #CCD3CE",
-"}# c #7C98A9",
-"|# c #86A1B1",
-"1# c #94ABBA",
-"2# c #A4B9C6",
-"3# c #B4C5D0",
-"4# c #C2D0D9",
-"5# c #CFDAE1",
-"6# c #D8E1E8",
-"7# c #ECF1F3",
-"8# c #F2F2F2",
-"9# c #F5F9F6",
-"0# c #75C08C",
-"a# c #078E3B",
-"b# c #129444",
-"c# c #29A057",
-"d# c #31A55D",
-"e# c #32A65E",
-"f# c #32A75E",
-"g# c #31A65D",
-"h# c #32A55E",
-"i# c #31A45D",
-"j# c #2EA25A",
-"k# c #1C994C",
-"l# c #098E3C",
-"m# c #66B881",
-"n# c #ECF1ED",
-"o# c #CBD4CE",
-"p# c #E5E9EB",
-"q# c #FBFBFB",
-"r# c #69BB82",
-"s# c #048F38",
-"t# c #1D9C4D",
-"u# c #32A95D",
-"v# c #33AA5D",
-"w# c #36AB5D",
-"x# c #A3D9B6",
-"y# c #AFDEC1",
-"z# c #AFDEC0",
-"A# c #A0D7B5",
-"B# c #2BA65A",
-"C# c #32A85D",
-"D# c #28A056",
-"E# c #0A913D",
-"F# c #57B375",
-"G# c #F3F4F3",
-"H# c #C7CFC9",
-"I# c #DAE1E6",
-"J# c #F8F8F8",
-"K# c #90CEA2",
-"L# c #029037",
-"M# c #21A04F",
-"N# c #34AA5D",
-"O# c #3AAD5D",
-"P# c #41AE5C",
-"Q# c #47B05C",
-"R# c #4DB15D",
-"S# c #E9F5EB",
-"T# c #E6F4EC",
-"U# c #32A658",
-"V# c #45AF5C",
-"W# c #3FAE5C",
-"X# c #38AC5D",
-"Y# c #2CA459",
-"Z# c #09923D",
-"`# c #7AC391",
-" $ c #EBECEB",
-".$ c #EBEEF0",
-"+$ c #D6EDDB",
-"@$ c #119941",
-"#$ c #1BA04A",
-"$$ c #3CAD5C",
-"%$ c #50B25C",
-"&$ c #56B45C",
-"*$ c #5AB65B",
-"=$ c #5EB85C",
-"-$ c #EBF6EB",
-";$ c #FFFFFF",
-">$ c #3AA957",
-",$ c #59B55B",
-"'$ c #54B35C",
-")$ c #4DB15C",
-"!$ c #43AE5C",
-"~$ c #39AC5D",
-"{$ c #29A556",
-"]$ c #0D963E",
-"^$ c #C6E4CE",
-"/$ c #D9DBD9",
-"($ c #62BC7D",
-"_$ c #0E9B3C",
-":$ c #42AE5B",
-"<$ c #58B55B",
-"[$ c #5FB85B",
-"}$ c #65BB5B",
-"|$ c #69BC5B",
-"1$ c #6DBE5D",
-"2$ c #EDF7EB",
-"3$ c #41AC57",
-"4$ c #68BB5B",
-"5$ c #63BA5B",
-"6$ c #5DB75B",
-"7$ c #4CB15C",
-"8$ c #3FAE5D",
-"9$ c #1BA049",
-"0$ c #4DB36E",
-"a$ c #F2F1F1",
-"b$ c #6E8A99",
-"c$ c #718EA0",
-"d$ c #E2E7EA",
-"e$ c #E2F2E4",
-"f$ c #29A440",
-"g$ c #3BAA4D",
-"h$ c #56B45B",
-"i$ c #67BB5B",
-"j$ c #6DBE5C",
-"k$ c #72BF5F",
-"l$ c #76C061",
-"m$ c #79C264",
-"n$ c #EEF7EC",
-"o$ c #47AE5A",
-"p$ c #74C060",
-"q$ c #70BF5D",
-"r$ c #6BBD5B",
-"s$ c #64BA5B",
-"t$ c #5CB75B",
-"u$ c #52B35C",
-"v$ c #40AD59",
-"w$ c #20A23E",
-"x$ c #D1EAD7",
-"y$ c #CDD5CD",
-"z$ c #A6B2B9",
-"A$ c #E1E5E7",
-"B$ c #7B909D",
-"C$ c #6B8797",
-"D$ c #728E9F",
-"E$ c #7B98A8",
-"F$ c #C2D0DA",
-"G$ c #EFF1F3",
-"H$ c #ADDBB4",
-"I$ c #52B030",
-"J$ c #6BBC54",
-"K$ c #78C163",
-"L$ c #7CC367",
-"M$ c #80C56A",
-"N$ c #83C66C",
-"O$ c #EFF8ED",
-"P$ c #4BB05E",
-"Q$ c #7FC469",
-"R$ c #7BC265",
-"S$ c #76C161",
-"T$ c #60B85B",
-"U$ c #65BA59",
-"V$ c #56B33D",
-"W$ c #93D1A0",
-"X$ c #E2E1E1",
-"Y$ c #EFF1F2",
-"Z$ c #9AA7AD",
-"`$ c #627580",
-" % c #4C6370",
-".% c #435C69",
-"+% c #6E8897",
-"@% c #7D96A5",
-"#% c #89A2B2",
-"$% c #96ADBC",
-"%% c #F8F8F9",
-"&% c #82C786",
-"*% c #73BC32",
-"=% c #93CB50",
-"-% c #78C365",
-";% c #A7D89C",
-">% c #ACD9A2",
-",% c #B0DBA5",
-"'% c #B2DCA7",
-")% c #B1DBA5",
-"!% c #AFDAA1",
-"~% c #F5FAF3",
-"{% c #F0F8F4",
-"]% c #90CE9B",
-"^% c #AFDAA2",
-"/% c #AEDAA4",
-"(% c #ABD8A0",
-"_% c #A5D79C",
-":% c #5EB862",
-"<% c #8ECA51",
-"[% c #79C044",
-"}% c #70C07C",
-"|% c #EDECEC",
-"1% c #8E9DA5",
-"2% c #58707D",
-"3% c #536C79",
-"4% c #627A87",
-"5% c #677E8B",
-"6% c #82959F",
-"7% c #76C172",
-"8% c #82C338",
-"9% c #9BCE4E",
-"0% c #A2D36E",
-"a% c #F8FCF7",
-"b% c #F9FCFB",
-"c% c #5BB66A",
-"d% c #86C64A",
-"e% c #5AB557",
-"f% c #FDFEFE",
-"g% c #8497A1",
-"h% c #647C89",
-"i% c #647B88",
-"j% c #80939D",
-"k% c #72C063",
-"l% c #86C43A",
-"m% c #ABD669",
-"n% c #FAFCF6",
-"o% c #5CB76A",
-"p% c #8BC84C",
-"q% c #57B44C",
-"r% c #F3F3F3",
-"s% c #CFD8DE",
-"t% c #E1E6E8",
-"u% c #889AA5",
-"v% c #778C99",
-"w% c #8C9DA8",
-"x% c #81C771",
-"y% c #85C439",
-"z% c #AAD568",
-"A% c #FAFCF5",
-"B% c #5BB76A",
-"C% c #8AC74B",
-"D% c #66BB55",
-"E% c #638294",
-"F% c #BBC9D1",
-"G% c #CAD3D8",
-"H% c #A1B0B9",
-"I% c #90A2AD",
-"J% c #8EA1AC",
-"K% c #8FA1AC",
-"L% c #99A9B3",
-"M% c #F6F7F8",
-"N% c #97D087",
-"O% c #7FC136",
-"P% c #96CB45",
-"Q% c #B4DA84",
-"R% c #B3DA89",
-"S% c #B4DB8C",
-"T% c #BADE9D",
-"U% c #C1E1AC",
-"V% c #F7FBF5",
-"W% c #F1F9F5",
-"X% c #A0D5A6",
-"Y% c #BBDE9E",
-"Z% c #B4DB8D",
-"`% c #B0D987",
-" & c #6EBB43",
-".& c #99CD4B",
-"+& c #82C447",
-"@& c #8ACA7A",
-"#& c #EFEFEF",
-"$& c #638495",
-"%& c #7F9AA9",
-"&& c #B9C7D0",
-"*& c #E8ECEF",
-"=& c #E8ECEE",
-"-& c #D1D9DE",
-";& c #BBC7CF",
-">& c #ABB9C4",
-",& c #A5B5C0",
-"'& c #A1B2BD",
-")& c #A0B1BC",
-"!& c #A3B3BE",
-"~& c #BFE2B4",
-"{& c #73BC36",
-"]& c #95CB44",
-"^& c #83C124",
-"/& c #82C023",
-"(& c #83C126",
-"_& c #89C434",
-":& c #F1F8E7",
-"<& c #4EAF41",
-"[& c #8CC637",
-"}& c #76BF42",
-"|& c #ACD99F",
-"1& c #E7E6E6",
-"2& c #7593A3",
-"3& c #94ABB8",
-"4& c #B7C7D0",
-"5& c #DBE3E8",
-"6& c #EBEFF1",
-"7& c #E2E8EC",
-"8& c #DBE2E7",
-"9& c #D5DDE3",
-"0& c #CFD9DF",
-"a& c #CDD7DE",
-"b& c #CBD5DD",
-"c& c #C9D4DC",
-"d& c #E9ECEF",
-"e& c #E8F4E3",
-"f& c #73BD49",
-"g& c #85C22A",
-"h& c #83C125",
-"i& c #EFF7E4",
-"j& c #4CAE3D",
-"k& c #7FC028",
-"l& c #6ABA43",
-"m& c #DCEED6",
-"n& c #D7DDD3",
-"o& c #92AAB9",
-"p& c #A9BCC9",
-"q& c #B9C9D3",
-"r& c #C7D4DC",
-"s& c #E1E8ED",
-"t& c #E7EDF0",
-"u& c #9BD084",
-"v& c #7CBE2E",
-"w& c #74BC2D",
-"x& c #8CCA75",
-"y& c #F6F6F6",
-"z& c #F0F2F4",
-"A& c #E2F1DB",
-"B& c #7EC150",
-"C& c #81C025",
-"D& c #82C124",
-"E& c #7DBF25",
-"F& c #74BD48",
-"G& c #D7ECCF",
-"H& c #E4E5E2",
-"I& c #DDE4E9",
-"J& c #BCDFA9",
-"K& c #81C13F",
-"L& c #82C024",
-"M& c #80C024",
-"N& c #78BE3B",
-"O& c #AED89A",
-"P& c #607F91",
-"Q& c #EBEEF1",
-"R& c #AFD993",
-"S& c #86C441",
-"T& c #CBE5A8",
-"U& c #D0E9BB",
-"V& c #C1E2AE",
-"W& c #5DB435",
-"X& c #7FBF24",
-"Y& c #7DC03D",
-"Z& c #A4D387",
-"`& c #F8F9F7",
-" * c #DADDD5",
-".* c #6D8491",
-"+* c #638394",
-"@* c #F2F4F5",
-"#* c #F9FBF7",
-"$* c #BADE9E",
-"%* c #90C950",
-"&* c #82C128",
-"** c #7EBF28",
-"=* c #87C54B",
-"-* c #B1DA94",
-";* c #F4F8F1",
-">* c #E1E4DC",
-",* c #728792",
-"'* c #F5F6F7",
-")* c #FBFCFA",
-"!* c #D7EBC4",
-"~* c #9FD06C",
-"{* c #8BC642",
-"]* c #81C027",
-"^* c #81C024",
-"/* c #7EBF27",
-"(* c #86C440",
-"_* c #99CD66",
-":* c #D1E9BD",
-"<* c #E2E5DE",
-"[* c #758893",
-"}* c #738A97",
-"|* c #738F9E",
-"1* c #7793A4",
-"2* c #FAFAFB",
-"3* c #D2E9BB",
-"4* c #B3DA8B",
-"5* c #98CD5D",
-"6* c #91C94D",
-"7* c #8DC746",
-"8* c #8CC746",
-"9* c #8FC84D",
-"0* c #95CB5B",
-"a* c #B0D886",
-"b* c #CEE7B6",
-"c* c #F4F9F1",
-"d* c #778B96",
-"e* c #798E9A",
-"f* c #7C929F",
-"g* c #8399A7",
-"h* c #89A1B0",
-"i* c #90A8B7",
-"j* c #97ADBC",
-"k* c #DEE5EA",
-"l* c #E5EAEE",
-"m* c #EAEDF0",
-"n* c #E3E6E8",
-"o* c #D5DADC",
-"p* c #F0F1F2",
-"q* c #FAFBF9",
-"r* c #F2F8ED",
-"s* c #E6F3DA",
-"t* c #D8ECC6",
-"u* c #D7ECC5",
-"v* c #E5F2D8",
-"w* c #F2F8EC",
-"x* c #F8FAF7",
-"y* c #F4F4F3",
-"z* c #E2E4DF",
-"A* c #8496A2",
-"B* c #82949E",
-"C* c #81929C",
-"D* c #83949E",
-"E* c #8797A1",
-"F* c #8B9BA4",
-"G* c #8D9CA4",
-"H* c #8D9BA4",
-"I* c #8B99A1",
-"J* c #A4AFB6",
-"K* c #E7EDDF",
-"L* c #EDEDEB",
-"M* c #EFEEEE",
-"N* c #EBEBEB",
-"O* c #E4E9DD",
-" . + @ # $ % & * = - ; ",
-" > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 ) 3 4 5 ",
-" 6 ' 7 8 9 0 a b > ; c d e e f g h i j k l m n o p q r s t ",
-" u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W y X Y Z ",
-" ` ...+.@.#.$.%.&.*.E =.-.;.>.,.'.).!.M N O ~.Q R {.].^./.(._.:.<.[.}. ",
-" |.1.2.3.M L $.%.&.*.F -.-.;.4.,.'.).!.M N O ~.Q R {.].^./.(.5.6.7.8.9. ",
-" 0.a.b.3.M #.K J I c.G ;.;.G H I J d.L M N O P Q R S T ^.e.f.g.h.i.6.j.k. ",
-" l.m.n.o.p.q.r.s.t.&.u.4.4.H ,.v.s.w.x.y.o.z.A.B.C.D.T ^.E.F.g.h.G.H.I. ",
-" J.K.L.M.r.N.L K s.B I ,.,.I v.H.K !.n.O.P.Q.R.S.T.U.V.W.X.F.Y.p.Z.`. + ",
-" .+++@+#+$+%+&+&.*+=+J '.'.J s.K -+q.p.3.O ~.;+>+,+'+S.)+!+&+=.~+{+]+^+ ",
-" .+++/+(+_+:+<+[+}+|+%+%+Z.1+2+H 3+4+I.B t.t.4+H F %+-.5+H 6+M )+>+]+^+ ",
-" .+++7+(+8+9+0+a+b+c+U d+e+O M L ).f+4+M.&+;.%+0.g+Z.H t.K #.h+)+i+V.^+ ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+)+>+]+^+ ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+)+>+]+^+ ",
-" .+++7+(+8+9+0+a+j+k+l+u+n+o+v+q+{.r+P.w+).I |+9.s+;.H t.K #.h+)+i+V.^+ ",
-" ++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+)+>+]+ ",
-" x+y+z+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+P.A+ ",
-" B+) C+D+E+F+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.G+H+I+J+K+. ",
-" < L+M+N+O+P+P+Q+R+S+T+U+V+W+X+^.{.r+P.N.Y+Z+`+ @.@+@@@#@$@P+%@&@*@=@-@ ",
-" g+;@>@,@'@'@,@'@'@'@'@)@!@~@{@]@^@/@(@_@:@<@[@}@'@'@'@,@'@'@'@,@|@1@g+ ",
-" 2@3@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@5@6@7@ ",
-" 8@9@0@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@b@n c@d@e@e@f@g@h@i@ ",
-" j@k@l@m@n@o@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@q@r@s@t@u@v@w@x@y@z@A@B@C@ ",
-" .+++D@E@F@l@G@H@I@J@K@L@K@L@L@K@L@L@K@L@L@K@L@M@N@O@P@Q@R@S@T@T@T@U@V@W@X@Y@ ",
-" .+++7+(+Z@`@ #k.F@Z..#+#$+@###$#%#a.&#$#*#=#{ -#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[# ",
-" .+++/+(+8+9+0+}#|#1#2#3#4#5#6#`.%.4+7#>.G 8#9#0#a#b#c#d#e#e#f#g#e#h#i#j#k#l#m#n#o# ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.p#q#r#s#t#g#u#v#w#x#y#z#A#B#u#C#e#D#E#F#G#H# ",
-" .+++7+(+8+9+0+a+j+k+l+u+n+o+v+q+{.r+P.I#J#K#L#M#N#O#P#Q#R#S#2@2@T#U#V#W#X#v#Y#Z#`# $ ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P..$+$@$#$$$Q#%$&$*$=$-$;$2@T#>$,$'$)$!$~${$]$^$/$ ",
-" ++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+%#q#($_$:$%$<$[$}$|$1$2$;$2@T#3$4$5$6$&$7$8$9$0$a$ ",
-" b$c$8+9+0+a+j+k+l+u+n+o+v+q+{.r+d$e$f$g$h$[$i$j$k$l$m$n$2@2@T#o$p$q$r$s$t$u$v$w$x$y$ ",
-" z$A$X B$C$D$E$j+k+l+m+n+o+p+q+{.F$G$H$I$J$s$r$k$K$L$M$N$O$;$2@T#P$Q$R$S$q$|$T$U$V$W$X$ ",
-" . Y$Z$`$ %.%P+Q+R++%@%#%$%o+p+q+{.P %%&%*%=%-%;%>%,%'%)%!%~%;$2@{%]%^%,%/%(%_%:%<%[%}%|% ",
-" g+1%2%3%3%3%3%3%3%3%3%3%3%)@~@4%5%6%q#7%8%9%0%a%2@2@2@2@2@2@2@2@2@2@2@2@2@2@b%c%9%d%e%a$ ",
-" f%g%h%i%h%h%i%h%h%h%i%h%i%h%h%i%h%j%q#k%l%9%m%n%2@;$;$2@;$;$;$2@;$;$2@;$;$2@b%o%9%p%q%r% ",
-" s%t%u%v%v%v%v%v%v%v%v%v%v%v%v%v%v%w%q#x%y%9%z%A%2@2@2@2@2@2@2@2@2@2@2@2@2@2@b%B%9%C%D%8# ",
-" E%F%.#G%H%I%J%K%K%K%J%K%J%K%K%J%K%L%M%N%O%9%P%Q%R%R%S%T%U%V%;$2@W%X%Y%Z%R%R%`% &.&+&@&#& ",
-" .+$&%&&&*&=&-&;&>&,&'&)&)&)&)&)&)&!&.$~&{&]&^&^&/&^&^&(&_&:&;$2@T#<&(&^&^&/&^&^&[&}&|&1& ",
-" .+++/+(+2&3&4&5&G ;.6&7&8&9&0&a&b&c&d&e&f&g&^&^&/&^&^&/&h&i&;$2@T#j&/&^&^&/&^&^&k&l&m&n& ",
-" .+++7+(+8+9+0+a+j+o&p&q&r&M w.s&t&C l@0.u&v&/&/&/&/&/&/&h&i&2@2@T#j&/&/&/&/&/&/&w&x&y& ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.z&A&B&C&^&/&^&^&/&h&i&;$2@T#j&/&^&^&/&D&E&F&G&H& ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.I&q#J&K&L&/&^&^&/&h&i&;$2@T#j&/&^&^&/&M&N&O&G# ",
-" P&++7+(+8+9+0+a+j+k+l+u+n+o+v+q+{.r+P.w+Q&0.R&S&L&/&/&/&^&T&U&U&V&W&/&/&/&X&Y&Z&`& * ",
-" .*+*/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).@*#*$*%*&*L&/&^&^&^&/&^&^&/&L&**=*-*;*>* ",
-" ,*S+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I '*)*!*~*{*]*L&^&^&/&D&^*/*(*_*:*`&<* ",
-" [*}*|*1*a+j+k+l+u+n+o+v+q+{.r+P.w+).I |+J#2*V%3*4*5*6*7*8*9*0*a*b*c*r% ",
-" d*e*f*g*h*i*j*6.(.^.{.r+P.n.k*l*m*v n*o*p*q*r*s*t*u*v*w*x*y*z* ",
-" A*B*C*D*E*F*G*G*H*I*J* K*L*#&M*N*O* "};
+++ /dev/null
-/* XPM */
-static const char * database_add_xpm[] = {
-"48 48 816 2",
-" c None",
-". c #BAC3C7",
-"+ c #B4BDC2",
-"@ c #B1BABF",
-"# c #B5BEC3",
-"$ c #BAC2C6",
-"% c #BDC5C9",
-"& c #BAC2C7",
-"* c #B6BFC3",
-"= c #B2BBC0",
-"- c #ABB5BA",
-"; c #B8C1C7",
-"> c #AEB8BE",
-", c #C8CFD3",
-"' c #D9DDE0",
-") c #E7EAEC",
-"! c #E9ECED",
-"~ c #E6E9EB",
-"{ c #DDE1E4",
-"] c #D1D7DA",
-"^ c #C8CFD2",
-"/ c #C4CBCF",
-"( c #C0C8CC",
-"_ c #BEC6CB",
-": c #C0C7CC",
-"< c #C2CACE",
-"[ c #C5CCD0",
-"} c #CCD2D6",
-"| c #D7DDE0",
-"1 c #E3E7E9",
-"2 c #E8EBED",
-"3 c #DDE1E3",
-"4 c #C9D0D3",
-"5 c #ACB6BC",
-"6 c #B2BBC1",
-"7 c #EEF0F2",
-"8 c #D7DCDF",
-"9 c #B8C0C5",
-"0 c #A1ADB3",
-"a c #A2AEB4",
-"b c #A6B1B8",
-"c c #C1C9CE",
-"d c #C8D0D4",
-"e c #C8D0D6",
-"f c #C6CFD5",
-"g c #C0CBD2",
-"h c #BBC6CE",
-"i c #B4C1C9",
-"j c #ACBAC2",
-"k c #A2B1BA",
-"l c #99A9B2",
-"m c #92A2AC",
-"n c #94A3AC",
-"o c #9BA8AF",
-"p c #ADB8BE",
-"q c #CFD5D9",
-"r c #EAEDEF",
-"s c #E0E4E6",
-"t c #B9C2C7",
-"u c #B8C1C6",
-"v c #EEF0F1",
-"w c #D6DBDF",
-"x c #A8B3B9",
-"y c #9AA8B0",
-"z c #B4BEC6",
-"A c #CED6DC",
-"B c #E6EBEF",
-"C c #ECF0F3",
-"D c #F0F3F5",
-"E c #F3F6F7",
-"F c #F3F6F8",
-"G c #F1F4F6",
-"H c #EDF1F4",
-"I c #E9EEF1",
-"J c #E3E9EE",
-"K c #DFE6EB",
-"L c #D9E2E8",
-"M c #D4DEE5",
-"N c #D0DBE2",
-"O c #CBD7DF",
-"P c #C5D3DC",
-"Q c #BFCFD9",
-"R c #B9CAD5",
-"S c #B4C7D2",
-"T c #AEC1CF",
-"U c #A3B7C4",
-"V c #96A8B5",
-"W c #899BA6",
-"X c #C8CFD4",
-"Y c #F0F2F3",
-"Z c #BCC4C8",
-"` c #CED4D8",
-" . c #EBEEEF",
-".. c #A6B2B8",
-"+. c #ABB8C0",
-"@. c #CCD6DD",
-"#. c #D8E1E7",
-"$. c #E0E6EB",
-"%. c #E4EAEE",
-"&. c #EAEFF2",
-"*. c #EEF1F4",
-"=. c #F8F9FA",
-"-. c #F9FAFB",
-";. c #F4F6F8",
-">. c #EEF2F5",
-",. c #EBEFF2",
-"'. c #E4EAEF",
-"). c #E0E7EC",
-"!. c #DAE3E8",
-"~. c #C6D3DD",
-"{. c #B5C7D3",
-"]. c #AFC2CF",
-"^. c #ABBFCD",
-"/. c #A8BCCB",
-"(. c #A5B9C8",
-"_. c #9FB4C1",
-":. c #91A5B1",
-"<. c #94A4AD",
-"[. c #DDE2E5",
-"}. c #D8DDDF",
-"|. c #FCFCFC",
-"1. c #B0BBC2",
-"2. c #C2CED6",
-"3. c #CFDAE2",
-"4. c #EFF2F5",
-"5. c #A2B7C5",
-"6. c #9EB4C2",
-"7. c #99AFBD",
-"8. c #8FA2AD",
-"9. c #FCFCFD",
-"0. c #FDFDFD",
-"a. c #D0DAE1",
-"b. c #CAD7DF",
-"c. c #EDF0F3",
-"d. c #E0E6EC",
-"e. c #A7BCCB",
-"f. c #A4BAC8",
-"g. c #A1B7C5",
-"h. c #9DB4C2",
-"i. c #9AB1C0",
-"j. c #FAFBFB",
-"k. c #D5DEE3",
-"l. c #C1CED4",
-"m. c #F5F8F9",
-"n. c #D5DFE5",
-"o. c #CED9E1",
-"p. c #D3DDE4",
-"q. c #D6E0E6",
-"r. c #DCE4EA",
-"s. c #E2E8ED",
-"t. c #E5EBEF",
-"u. c #EDF1F3",
-"v. c #E6ECEF",
-"w. c #DDE5EA",
-"x. c #D7E1E7",
-"y. c #D3DDE5",
-"z. c #CAD6DE",
-"A. c #C4D2DC",
-"B. c #BECED8",
-"C. c #B8C9D5",
-"D. c #B4C6D2",
-"E. c #A7BBCA",
-"F. c #A4B9C8",
-"G. c #A8BCC9",
-"H. c #E3E9ED",
-"I. c #E8EDF1",
-"J. c #628293",
-"K. c #ADBEC8",
-"L. c #F4F6F7",
-"M. c #ECF1F4",
-"N. c #D5DFE6",
-"O. c #D2DCE3",
-"P. c #CCD8E0",
-"Q. c #C9D5DE",
-"R. c #C2D1DB",
-"S. c #BCCCD7",
-"T. c #B7C9D4",
-"U. c #B2C4D1",
-"V. c #ADC0CE",
-"W. c #AABECC",
-"X. c #A6BBCA",
-"Y. c #B0C2CE",
-"Z. c #F5F7F9",
-"`. c #DDE5EB",
-" + c #AABDCB",
-".+ c #5E7F91",
-"++ c #628394",
-"@+ c #728FA0",
-"#+ c #AABCC6",
-"$+ c #E1E7EB",
-"%+ c #F7F9FA",
-"&+ c #F0F3F6",
-"*+ c #E6EBF0",
-"=+ c #E5EAEF",
-"-+ c #DBE4E9",
-";+ c #C0D0D9",
-">+ c #BACBD6",
-",+ c #B6C8D3",
-"'+ c #B7C8D4",
-")+ c #C8D5DE",
-"!+ c #DAE3E9",
-"~+ c #E3EAEE",
-"{+ c #C3D2DB",
-"]+ c #ADC1CE",
-"^+ c #A4B9C7",
-"/+ c #668698",
-"(+ c #6A899B",
-"_+ c #7391A1",
-":+ c #87A1B0",
-"<+ c #ABBDC8",
-"[+ c #CFD9E0",
-"}+ c #E7ECEF",
-"|+ c #F2F5F7",
-"1+ c #F3F5F7",
-"2+ c #EFF3F5",
-"3+ c #EBF0F3",
-"4+ c #E9EEF2",
-"5+ c #F6F8FA",
-"6+ c #DFE7EC",
-"7+ c #658697",
-"8+ c #6E8D9E",
-"9+ c #7291A2",
-"0+ c #7794A6",
-"a+ c #7B98A9",
-"b+ c #829DAE",
-"c+ c #91AAB9",
-"d+ c #AFC2CD",
-"e+ c #BECDD6",
-"f+ c #E6ECF0",
-"g+ c #FBFCFC",
-"h+ c #D2DDE4",
-"i+ c #BACBD5",
-"j+ c #819DAE",
-"k+ c #88A3B3",
-"l+ c #8EA7B7",
-"m+ c #93ACBB",
-"n+ c #99B0BF",
-"o+ c #A0B6C4",
-"p+ c #A6BBC9",
-"q+ c #ACBFCE",
-"r+ c #C1D0DA",
-"s+ c #FAFBFC",
-"t+ c #D8E2E8",
-"u+ c #93ABBB",
-"v+ c #A6BAC9",
-"w+ c #D6DFE6",
-"x+ c #728D9D",
-"y+ c #7693A3",
-"z+ c #6E8D9F",
-"A+ c #B6C5CF",
-"B+ c #AAB5BB",
-"C+ c #CAD1D5",
-"D+ c #788D99",
-"E+ c #698594",
-"F+ c #7390A1",
-"G+ c #D9E0E6",
-"H+ c #B4C0C8",
-"I+ c #9EACB5",
-"J+ c #C2CACF",
-"K+ c #ECEFF0",
-"L+ c #EBEDEF",
-"M+ c #909EA5",
-"N+ c #607580",
-"O+ c #4B6370",
-"P+ c #47606D",
-"Q+ c #526C7A",
-"R+ c #5F7988",
-"S+ c #6C8695",
-"T+ c #7B94A3",
-"U+ c #859EAD",
-"V+ c #8FA6B5",
-"W+ c #9AB0BE",
-"X+ c #A3B8C7",
-"Y+ c #DCE4E9",
-"Z+ c #E0E6EA",
-"`+ c #DEE4E7",
-" @ c #DBE0E3",
-".@ c #CDD4D8",
-"+@ c #ADB9BF",
-"@@ c #8D9DA6",
-"#@ c #6E828D",
-"$@ c #4B6471",
-"%@ c #49626E",
-"&@ c #5C727D",
-"*@ c #819199",
-"=@ c #DDE2E4",
-"-@ c #D4D9DC",
-";@ c #8F9EA6",
-">@ c #5C7380",
-",@ c #576F7C",
-"'@ c #57707D",
-")@ c #58717E",
-"!@ c #5B7481",
-"~@ c #5E7784",
-"{@ c #607986",
-"]@ c #627A88",
-"^@ c #667E8B",
-"/@ c #6A818E",
-"(@ c #6A818D",
-"_@ c #687F8B",
-":@ c #677E8A",
-"<@ c #657C89",
-"[@ c #617985",
-"}@ c #5C7481",
-"|@ c #5A727E",
-"1@ c #768993",
-"2@ c #FEFEFE",
-"3@ c #889AA4",
-"4@ c #687F8C",
-"5@ c #728793",
-"6@ c #F9FAFA",
-"7@ c #D4DEDD",
-"8@ c #C6D1D8",
-"9@ c #E7EBED",
-"0@ c #94A5AF",
-"a@ c #7E929E",
-"b@ c #8295A1",
-"c@ c #ADB6BD",
-"d@ c #BEC5C9",
-"e@ c #C6CBCF",
-"f@ c #BDC4C8",
-"g@ c #CED2D5",
-"h@ c #E9EBEC",
-"i@ c #ABC1C0",
-"j@ c #648395",
-"k@ c #B4C3CC",
-"l@ c #EDF0F2",
-"m@ c #D2D9DE",
-"n@ c #A7B5BE",
-"o@ c #97A8B3",
-"p@ c #93A5B0",
-"q@ c #9AA9B3",
-"r@ c #BCC5CA",
-"s@ c #E3E4E6",
-"t@ c #F3F4F4",
-"u@ c #E5F1E8",
-"v@ c #D4EADB",
-"w@ c #B9DDC3",
-"x@ c #B7DCC1",
-"y@ c #D2E8D9",
-"z@ c #E2EFE5",
-"A@ c #EFF1F0",
-"B@ c #E2E3E3",
-"C@ c #C7D1CB",
-"D@ c #7B97A6",
-"E@ c #B2C2CB",
-"F@ c #E9EEF0",
-"G@ c #D7DEE3",
-"H@ c #C1CDD4",
-"I@ c #AFBEC8",
-"J@ c #A4B5C1",
-"K@ c #A3B4BF",
-"L@ c #A3B4C0",
-"M@ c #BBC5CC",
-"N@ c #E9EAEB",
-"O@ c #F5F9F5",
-"P@ c #A2D3B1",
-"Q@ c #48A86C",
-"R@ c #128F41",
-"S@ c #018636",
-"T@ c #008636",
-"U@ c #0F8D3F",
-"V@ c #43A567",
-"W@ c #98CEA9",
-"X@ c #EEF3EF",
-"Y@ c #E5E4E4",
-"Z@ c #6F8E9F",
-"`@ c #8AA4B2",
-" # c #B0C1CC",
-".# c #F2F4F6",
-"+# c #E8EDF0",
-"@# c #DBE2E8",
-"## c #D6DEE4",
-"$# c #D3DCE3",
-"%# c #D2DBE2",
-"&# c #D1DAE1",
-"*# c #D5DEE4",
-"=# c #D8E0E5",
-"-# c #F7F8F7",
-";# c #B0DABC",
-"># c #21974D",
-",# c #038A38",
-"'# c #109142",
-")# c #20994F",
-"!# c #2A9F57",
-"~# c #2FA15C",
-"{# c #30A25C",
-"]# c #2CA059",
-"^# c #249B53",
-"/# c #169447",
-"(# c #078B3B",
-"_# c #199346",
-":# c #A4D4B2",
-"<# c #EFF0EF",
-"[# c #CCD3CE",
-"}# c #7C98A9",
-"|# c #86A1B1",
-"1# c #94ABBA",
-"2# c #A4B9C6",
-"3# c #B4C5D0",
-"4# c #C2D0D9",
-"5# c #CFDAE1",
-"6# c #D8E1E8",
-"7# c #ECF1F3",
-"8# c #F2F2F2",
-"9# c #F5F9F6",
-"0# c #75C08C",
-"a# c #078E3B",
-"b# c #129444",
-"c# c #29A057",
-"d# c #31A55D",
-"e# c #32A65E",
-"f# c #32A75E",
-"g# c #31A65D",
-"h# c #32A55E",
-"i# c #31A45D",
-"j# c #2EA25A",
-"k# c #1C994C",
-"l# c #098E3C",
-"m# c #66B881",
-"n# c #ECF1ED",
-"o# c #CBD4CE",
-"p# c #E5E9EB",
-"q# c #FBFBFB",
-"r# c #69BB82",
-"s# c #048F38",
-"t# c #1D9C4D",
-"u# c #32A95D",
-"v# c #33AA5D",
-"w# c #36AB5D",
-"x# c #A3D9B6",
-"y# c #AFDEC1",
-"z# c #AFDEC0",
-"A# c #A0D7B5",
-"B# c #2BA65A",
-"C# c #32A85D",
-"D# c #28A056",
-"E# c #0A913D",
-"F# c #57B375",
-"G# c #F3F4F3",
-"H# c #C7CFC9",
-"I# c #DAE1E6",
-"J# c #F8F8F8",
-"K# c #90CEA2",
-"L# c #029037",
-"M# c #21A04F",
-"N# c #34AA5D",
-"O# c #3AAD5D",
-"P# c #41AE5C",
-"Q# c #47B05C",
-"R# c #4DB15D",
-"S# c #E9F5EB",
-"T# c #E6F4EC",
-"U# c #32A658",
-"V# c #45AF5C",
-"W# c #3FAE5C",
-"X# c #38AC5D",
-"Y# c #2CA459",
-"Z# c #09923D",
-"`# c #7AC391",
-" $ c #EBECEB",
-".$ c #EBEEF0",
-"+$ c #D6EDDB",
-"@$ c #119941",
-"#$ c #1BA04A",
-"$$ c #3CAD5C",
-"%$ c #50B25C",
-"&$ c #56B45C",
-"*$ c #5AB65B",
-"=$ c #5EB85C",
-"-$ c #EBF6EB",
-";$ c #FFFFFF",
-">$ c #3AA957",
-",$ c #59B55B",
-"'$ c #54B35C",
-")$ c #4DB15C",
-"!$ c #43AE5C",
-"~$ c #39AC5D",
-"{$ c #29A556",
-"]$ c #0D963E",
-"^$ c #C6E4CE",
-"/$ c #D9DBD9",
-"($ c #62BC7D",
-"_$ c #0E9B3C",
-":$ c #42AE5B",
-"<$ c #58B55B",
-"[$ c #5FB85B",
-"}$ c #65BB5B",
-"|$ c #69BC5B",
-"1$ c #6DBE5D",
-"2$ c #EDF7EB",
-"3$ c #41AC57",
-"4$ c #68BB5B",
-"5$ c #63BA5B",
-"6$ c #5DB75B",
-"7$ c #4CB15C",
-"8$ c #3FAE5D",
-"9$ c #1BA049",
-"0$ c #4DB36E",
-"a$ c #F2F1F1",
-"b$ c #6E8A99",
-"c$ c #718EA0",
-"d$ c #E2E7EA",
-"e$ c #E2F2E4",
-"f$ c #29A440",
-"g$ c #3BAA4D",
-"h$ c #56B45B",
-"i$ c #67BB5B",
-"j$ c #6DBE5C",
-"k$ c #72BF5F",
-"l$ c #76C061",
-"m$ c #79C264",
-"n$ c #EEF7EC",
-"o$ c #47AE5A",
-"p$ c #74C060",
-"q$ c #70BF5D",
-"r$ c #6BBD5B",
-"s$ c #64BA5B",
-"t$ c #5CB75B",
-"u$ c #52B35C",
-"v$ c #40AD59",
-"w$ c #20A23E",
-"x$ c #D1EAD7",
-"y$ c #CDD5CD",
-"z$ c #A6B2B9",
-"A$ c #E1E5E7",
-"B$ c #7B909D",
-"C$ c #6B8797",
-"D$ c #728E9F",
-"E$ c #7B98A8",
-"F$ c #C2D0DA",
-"G$ c #EFF1F3",
-"H$ c #ADDBB4",
-"I$ c #52B030",
-"J$ c #6BBC54",
-"K$ c #78C163",
-"L$ c #7CC367",
-"M$ c #80C56A",
-"N$ c #83C66C",
-"O$ c #EFF8ED",
-"P$ c #4BB05E",
-"Q$ c #7FC469",
-"R$ c #7BC265",
-"S$ c #76C161",
-"T$ c #60B85B",
-"U$ c #65BA59",
-"V$ c #56B33D",
-"W$ c #93D1A0",
-"X$ c #E2E1E1",
-"Y$ c #EFF1F2",
-"Z$ c #9AA7AD",
-"`$ c #627580",
-" % c #4C6370",
-".% c #435C69",
-"+% c #6E8897",
-"@% c #7D96A5",
-"#% c #89A2B2",
-"$% c #96ADBC",
-"%% c #F8F8F9",
-"&% c #82C786",
-"*% c #73BC32",
-"=% c #93CB50",
-"-% c #78C365",
-";% c #A7D89C",
-">% c #ACD9A2",
-",% c #B0DBA5",
-"'% c #B2DCA7",
-")% c #B1DBA5",
-"!% c #AFDAA1",
-"~% c #F5FAF3",
-"{% c #F0F8F4",
-"]% c #90CE9B",
-"^% c #AFDAA2",
-"/% c #AEDAA4",
-"(% c #ABD8A0",
-"_% c #A5D79C",
-":% c #5EB862",
-"<% c #8ECA51",
-"[% c #79C044",
-"}% c #70C07C",
-"|% c #EDECEC",
-"1% c #8E9DA5",
-"2% c #58707D",
-"3% c #536C79",
-"4% c #627A87",
-"5% c #677E8B",
-"6% c #82959F",
-"7% c #76C172",
-"8% c #82C338",
-"9% c #9BCE4E",
-"0% c #A2D36E",
-"a% c #F8FCF7",
-"b% c #F9FCFB",
-"c% c #5BB66A",
-"d% c #86C64A",
-"e% c #5AB557",
-"f% c #FDFEFE",
-"g% c #8497A1",
-"h% c #647C89",
-"i% c #647B88",
-"j% c #80939D",
-"k% c #72C063",
-"l% c #86C43A",
-"m% c #ABD669",
-"n% c #FAFCF6",
-"o% c #5CB76A",
-"p% c #8BC84C",
-"q% c #57B44C",
-"r% c #F3F3F3",
-"s% c #CFD8DE",
-"t% c #E1E6E8",
-"u% c #889AA5",
-"v% c #778C99",
-"w% c #8C9DA8",
-"x% c #81C771",
-"y% c #85C439",
-"z% c #AAD568",
-"A% c #FAFCF5",
-"B% c #5BB76A",
-"C% c #8AC74B",
-"D% c #66BB55",
-"E% c #638294",
-"F% c #BBC9D1",
-"G% c #CAD3D8",
-"H% c #A1B0B9",
-"I% c #90A2AD",
-"J% c #8EA1AC",
-"K% c #8FA1AC",
-"L% c #99A9B3",
-"M% c #F6F7F8",
-"N% c #97D087",
-"O% c #7FC136",
-"P% c #96CB45",
-"Q% c #B4DA84",
-"R% c #B3DA89",
-"S% c #B4DB8C",
-"T% c #BADE9D",
-"U% c #C1E1AC",
-"V% c #F7FBF5",
-"W% c #F1F9F5",
-"X% c #A0D5A6",
-"Y% c #BBDE9E",
-"Z% c #B4DB8D",
-"`% c #B0D987",
-" & c #6EBB43",
-".& c #99CD4B",
-"+& c #82C447",
-"@& c #8ACA7A",
-"#& c #EFEFEF",
-"$& c #638495",
-"%& c #7F9AA9",
-"&& c #B9C7D0",
-"*& c #E8ECEF",
-"=& c #E8ECEE",
-"-& c #D1D9DE",
-";& c #BBC7CF",
-">& c #ABB9C4",
-",& c #A5B5C0",
-"'& c #A1B2BD",
-")& c #A0B1BC",
-"!& c #A3B3BE",
-"~& c #BFE2B4",
-"{& c #73BC36",
-"]& c #95CB44",
-"^& c #83C124",
-"/& c #82C023",
-"(& c #83C126",
-"_& c #89C434",
-":& c #F1F8E7",
-"<& c #4EAF41",
-"[& c #8CC637",
-"}& c #76BF42",
-"|& c #ACD99F",
-"1& c #E7E6E6",
-"2& c #7593A3",
-"3& c #94ABB8",
-"4& c #B7C7D0",
-"5& c #DBE3E8",
-"6& c #EBEFF1",
-"7& c #E2E8EC",
-"8& c #DBE2E7",
-"9& c #D5DDE3",
-"0& c #CFD9DF",
-"a& c #CDD7DE",
-"b& c #CBD5DD",
-"c& c #C9D4DC",
-"d& c #E9ECEF",
-"e& c #E8F4E3",
-"f& c #73BD49",
-"g& c #85C22A",
-"h& c #83C125",
-"i& c #EFF7E4",
-"j& c #4CAE3D",
-"k& c #7FC028",
-"l& c #6ABA43",
-"m& c #DCEED6",
-"n& c #D7DDD3",
-"o& c #92AAB9",
-"p& c #A9BCC9",
-"q& c #B9C9D3",
-"r& c #C7D4DC",
-"s& c #E1E8ED",
-"t& c #E7EDF0",
-"u& c #9BD084",
-"v& c #7CBE2E",
-"w& c #74BC2D",
-"x& c #8CCA75",
-"y& c #F6F6F6",
-"z& c #F0F2F4",
-"A& c #E2F1DB",
-"B& c #7EC150",
-"C& c #81C025",
-"D& c #82C124",
-"E& c #7DBF25",
-"F& c #74BD48",
-"G& c #D7ECCF",
-"H& c #E4E5E2",
-"I& c #DDE4E9",
-"J& c #BCDFA9",
-"K& c #81C13F",
-"L& c #82C024",
-"M& c #80C024",
-"N& c #78BE3B",
-"O& c #AED89A",
-"P& c #607F91",
-"Q& c #EBEEF1",
-"R& c #AFD993",
-"S& c #86C441",
-"T& c #CBE5A8",
-"U& c #D0E9BB",
-"V& c #C1E2AE",
-"W& c #5DB435",
-"X& c #7FBF24",
-"Y& c #7DC03D",
-"Z& c #A4D387",
-"`& c #F8F9F7",
-" * c #DADDD5",
-".* c #6D8491",
-"+* c #638394",
-"@* c #F2F4F5",
-"#* c #F9FBF7",
-"$* c #BADE9E",
-"%* c #90C950",
-"&* c #82C128",
-"** c #7EBF28",
-"=* c #87C54B",
-"-* c #B1DA94",
-";* c #F4F8F1",
-">* c #E1E4DC",
-",* c #728792",
-"'* c #F5F6F7",
-")* c #FBFCFA",
-"!* c #D7EBC4",
-"~* c #9FD06C",
-"{* c #8BC642",
-"]* c #81C027",
-"^* c #81C024",
-"/* c #7EBF27",
-"(* c #86C440",
-"_* c #99CD66",
-":* c #D1E9BD",
-"<* c #E2E5DE",
-"[* c #758893",
-"}* c #738A97",
-"|* c #738F9E",
-"1* c #7793A4",
-"2* c #FAFAFB",
-"3* c #D2E9BB",
-"4* c #B3DA8B",
-"5* c #98CD5D",
-"6* c #91C94D",
-"7* c #8DC746",
-"8* c #8CC746",
-"9* c #8FC84D",
-"0* c #95CB5B",
-"a* c #B0D886",
-"b* c #CEE7B6",
-"c* c #F4F9F1",
-"d* c #778B96",
-"e* c #798E9A",
-"f* c #7C929F",
-"g* c #8399A7",
-"h* c #89A1B0",
-"i* c #90A8B7",
-"j* c #97ADBC",
-"k* c #DEE5EA",
-"l* c #E5EAEE",
-"m* c #EAEDF0",
-"n* c #E3E6E8",
-"o* c #D5DADC",
-"p* c #F0F1F2",
-"q* c #FAFBF9",
-"r* c #F2F8ED",
-"s* c #E6F3DA",
-"t* c #D8ECC6",
-"u* c #D7ECC5",
-"v* c #E5F2D8",
-"w* c #F2F8EC",
-"x* c #F8FAF7",
-"y* c #F4F4F3",
-"z* c #E2E4DF",
-"A* c #8496A2",
-"B* c #82949E",
-"C* c #81929C",
-"D* c #83949E",
-"E* c #8797A1",
-"F* c #8B9BA4",
-"G* c #8D9CA4",
-"H* c #8D9BA4",
-"I* c #8B99A1",
-"J* c #A4AFB6",
-"K* c #E7EDDF",
-"L* c #EDEDEB",
-"M* c #EFEEEE",
-"N* c #EBEBEB",
-"O* c #E4E9DD",
-" . + @ # $ % & * = - ; ",
-" > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 ) 3 4 5 ",
-" 6 ' 7 8 9 0 a b > ; c d e e f g h i j k l m n o p q r s t ",
-" u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W y X Y Z ",
-" ` ...+.@.#.$.%.&.*.E =.-.;.>.,.'.).!.M N O ~.Q R {.].^./.(._.:.<.[.}. ",
-" |.1.2.3.M L $.%.&.*.F -.-.;.4.,.'.).!.M N O ~.Q R {.].^./.(.5.6.7.8.9. ",
-" 0.a.b.3.M #.K J I c.G ;.;.G H I J d.L M N O P Q R S T ^.e.f.g.h.i.6.j.k. ",
-" l.m.n.o.p.q.r.s.t.&.u.4.4.H ,.v.s.w.x.y.o.z.A.B.C.D.T ^.E.F.g.h.G.H.I. ",
-" J.K.L.M.r.N.L K s.B I ,.,.I v.H.K !.n.O.P.Q.R.S.T.U.V.W.X.F.Y.p.Z.`. + ",
-" .+++@+#+$+%+&+&.*+=+J '.'.J s.K -+q.p.3.O ~.;+>+,+'+S.)+!+&+=.~+{+]+^+ ",
-" .+++/+(+_+:+<+[+}+|+%+%+Z.1+2+H 3+4+I.B t.t.4+H F %+-.5+H 6+M )+>+]+^+ ",
-" .+++7+(+8+9+0+a+b+c+U d+e+O M L ).f+4+M.&+;.%+0.g+Z.H t.K #.h+)+i+V.^+ ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+)+>+]+^+ ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+)+>+]+^+ ",
-" .+++7+(+8+9+0+a+j+k+l+u+n+o+v+q+{.r+P.w+).I |+9.s+;.H t.K #.h+)+i+V.^+ ",
-" ++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+)+>+]+ ",
-" x+y+z+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.K t+h+P.A+ ",
-" B+) C+D+E+F+a+j+k+l+m+n+o+p+q+{.r+P.q.).I 1+9.s+;.H t.G+H+I+J+K+. ",
-" < L+M+N+O+P+P+Q+R+S+T+U+V+W+X+^.{.r+P.N.Y+Z+`+ @.@+@@@#@$@P+%@&@*@=@-@ ",
-" g+;@>@,@'@'@,@'@'@'@'@)@!@~@{@]@^@/@(@_@:@<@[@}@'@'@'@,@'@'@'@,@|@1@g+ ",
-" 2@3@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@4@5@6@7@ ",
-" 8@9@0@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@a@b@n c@d@e@e@f@g@h@i@ ",
-" j@k@l@m@n@o@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@q@r@s@t@u@v@w@x@y@z@A@B@C@ ",
-" .+++D@E@F@l@G@H@I@J@K@L@K@L@L@K@L@L@K@L@L@K@L@M@N@O@P@Q@R@S@T@T@T@U@V@W@X@Y@ ",
-" .+++7+(+Z@`@ #k.F@Z..#+#$+@###$#%#a.&#$#*#=#{ -#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[# ",
-" .+++/+(+8+9+0+}#|#1#2#3#4#5#6#`.%.4+7#>.G 8#9#0#a#b#c#d#e#e#f#g#e#h#i#j#k#l#m#n#o# ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.p#q#r#s#t#g#u#v#w#x#y#z#A#B#u#C#e#D#E#F#G#H# ",
-" .+++7+(+8+9+0+a+j+k+l+u+n+o+v+q+{.r+P.I#J#K#L#M#N#O#P#Q#R#S#2@2@T#U#V#W#X#v#Y#Z#`# $ ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P..$+$@$#$$$Q#%$&$*$=$-$;$2@T#>$,$'$)$!$~${$]$^$/$ ",
-" ++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+%#q#($_$:$%$<$[$}$|$1$2$;$2@T#3$4$5$6$&$7$8$9$0$a$ ",
-" b$c$8+9+0+a+j+k+l+u+n+o+v+q+{.r+d$e$f$g$h$[$i$j$k$l$m$n$2@2@T#o$p$q$r$s$t$u$v$w$x$y$ ",
-" z$A$X B$C$D$E$j+k+l+m+n+o+p+q+{.F$G$H$I$J$s$r$k$K$L$M$N$O$;$2@T#P$Q$R$S$q$|$T$U$V$W$X$ ",
-" . Y$Z$`$ %.%P+Q+R++%@%#%$%o+p+q+{.P %%&%*%=%-%;%>%,%'%)%!%~%;$2@{%]%^%,%/%(%_%:%<%[%}%|% ",
-" g+1%2%3%3%3%3%3%3%3%3%3%3%)@~@4%5%6%q#7%8%9%0%a%2@2@2@2@2@2@2@2@2@2@2@2@2@2@b%c%9%d%e%a$ ",
-" f%g%h%i%h%h%i%h%h%h%i%h%i%h%h%i%h%j%q#k%l%9%m%n%2@;$;$2@;$;$;$2@;$;$2@;$;$2@b%o%9%p%q%r% ",
-" s%t%u%v%v%v%v%v%v%v%v%v%v%v%v%v%v%w%q#x%y%9%z%A%2@2@2@2@2@2@2@2@2@2@2@2@2@2@b%B%9%C%D%8# ",
-" E%F%.#G%H%I%J%K%K%K%J%K%J%K%K%J%K%L%M%N%O%9%P%Q%R%R%S%T%U%V%;$2@W%X%Y%Z%R%R%`% &.&+&@&#& ",
-" .+$&%&&&*&=&-&;&>&,&'&)&)&)&)&)&)&!&.$~&{&]&^&^&/&^&^&(&_&:&;$2@T#<&(&^&^&/&^&^&[&}&|&1& ",
-" .+++/+(+2&3&4&5&G ;.6&7&8&9&0&a&b&c&d&e&f&g&^&^&/&^&^&/&h&i&;$2@T#j&/&^&^&/&^&^&k&l&m&n& ",
-" .+++7+(+8+9+0+a+j+o&p&q&r&M w.s&t&C l@0.u&v&/&/&/&/&/&/&h&i&2@2@T#j&/&/&/&/&/&/&w&x&y& ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.z&A&B&C&^&/&^&^&/&h&i&;$2@T#j&/&^&^&/&D&E&F&G&H& ",
-" .+++/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.I&q#J&K&L&/&^&^&/&h&i&;$2@T#j&/&^&^&/&M&N&O&G# ",
-" P&++7+(+8+9+0+a+j+k+l+u+n+o+v+q+{.r+P.w+Q&0.R&S&L&/&/&/&^&T&U&U&V&W&/&/&/&X&Y&Z&`& * ",
-" .*+*/+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).@*#*$*%*&*L&/&^&^&^&/&^&^&/&L&**=*-*;*>* ",
-" ,*S+(+8+9+0+a+j+k+l+m+n+o+p+q+{.r+P.q.).I '*)*!*~*{*]*L&^&^&/&D&^*/*(*_*:*`&<* ",
-" [*}*|*1*a+j+k+l+u+n+o+v+q+{.r+P.w+).I |+J#2*V%3*4*5*6*7*8*9*0*a*b*c*r% ",
-" d*e*f*g*h*i*j*6.(.^.{.r+P.n.k*l*m*v n*o*p*q*r*s*t*u*v*w*x*y*z* ",
-" A*B*C*D*E*F*G*G*H*I*J* K*L*#&M*N*O* "};
+++ /dev/null
-/* XPM */
-static const char * folder_down_xpm[] = {
-"48 48 649 2",
-" c None",
-". c #C2AA68",
-"+ c #BBA260",
-"@ c #B79E63",
-"# c #E9DEA7",
-"$ c #BCA05D",
-"% c #BB9F5C",
-"& c #BFA35C",
-"* c #C0A45B",
-"= c #C2A65A",
-"- c #C4A859",
-"; c #C4A958",
-"> c #C3A857",
-", c #C3A958",
-"' c #CDB977",
-") c #F1E8B1",
-"! c #FFFAC3",
-"~ c #CFB266",
-"{ c #D1B465",
-"] c #CCAE63",
-"^ c #D0B263",
-"/ c #D1B462",
-"( c #D1B460",
-"_ c #D0B35E",
-": c #CFB25D",
-"< c #CCB05C",
-"[ c #CBAF5B",
-"} c #CAAE5A",
-"| c #C8AC59",
-"1 c #C7AB58",
-"2 c #C4A959",
-"3 c #D0BB78",
-"4 c #EBE0A6",
-"5 c #FDF8C1",
-"6 c #FEF9C2",
-"7 c #D9BC72",
-"8 c #CFB36D",
-"9 c #D9BD6F",
-"0 c #E4C772",
-"a c #EECF73",
-"b c #F3D473",
-"c c #F1D272",
-"d c #EECF6F",
-"e c #E9CB6C",
-"f c #E5C66A",
-"g c #E0C167",
-"h c #DDBE65",
-"i c #D9BB63",
-"j c #D4B761",
-"k c #CDB05C",
-"l c #C8AD5F",
-"m c #D6C280",
-"n c #F1E8AF",
-"o c #FFF9C0",
-"p c #FFFAC0",
-"q c #FEF9C0",
-"r c #C6AB6C",
-"s c #F2D781",
-"t c #F9DD82",
-"u c #FADD81",
-"v c #FADC7E",
-"w c #FADC7B",
-"x c #F9DB79",
-"y c #F9DA77",
-"z c #F5D673",
-"A c #E5C76A",
-"B c #DDBF65",
-"C c #CCAF5C",
-"D c #CBB163",
-"E c #DBC989",
-"F c #F4EBB1",
-"G c #FEF8BE",
-"H c #FFF9BF",
-"I c #FEF9BF",
-"J c #E1C77B",
-"K c #FAE086",
-"L c #FADE83",
-"M c #F9DB7B",
-"N c #F6D674",
-"O c #EDCE6F",
-"P c #E1C267",
-"Q c #CBAF5D",
-"R c #D7C482",
-"S c #F6EDB2",
-"T c #FEF8BD",
-"U c #E8CE7E",
-"V c #FBE086",
-"W c #F2D372",
-"X c #EACB6C",
-"Y c #D5B761",
-"Z c #CAB273",
-"` c #FDF5BA",
-" . c #FEF8BC",
-".. c #FFF8BC",
-"+. c #EACF7F",
-"@. c #D0BC80",
-"#. c #FFF8BB",
-"$. c #FEF7BA",
-"%. c #D1BD82",
-"&. c #FEF7B9",
-"*. c #F9DA78",
-"=. c #D5B861",
-"-. c #D1BD81",
-";. c #FEF5B6",
-">. c #D1BD80",
-",. c #FEF4B3",
-"'. c #FDF4B3",
-"). c #D1BC7F",
-"!. c #FDF3B1",
-"~. c #EACF80",
-"{. c #FBE087",
-"]. c #FADF84",
-"^. c #FBDE82",
-"/. c #FADD7F",
-"(. c #FADC7C",
-"_. c #F9DB7A",
-":. c #FADB78",
-"<. c #F7D775",
-"[. c #F3D472",
-"}. c #EFD070",
-"|. c #EBCC6D",
-"1. c #E6C86B",
-"2. c #E2C368",
-"3. c #DEC066",
-"4. c #DABC64",
-"5. c #D6B962",
-"6. c #D1B45F",
-"7. c #D1BC7E",
-"8. c #FEF3AF",
-"9. c #FDF2AF",
-"0. c #D1BC7D",
-"a. c #FEF2AC",
-"b. c #FDF1AB",
-"c. c #FAE087",
-"d. c #FADD82",
-"e. c #D1BB7C",
-"f. c #FDF0A9",
-"g. c #D0BB7B",
-"h. c #FDEFA6",
-"i. c #FCEFA6",
-"j. c #E6C96B",
-"k. c #E2C468",
-"l. c #D2B55F",
-"m. c #D0BA7A",
-"n. c #FDEEA4",
-"o. c #FCEEA4",
-"p. c #F7D875",
-"q. c #E7C96B",
-"r. c #D7B962",
-"s. c #D0BA79",
-"t. c #FDEEA2",
-"u. c #FCEDA2",
-"v. c #ECCD6D",
-"w. c #DBBC64",
-"x. c #D0B978",
-"y. c #FCEC9F",
-"z. c #E3C468",
-"A. c #D0B977",
-"B. c #FDEB9D",
-"C. c #FCEB9D",
-"D. c #F8D876",
-"E. c #D0B876",
-"F. c #FCEA9A",
-"G. c #D0B875",
-"H. c #FBE998",
-"I. c #FAE899",
-"J. c #F0E2A5",
-"K. c #E7DEB6",
-"L. c #E3DEC7",
-"M. c #E2DFD4",
-"N. c #E0DED8",
-"O. c #E1DED6",
-"P. c #E1DDCE",
-"Q. c #E3DCBF",
-"R. c #E9DEAD",
-"S. c #CFB776",
-"T. c #EDE0AC",
-"U. c #E4E0D0",
-"V. c #EDEDEB",
-"W. c #E2EDE5",
-"X. c #C3E1CB",
-"Y. c #97CCA7",
-"Z. c #8BC79E",
-"`. c #8EC8A0",
-" + c #A7D4B4",
-".+ c #D4E8DA",
-"++ c #E8EDE9",
-"@+ c #E1E0E0",
-"#+ c #C9CEC8",
-"$+ c #FADF85",
-"%+ c #FBDE83",
-"&+ c #FADC7D",
-"*+ c #F8D976",
-"=+ c #F4D573",
-"-+ c #F0D170",
-";+ c #ECCD6E",
-">+ c #E7CA6B",
-",+ c #DFC066",
-"'+ c #DBBD64",
-")+ c #D2B86D",
-"!+ c #D6CFBF",
-"~+ c #F1F1F0",
-"{+ c #C8E3CF",
-"]+ c #57AF76",
-"^+ c #169045",
-"/+ c #05883A",
-"(+ c #0D8C41",
-"_+ c #118E44",
-":+ c #0B8B3F",
-"<+ c #07893B",
-"[+ c #2E9B57",
-"}+ c #85C59A",
-"|+ c #E6EFE8",
-"1+ c #E2E1E1",
-"2+ c #FAE088",
-"3+ c #FADD80",
-"4+ c #F0D171",
-"5+ c #EDCE6E",
-"6+ c #E8CA6C",
-"7+ c #E4C569",
-"8+ c #DFC067",
-"9+ c #DCBD65",
-"0+ c #D7C080",
-"a+ c #E4E1DA",
-"b+ c #E0EFE4",
-"c+ c #58B176",
-"d+ c #058A39",
-"e+ c #159347",
-"f+ c #289D56",
-"g+ c #31A25D",
-"h+ c #30A15D",
-"i+ c #249A53",
-"j+ c #108F42",
-"k+ c #179245",
-"l+ c #9ACFAB",
-"m+ c #EEEEEE",
-"n+ c #C6CFC9",
-"o+ c #FBE088",
-"p+ c #FADB79",
-"q+ c #DAC37F",
-"r+ c #E8E6DE",
-"s+ c #CEE7D4",
-"t+ c #22994D",
-"u+ c #0F9241",
-"v+ c #2AA058",
-"w+ c #31A45D",
-"x+ c #32A55E",
-"y+ c #32A65E",
-"z+ c #35A760",
-"A+ c #34A860",
-"B+ c #34A760",
-"C+ c #33A65F",
-"D+ c #31A55D",
-"E+ c #32A45E",
-"F+ c #31A35D",
-"G+ c #259C53",
-"H+ c #0B8F3E",
-"I+ c #6BBA86",
-"J+ c #E8EEE9",
-"K+ c #CECFCE",
-"L+ c #E9CF80",
-"M+ c #DEC16F",
-"N+ c #E6E2D7",
-"O+ c #D2E9D7",
-"P+ c #1C9848",
-"Q+ c #169748",
-"R+ c #30A55C",
-"S+ c #31A75D",
-"T+ c #32A95D",
-"U+ c #34AA5D",
-"V+ c #4DB570",
-"W+ c #D2ECDB",
-"X+ c #D1ECDB",
-"Y+ c #96D2AF",
-"Z+ c #24A354",
-"`+ c #31A85D",
-" @ c #2EA25A",
-".@ c #0D9240",
-"+@ c #67BA82",
-"@@ c #EFF0EF",
-"#@ c #BECAC2",
-"$@ c #EDD382",
-"%@ c #F8D977",
-"&@ c #E4C66A",
-"*@ c #E0D5B4",
-"=@ c #EAF4EC",
-"-@ c #2FA257",
-";@ c #149846",
-">@ c #32A85D",
-",@ c #35AB5D",
-"'@ c #3BAD5D",
-")@ c #42AF5C",
-"!@ c #48B05C",
-"~@ c #67BD74",
-"{@ c #FEFEFE",
-"]@ c #B4DEC6",
-"^@ c #2DA451",
-"/@ c #45AF5C",
-"(@ c #3EAD5C",
-"_@ c #37AC5D",
-":@ c #2EA55B",
-"<@ c #0D943F",
-"[@ c #8BCB9F",
-"}@ c #E8E7E7",
-"|@ c #D3B976",
-"1@ c #F9DF89",
-"2@ c #F9D977",
-"3@ c #E2CA82",
-"4@ c #F1F0EE",
-"5@ c #79C490",
-"6@ c #0B963E",
-"7@ c #31A95B",
-"8@ c #3EAD5D",
-"9@ c #50B25C",
-"0@ c #57B45C",
-"a@ c #5BB65B",
-"b@ c #76C273",
-"c@ c #FFFFFF",
-"d@ c #39A850",
-"e@ c #58B55B",
-"f@ c #53B35C",
-"g@ c #4CB15C",
-"h@ c #42AE5C",
-"i@ c #29A557",
-"j@ c #0F9640",
-"k@ c #DAECDE",
-"l@ c #D3D5D3",
-"m@ c #BDA36A",
-"n@ c #F1D889",
-"o@ c #FAE28D",
-"p@ c #FBE18A",
-"q@ c #F5D573",
-"r@ c #F1D271",
-"s@ c #E9CA6C",
-"t@ c #E4D9B8",
-"u@ c #E7F3E9",
-"v@ c #0C983C",
-"w@ c #2BA752",
-"x@ c #52B35C",
-"y@ c #59B55B",
-"z@ c #60B85B",
-"A@ c #66BB5B",
-"B@ c #69BC5B",
-"C@ c #82C774",
-"D@ c #42AC50",
-"E@ c #67BB5B",
-"F@ c #62B95B",
-"G@ c #5CB75B",
-"H@ c #55B45C",
-"I@ c #4AB15C",
-"J@ c #3DAD5C",
-"K@ c #1A9F49",
-"L@ c #69BE84",
-"M@ c #ECEBEB",
-"N@ c #D7BE7B",
-"O@ c #FAE38F",
-"P@ c #FAE18A",
-"Q@ c #E7CB75",
-"R@ c #EFECE4",
-"S@ c #8DCF9F",
-"T@ c #2AA43C",
-"U@ c #4BB05B",
-"V@ c #57B55B",
-"W@ c #61B85B",
-"X@ c #68BC5B",
-"Y@ c #6EBE5C",
-"Z@ c #72C05F",
-"`@ c #76C161",
-" # c #8CCB7A",
-".# c #4AAF54",
-"+# c #74C060",
-"@# c #70BE5D",
-"## c #6ABD5B",
-"$# c #64BA5B",
-"%# c #51B25C",
-"&# c #42AE59",
-"*# c #27A442",
-"=# c #E3EFE6",
-"-# c #C6D2C5",
-";# c #DFC680",
-"># c #FBE38F",
-",# c #E6D08B",
-"'# c #F5F6F4",
-")# c #52B567",
-"!# c #79C040",
-"~# c #61B85A",
-"{# c #6CBE5C",
-"]# c #75C061",
-"^# c #7DC46D",
-"/# c #78C166",
-"(# c #80C56A",
-"_# c #94CE80",
-":# c #50B159",
-"<# c #7EC469",
-"[# c #7CC367",
-"}# c #7AC36A",
-"|# c #6ABD5C",
-"1# c #68BB5B",
-"2# c #5EB75B",
-"3# c #71BF56",
-"4# c #48AE3B",
-"5# c #B1DDBA",
-"6# c #DCDBDB",
-"7# c #E0C881",
-"8# c #E7D5A1",
-"9# c #EBF4EB",
-"0# c #45AC43",
-"a# c #92CA46",
-"b# c #87C753",
-"c# c #6FBE5C",
-"d# c #76C162",
-"e# c #B5DDA9",
-"f# c #E0F1E5",
-"g# c #51B369",
-"h# c #73BE5A",
-"i# c #8AC870",
-"j# c #48AD4D",
-"k# c #77BF5B",
-"l# c #BDE1B1",
-"m# c #D8EEDE",
-"n# c #4DB165",
-"o# c #70BF5E",
-"p# c #71BF59",
-"q# c #96CC50",
-"r# c #6ABA42",
-"s# c #8DCE98",
-"t# c #E0C781",
-"u# c #E9DBB1",
-"v# c #E4F2E4",
-"w# c #48AC33",
-"x# c #98CD4C",
-"y# c #9BCE4F",
-"z# c #87C75A",
-"A# c #BADFAF",
-"B# c #FCFEFC",
-"C# c #E0F1E7",
-"D# c #55B469",
-"E# c #8DC973",
-"F# c #50B052",
-"G# c #B9DEA8",
-"H# c #DEF1E6",
-"I# c #4EB265",
-"J# c #8DC951",
-"K# c #9BCE4E",
-"L# c #7BC147",
-"M# c #77C377",
-"N# c #EEEDED",
-"O# c #DFC780",
-"P# c #FAE085",
-"Q# c #EADDB6",
-"R# c #E5F2E4",
-"S# c #50AF30",
-"T# c #9ACE4E",
-"U# c #9CCF4F",
-"V# c #ADD76E",
-"W# c #FAFDF8",
-"X# c #DDF0E5",
-"Y# c #72C185",
-"Z# c #B8E0C9",
-"`# c #9AD2A4",
-" $ c #AEDCC1",
-".$ c #65B94B",
-"+$ c #81C448",
-"@$ c #74C16D",
-"#$ c #EFEFEF",
-"$$ c #DEC680",
-"%$ c #FAE390",
-"&$ c #FAE28E",
-"*$ c #FAE18B",
-"=$ c #F9DB7C",
-"-$ c #EADCB1",
-";$ c #E7F3E5",
-">$ c #56B233",
-",$ c #98CD4D",
-"'$ c #94CA41",
-")$ c #BADD84",
-"!$ c #FCFDFA",
-"~$ c #EBF6F0",
-"{$ c #F1F9F4",
-"]$ c #FAFDFB",
-"^$ c #D9EFE3",
-"/$ c #52B14D",
-"($ c #92CA47",
-"_$ c #80C346",
-":$ c #86C97B",
-"<$ c #DEC580",
-"[$ c #FBE390",
-"}$ c #FBE18B",
-"|$ c #FBE189",
-"1$ c #FBDF84",
-"2$ c #FADD7E",
-"3$ c #FADB7A",
-"4$ c #E9D8A1",
-"5$ c #EFF6ED",
-"6$ c #66B948",
-"7$ c #93CB47",
-"8$ c #98CC48",
-"9$ c #84C227",
-"0$ c #83C124",
-"a$ c #B6DB7E",
-"b$ c #FBFDF9",
-"c$ c #D2ECDC",
-"d$ c #51B14B",
-"e$ c #81C024",
-"f$ c #88C42D",
-"g$ c #9ACE4D",
-"h$ c #78C043",
-"i$ c #A6D79A",
-"j$ c #EBEAEA",
-"k$ c #DDC47F",
-"l$ c #E9D28B",
-"m$ c #F8F8F6",
-"n$ c #84C770",
-"o$ c #88C640",
-"p$ c #8BC532",
-"q$ c #82C023",
-"r$ c #84C126",
-"s$ c #D2EBDC",
-"t$ c #56B34D",
-"u$ c #7EBF24",
-"v$ c #8FC83C",
-"w$ c #6CBB40",
-"x$ c #CBE7C3",
-"y$ c #DCC47F",
-"z$ c #E9CD74",
-"A$ c #F4F1E7",
-"B$ c #B9DEAC",
-"C$ c #73BD39",
-"D$ c #83C125",
-"E$ c #B9DC83",
-"F$ c #D9EFE2",
-"G$ c #7FC02A",
-"H$ c #71BD52",
-"I$ c #EEF5EC",
-"J$ c #D2DACD",
-"K$ c #DCC37E",
-"L$ c #EACC6D",
-"M$ c #EBDEB8",
-"N$ c #F4F9F2",
-"O$ c #73BD4F",
-"P$ c #7EBF26",
-"Q$ c #D3ECDD",
-"R$ c #50B04A",
-"S$ c #72BB33",
-"T$ c #A7D697",
-"U$ c #F2F1F1",
-"V$ c #DBC27E",
-"W$ c #E6CD80",
-"X$ c #F7F5F1",
-"Y$ c #BADEAA",
-"Z$ c #79BE3B",
-"`$ c #82C024",
-" % c #BFDF8D",
-".% c #FDFEFD",
-"+% c #DCF0E4",
-"@% c #56B354",
-"#% c #7DBF24",
-"$% c #7BBE29",
-"%% c #7AC054",
-"&% c #EEF6EA",
-"*% c #DDE1D9",
-"=% c #DAC27D",
-"-% c #FBE391",
-";% c #F6D774",
-">% c #EADCB5",
-",% c #F6FAF5",
-"'% c #99CE7A",
-")% c #7EBF32",
-"!% c #C2E194",
-"~% c #E4F3EA",
-"{% c #52B253",
-"]% c #7DBF25",
-"^% c #7FBF25",
-"/% c #7CC047",
-"(% c #C8E5BA",
-"_% c #F1F1F1",
-":% c #D7BF7B",
-"<% c #E6C76A",
-"[% c #E1C36C",
-"}% c #EFEEE2",
-"|% c #EDF6E8",
-"1% c #99CE74",
-"2% c #81C132",
-"3% c #B6DA7F",
-"4% c #66B94F",
-"5% c #81C249",
-"6% c #BBDEA6",
-"7% c #F9F9F9",
-"8% c #CBB273",
-"9% c #F3F3F2",
-"0% c #A6D47E",
-"a% c #88C540",
-"b% c #81C026",
-"c% c #82C124",
-"d% c #80C02D",
-"e% c #8FC857",
-"f% c #C4E3AF",
-"g% c #F7F9F6",
-"h% c #DDE2D7",
-"i% c #E3CA81",
-"j% c #F8E08D",
-"k% c #F6D87A",
-"l% c #F8D979",
-"m% c #F7FAF4",
-"n% c #C5E3AA",
-"o% c #96CC5E",
-"p% c #86C439",
-"q% c #80C025",
-"r% c #80C024",
-"s% c #80C02B",
-"t% c #8BC749",
-"u% c #A5D379",
-"v% c #DDEED0",
-"w% c #DEE2D8",
-"x% c #D5BB76",
-"y% c #F9DF88",
-"z% c #F8DD85",
-"A% c #F5DA81",
-"B% c #E8EBE3",
-"C% c #FAFAFA",
-"D% c #EFF7E9",
-"E% c #C8E4AC",
-"F% c #ACD77F",
-"G% c #96CB58",
-"H% c #90C94C",
-"I% c #8DC747",
-"J% c #8EC848",
-"K% c #92CA50",
-"L% c #9CCF65",
-"M% c #B6DC91",
-"N% c #D9ECC7",
-"O% c #FAFBF9",
-"P% c #E4DCCD",
-"Q% c #FAF8F2",
-"R% c #F8FAF5",
-"S% c #F2F8EC",
-"T% c #E1F0D3",
-"U% c #D8ECC5",
-"V% c #DAEDC9",
-"W% c #EBF5E1",
-"X% c #F3F8EE",
-"Y% c #FAFAF9",
-"Z% c #F2F2F1",
-"`% c #E0E6D9",
-" & c #C5AC71",
-".& c #F3D57F",
-"+& c #E9EBE1",
-"@& c #EAECE8",
-"#& c #E3EADB",
-" . + @ # ",
-" $ % & * = - ; > , ' ) ! ",
-" ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 6 ",
-" 7 8 9 0 a b c d e f g h i j _ : k [ } l m n o p q p p ",
-" r s t u v w x y z c d e A g B i j _ : C D E F G H H H I H H ",
-" J K L u v M x y N c O e A P B i j _ Q R S T T T T T T T T T ",
-" U V L u v w x y N W d X A P B i Y _ Z ` ..... ....... ..... ",
-" +.V L u v w x y N W d X A P B i Y _ @.#.$.#.#.$.#.#.#.$.#.#. ",
-" +.K L u v M x y N W d X A P B i Y _ %.&.&.&.&.&.&.&.&.&.&.&. ",
-" +.V L u v w x *.N W d X A P B i =._ -.;.;.;.;.;.;.;.;.;.;.;. ",
-" +.V L u v w x *.N W d X A P B i =._ >.,.'.,.,.'.,.,.,.'.,.,. ",
-" +.K L u v M x y N W d X A P B i =._ ).!.!.!.!.!.!.!.!.!.!.!. ",
-" ~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.8.8.9.8.8.8.9.8.8. ",
-" ~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.0.a.b.a.a.b.a.a.a.b.a.a. ",
-" +.c.].d./.(._.*.<.[.}.|.1.2.3.4.5.6.e.f.f.f.f.f.f.f.f.f.f.f. ",
-" ~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.g.h.i.h.h.i.h.h.h.i.h.h. ",
-" ~.{.].^./.(._.:.<.[.}.|.j.k.3.4.5.l.m.n.o.n.n.o.n.n.n.o.n.n. ",
-" ~.{.].^./.(._.:.p.[.}.|.q.k.3.4.r.l.s.t.u.t.t.u.t.t.t.u.t.t. ",
-" +.c.].d./.(._.*.p.[.}.v.q.2.3.w.r.l.x.y.y.y.y.y.y.y.y.y.y.y. ",
-" ~.{.].^./.(._.:.p.[.}.v.q.z.3.w.r.l.A.B.C.B.B.C.B.B.B.C.B.B. ",
-" ~.{.].^./.(._.:.D.[.}.v.q.z.3.w.r.l.E.F.F.F.F.F.F.F.F.F.F.F. ",
-" +.c.].d./.(._.*.D.[.}.v.q.z.3.w.r.l.G.H.I.J.K.L.M.N.O.P.Q.R. ",
-" ~.{.].^./.(._.:.D.[.}.v.q.z.3.w.r.l.S.T.U.V.W.X.Y.Z.`. +.+++@+#+ ",
-" ~.{.$+%+/.&+_.:.*+=+-+;+>+z.,+'+r.)+!+~+{+]+^+/+(+_+_+:+<+[+}+|+1+ ",
-" ~.2+$+L 3+&+M x *+=+4+5+6+7+8+9+0+a+b+c+d+e+f+g+g+g+g+g+h+i+j+k+l+m+n+ ",
-" ~.o+$+%+3+&+M p+*+=+4+5+6+7+8+q+r+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+J+K+ ",
-" L+o+$+%+3+&+M p+*+=+4+5+6+7+M+N+O+P+Q+R+S+T+U+V+W+X+X+Y+Z+T+`+y+ @.@+@@@#@ ",
-" $@2+$+L 3+&+M x %@=+4+5+6+&@*@=@-@;@>@,@'@)@!@~@{@{@{@]@^@/@(@_@T+:@<@[@}@ ",
-" |@1@o+$+%+3+&+M p+2@=+4+5+6+3@4@5@6@7@8@!@9@0@a@b@c@c@c@]@d@e@f@g@h@_@i@j@k@l@ ",
-" m@n@o@p@o+$+%+3+&+M p+y q@r@5+s@t@u@v@w@/@x@y@z@A@B@C@c@c@c@]@D@E@F@G@H@I@J@K@L@M@ ",
-" N@O@o@P@2+$+L 3+&+M x y q@r@5+Q@R@S@T@U@V@W@X@Y@Z@`@ #{@{@{@]@.#+#@###$#a@%#&#*#=#-# ",
-" ;#>#o@p@o+$+%+u &+M p+y q@r@5+,#'#)#!#~#$#{#]#^#/#(#_#c@c@c@]@:#<#[#}#|#1#2#3#4#5#6# ",
-" 7#>#o@p@o+$+%+u &+M p+y q@r@5+8#9#0#a#b#c#d#e#f#g#h#i#c@c@c@]@j#k#l#m#n#o#p#q#r#s#}@ ",
-" t#O@o@P@2+$+L 3+&+M x y q@r@5+u#v#w#x#y#z#A#B#{@C#D#E#{@{@{@]@F#G#{@{@H#I#J#K#L#M#N# ",
-" O#>#o@p@o+P#%+u v M p+y q@r@5+Q#R#S#T#U#V#W#c@{@c@X#Y#c@c@c@Z#`#B#{@c@c@ $.$U#+$@$#$ ",
-" $$%$&$*$2+K ].u v =$x *.N W d -$;$>$,$K#'$)$!${@{@{@~${@{@{@{$]${@{@{@^$/$($K#_$:$m+ ",
-" <$[$&$}$|$K 1$u 2$=$3$*.N W d 4$5$6$7$8$9$0$a$b$c@c@{@c@c@c@{@c@c@{@c$d$e$f$g$h$i$j$ ",
-" k$[$&$}$|$K 1$u 2$=$3$*.N W d l$m$n$o$p$q$0$r$a$!$c@{@c@c@c@{@c@c@s$t$u$q$0$v$w$x$@+ ",
-" y$[$&$}$|$K 1$u 2$=$3$*.N W d z$A$B$C$D$q$0$0$0$E$!${@c@c@c@{@c@F$d$u$0$q$0$G$H$I$J$ ",
-" K$%$&$*$2+K ].u v =$x *.N W d L$M$N$O$P$q$q$q$q$0$a$!${@{@{@{@Q$R$e$q$q$q$e$S$T$U$ ",
-" V$[$&$}$|$K 1$d.2$=$3$*.N W d L$W$X$Y$Z$`$0$0$q$0$r$ %.%c@c@+%@%#%q$0$0$q$$%%%&%*% ",
-" =%-%&$}$|$K 1$d.2$=$3$*.;%W d L$1.>%,%'%)%0$0$q$0$0$q$!%.%~%{%]%0$q$0$0$^%/%(%_% ",
-" :%%$&$*$2+K ].d.v =$x *.;%W d L$<%[%}%|%1%2%`$q$q$q$q$q$3%4%e$q$q$q$q$^%5%6%7% ",
-" 8%%$&$}$|$K 1$d.2$=$3$*.N c d 9%|%0%a%b%c%0$q$0$0$0$q$0$0$e$d%e%f%g%h% ",
-" i%j%}$|$K 1$d.2$k%l% U$m%n%o%p%q%`$0$0$0$q$r%s%t%u%v%7%w% ",
-" x%y%z%A% B%C%D%E%F%G%H%I%J%K%L%M%N%O%_% ",
-" P%Q%R%S%T%U%V%W%X%Y%Z%`% ",
-" &.& +&N##$m+@&#& "};
+++ /dev/null
-/* XPM */
-static const char * help_xpm[] = {
-"48 48 665 2",
-" c None",
-". c #D9D9DB",
-"+ c #D5D4D5",
-"@ c #D4D3D3",
-"# c #D6D5D5",
-"$ c #D5D4D4",
-"% c #D3D2D2",
-"& c #D3D2D3",
-"* c #D6D7D9",
-"= c #D5D5D6",
-"- c #DBDBDB",
-"; c #E5E4E4",
-"> c #ECECEC",
-", c #F2F2F2",
-"' c #F5F5F5",
-") c #F7F7F7",
-"! c #F8F7F7",
-"~ c #F6F6F6",
-"{ c #F5F4F4",
-"] c #F0F0F0",
-"^ c #EAE9E9",
-"/ c #E1E1E1",
-"( c #D7D7D7",
-"_ c #D0D0D1",
-": c #D9D9D9",
-"< c #E7E7E7",
-"[ c #F3F3F3",
-"} c #FAFAFA",
-"| c #FDFDFD",
-"1 c #F2F5F8",
-"2 c #DDE4EF",
-"3 c #FCFCFC",
-"4 c #F8F8F8",
-"5 c #EFEFEF",
-"6 c #E2E1E1",
-"7 c #DADADA",
-"8 c #F9F9F9",
-"9 c #FEFEFE",
-"0 c #FCFDFD",
-"a c #D7DDE9",
-"b c #9FA9C9",
-"c c #6B76AA",
-"d c #3A4B8F",
-"e c #222F7E",
-"f c #202A7A",
-"g c #3A4A8F",
-"h c #D7DDEA",
-"i c #E6E5E5",
-"j c #D6D6D7",
-"k c #E8E7E7",
-"l c #F2F4F8",
-"m c #ABB4D0",
-"n c #52619C",
-"o c #283581",
-"p c #1F2C7B",
-"q c #202C7B",
-"r c #202E7C",
-"s c #22307D",
-"t c #23317E",
-"u c #24327E",
-"v c #24327F",
-"w c #202D7C",
-"x c #E0DFDF",
-"y c #CECDCF",
-"z c #DCDCDD",
-"A c #F2F1F1",
-"B c #ADB7D2",
-"C c #425293",
-"D c #1F2D7B",
-"E c #1E2E7C",
-"F c #1F2F7D",
-"G c #2B3B85",
-"H c #37468B",
-"I c #3F4F91",
-"J c #445494",
-"K c #475696",
-"L c #485897",
-"M c #3F4E91",
-"N c #2B3B84",
-"O c #202F7D",
-"P c #1F2E7C",
-"Q c #D3D3D3",
-"R c #E1E0E0",
-"S c #DFE4EE",
-"T c #52649F",
-"U c #1E2F7D",
-"V c #1D2F7D",
-"W c #243682",
-"X c #35488D",
-"Y c #445696",
-"Z c #485A99",
-"` c #475B99",
-" . c #475A99",
-".. c #485A98",
-"+. c #455696",
-"@. c #36478D",
-"#. c #53659F",
-"$. c #F1F1F1",
-"%. c #D7D6D6",
-"&. c #E4E3E3",
-"*. c #B5C0D8",
-"=. c #32468C",
-"-. c #1C307E",
-";. c #203581",
-">. c #33488D",
-",. c #445897",
-"'. c #465B99",
-"). c #465C9A",
-"!. c #455D9A",
-"~. c #455C9A",
-"{. c #465C99",
-"]. c #34488D",
-"^. c #213581",
-"/. c #32458B",
-"(. c #B5BFD7",
-"_. c #F3F2F2",
-":. c #D9D8D9",
-"<. c #E2E2E2",
-"[. c #A4B1CF",
-"}. c #233984",
-"|. c #1B317F",
-"1. c #273D86",
-"2. c #405595",
-"3. c #445E9B",
-"4. c #435F9C",
-"5. c #425F9C",
-"6. c #41609C",
-"7. c #435E9B",
-"8. c #405495",
-"9. c #1C317E",
-"0. c #233883",
-"a. c #DFDFDF",
-"b. c #A3B1CF",
-"c. c #1B3280",
-"d. c #1B3480",
-"e. c #2C468C",
-"f. c #445C99",
-"g. c #435F9B",
-"h. c #415F9C",
-"i. c #40609C",
-"j. c #3F619D",
-"k. c #4D6DA4",
-"l. c #708AB6",
-"m. c #92A5C7",
-"n. c #A4B2CF",
-"o. c #B0BDD6",
-"p. c #B8C5DA",
-"q. c #AEB9D4",
-"r. c #9EA9CA",
-"s. c #7B87B5",
-"t. c #586CA4",
-"u. c #3D5897",
-"v. c #40609D",
-"w. c #445D9A",
-"x. c #445B99",
-"y. c #2D458B",
-"z. c #1B3380",
-"A. c #1B327F",
-"B. c #D3D3D4",
-"C. c #DADADB",
-"D. c #F4F4F4",
-"E. c #B4C1D8",
-"F. c #213B85",
-"G. c #193581",
-"H. c #2E498D",
-"I. c #425D9A",
-"J. c #3E629D",
-"K. c #3D639E",
-"L. c #5778AB",
-"M. c #B1C0D8",
-"N. c #EBEFF5",
-"O. c #FFFFFF",
-"P. c #FEFEFF",
-"Q. c #F4F3F8",
-"R. c #CDCCDF",
-"S. c #6D70A6",
-"T. c #3D5394",
-"U. c #3E609C",
-"V. c #3F609D",
-"W. c #1A3481",
-"X. c #213A85",
-"Y. c #B5C1D8",
-"Z. c #ECEBEB",
-"`. c #DFE5EF",
-" + c #2E4A8F",
-".+ c #173581",
-"++ c #2A488D",
-"@+ c #405E9B",
-"#+ c #3E619D",
-"$+ c #3D629E",
-"%+ c #3B639E",
-"&+ c #39639F",
-"*+ c #7F9BC1",
-"=+ c #EFF2F7",
-"-+ c #FCFCFD",
-";+ c #B7B1CF",
-">+ c #3E438B",
-",+ c #3B609C",
-"'+ c #3D629D",
-")+ c #415E9B",
-"!+ c #183481",
-"~+ c #2F498E",
-"{+ c #DFE5EE",
-"]+ c #FBFBFB",
-"^+ c #4E6AA3",
-"/+ c #163682",
-"(+ c #20438A",
-"_+ c #3E5F9C",
-":+ c #3C639E",
-"<+ c #3A639F",
-"[+ c #3764A0",
-"}+ c #3565A0",
-"|+ c #7B9BC1",
-"1+ c #F9FBFC",
-"2+ c #D6D2E3",
-"3+ c #3A3A85",
-"4+ c #375F9C",
-"5+ c #3B639F",
-"6+ c #3F5F9C",
-"7+ c #214289",
-"8+ c #173681",
-"9+ c #4E69A2",
-"0+ c #A9BAD4",
-"a+ c #143883",
-"b+ c #173D87",
-"c+ c #375B99",
-"d+ c #3366A1",
-"e+ c #507CAE",
-"f+ c #F4F7FA",
-"g+ c #B1AACB",
-"h+ c #303B86",
-"i+ c #38649F",
-"j+ c #385A99",
-"k+ c #183D86",
-"l+ c #163782",
-"m+ c #AAB9D4",
-"n+ c #F1F4F8",
-"o+ c #385B99",
-"p+ c #123984",
-"q+ c #285093",
-"r+ c #37649F",
-"s+ c #3366A0",
-"t+ c #3267A1",
-"u+ c #3469A3",
-"v+ c #B7CADF",
-"w+ c #FAFAFC",
-"x+ c #584D91",
-"y+ c #305898",
-"z+ c #3466A0",
-"A+ c #3665A0",
-"B+ c #3C629E",
-"C+ c #295092",
-"D+ c #A5B8D3",
-"E+ c #113A85",
-"F+ c #15428A",
-"G+ c #36619E",
-"H+ c #3466A1",
-"I+ c #3268A2",
-"J+ c #3168A3",
-"K+ c #507FB1",
-"L+ c #F7F9FB",
-"M+ c #E5E3EE",
-"N+ c #A6A9CA",
-"O+ c #9CAFCE",
-"P+ c #C2D2E4",
-"Q+ c #FAFBFD",
-"R+ c #A29BC1",
-"S+ c #2C3F89",
-"T+ c #3267A2",
-"U+ c #3266A1",
-"V+ c #3465A0",
-"W+ c #37609D",
-"X+ c #174289",
-"Y+ c #113984",
-"Z+ c #A6B8D3",
-"`+ c #466BA3",
-" @ c #0C3E88",
-".@ c #235395",
-"+@ c #3268A3",
-"@@ c #3269A4",
-"#@ c #316BA4",
-"$@ c #8CADCD",
-"%@ c #D4D0E2",
-"&@ c #42478D",
-"*@ c #3068A3",
-"=@ c #3270A8",
-"-@ c #3472AA",
-";@ c #9FBCD7",
-">@ c #CDC9DD",
-",@ c #2A2F7F",
-"'@ c #3169A3",
-")@ c #245395",
-"!@ c #0D3D87",
-"~@ c #466AA3",
-"{@ c #E6E5E6",
-"]@ c #D4DFEB",
-"^@ c #15458C",
-"/@ c #05569D",
-"(@ c #2F639F",
-"_@ c #3269A3",
-":@ c #326AA4",
-"<@ c #326BA5",
-"[@ c #316CA5",
-"}@ c #B8CCE0",
-"|@ c #645898",
-"1@ c #2F5D9D",
-"2@ c #3171AA",
-"3@ c #3271AA",
-"4@ c #6292BE",
-"5@ c #DCD9E7",
-"6@ c #292A7B",
-"7@ c #30629F",
-"8@ c #06569C",
-"9@ c #17458C",
-"0@ c #D5DFEB",
-"a@ c #EFEEEE",
-"b@ c #96AFCE",
-"c@ c #06428B",
-"d@ c #0F6CAD",
-"e@ c #3274AD",
-"f@ c #3169A4",
-"g@ c #316BA5",
-"h@ c #316CA6",
-"i@ c #316DA7",
-"j@ c #ABC4DB",
-"k@ c #D8E4EE",
-"l@ c #E9EEF4",
-"m@ c #F3F2F7",
-"n@ c #2B287A",
-"o@ c #2E6DA8",
-"p@ c #2E71AA",
-"q@ c #2F71AA",
-"r@ c #83ABCD",
-"s@ c #CCC7DC",
-"t@ c #2A3180",
-"u@ c #316AA4",
-"v@ c #3273AD",
-"w@ c #08428B",
-"x@ c #97AFCE",
-"y@ c #F6F5F5",
-"z@ c #5A82B2",
-"A@ c #024A92",
-"B@ c #1B76B4",
-"C@ c #3282B9",
-"D@ c #326DA6",
-"E@ c #326CA5",
-"F@ c #326EA7",
-"G@ c #316FA8",
-"H@ c #3270A9",
-"I@ c #3875AC",
-"J@ c #417BB0",
-"K@ c #4A83B5",
-"L@ c #5C90BD",
-"M@ c #6F9AC3",
-"N@ c #80A8CB",
-"O@ c #7EA1C7",
-"P@ c #133A87",
-"Q@ c #09599D",
-"R@ c #08599C",
-"S@ c #3F7EB2",
-"T@ c #E8EFF6",
-"U@ c #968EB9",
-"V@ c #2D488F",
-"W@ c #316EA7",
-"X@ c #326CA6",
-"Y@ c #3281B9",
-"Z@ c #1B76B3",
-"`@ c #034A92",
-" # c #5C82B2",
-".# c #225B9B",
-"+# c #01539A",
-"@# c #267DB7",
-"## c #3285BC",
-"$# c #327BB4",
-"%# c #326DA7",
-"&# c #326FA8",
-"*# c #3170A9",
-"=# c #3172AB",
-"-# c #1E67A4",
-";# c #0C5C9E",
-"># c #03559B",
-",# c #00549A",
-"'# c #00559A",
-")# c #4483B6",
-"!# c #E6EEF5",
-"~# c #F2F1F6",
-"{# c #484089",
-"]# c #3067A3",
-"^# c #327BB3",
-"/# c #267CB7",
-"(# c #235B9A",
-"_# c #E3E3E3",
-":# c #03458D",
-"<# c #035BA0",
-"[# c #2B80B9",
-"}# c #3185BC",
-"|# c #3186BD",
-"1# c #3177B0",
-"2# c #3171A9",
-"3# c #3172AA",
-"4# c #2F72AA",
-"5# c #06589C",
-"6# c #00559B",
-"7# c #00569B",
-"8# c #00579C",
-"9# c #02599D",
-"0# c #6398C2",
-"a# c #F9FBFD",
-"b# c #8077AB",
-"c# c #2C5195",
-"d# c #3170A8",
-"e# c #3177AF",
-"f# c #035AA0",
-"g# c #05448D",
-"h# c #D2D3D4",
-"i# c #F1F6F9",
-"j# c #00428B",
-"k# c #0460A5",
-"l# c #2F83BB",
-"m# c #3286BD",
-"n# c #3276AE",
-"o# c #286DA8",
-"p# c #0D5C9E",
-"q# c #01549A",
-"r# c #00569C",
-"s# c #00579D",
-"t# c #00589D",
-"u# c #00589E",
-"v# c #045BA0",
-"w# c #7DAACE",
-"x# c #FBFBFC",
-"y# c #9A94BD",
-"z# c #143987",
-"A# c #0E5B9D",
-"B# c #3275AE",
-"C# c #3186BC",
-"D# c #2F82BB",
-"E# c #0460A4",
-"F# c #E4E4E4",
-"G# c #DBE7F0",
-"H# c #00448D",
-"I# c #0562A7",
-"J# c #3084BB",
-"K# c #3187BE",
-"L# c #236AA6",
-"M# c #05579B",
-"N# c #00599F",
-"O# c #005A9F",
-"P# c #005AA0",
-"Q# c #7CABCE",
-"R# c #FBFCFD",
-"S# c #8E88B6",
-"T# c #143E8A",
-"U# c #05569B",
-"V# c #2369A6",
-"W# c #3285BD",
-"X# c #3187BD",
-"Y# c #3083BB",
-"Z# c #0562A6",
-"`# c #00438C",
-" $ c #DBE6F0",
-".$ c #00458D",
-"+$ c #0563A7",
-"@$ c #3184BB",
-"#$ c #3187BF",
-"$$ c #1E7CB9",
-"%$ c #025DA2",
-"&$ c #005BA0",
-"*$ c #005BA1",
-"=$ c #4287BA",
-"-$ c #FDFDFE",
-";$ c #6866A1",
-">$ c #0B4791",
-",$ c #1E7CB8",
-"'$ c #3183BB",
-")$ c #E3E2E2",
-"!$ c #00468E",
-"~$ c #0461A6",
-"{$ c #217EBA",
-"]$ c #036EB1",
-"^$ c #006CB1",
-"/$ c #0062A8",
-"($ c #00599E",
-"_$ c #005CA1",
-":$ c #005DA2",
-"<$ c #0561A5",
-"[$ c #BCD5E7",
-"}$ c #E6E4EE",
-"|$ c #565898",
-"1$ c #064F98",
-"2$ c #0062A7",
-"3$ c #006CB0",
-"4$ c #036DB1",
-"5$ c #217EB9",
-"6$ c #0461A5",
-"7$ c #034B92",
-"8$ c #035EA3",
-"9$ c #2B81B9",
-"0$ c #2881BB",
-"a$ c #046DB0",
-"b$ c #006BB0",
-"c$ c #006DB2",
-"d$ c #006AAF",
-"e$ c #0060A6",
-"f$ c #005EA3",
-"g$ c #005FA4",
-"h$ c #1C71AF",
-"i$ c #F3F8FB",
-"j$ c #EFEEF4",
-"k$ c #4F4D91",
-"l$ c #05539B",
-"m$ c #005CA2",
-"n$ c #0060A5",
-"o$ c #046CB0",
-"p$ c #035DA2",
-"q$ c #034B91",
-"r$ c #D4D4D5",
-"s$ c #E9E9E9",
-"t$ c #FBFAFA",
-"u$ c #2062A1",
-"v$ c #267DB8",
-"w$ c #2E84BC",
-"x$ c #0B6FB1",
-"y$ c #006EB3",
-"z$ c #006FB4",
-"A$ c #0064AA",
-"B$ c #0061A6",
-"C$ c #3E88BC",
-"D$ c #968DB8",
-"E$ c #10408E",
-"F$ c #0061A5",
-"G$ c #0064A9",
-"H$ c #006BAF",
-"I$ c #006AAE",
-"J$ c #2E83BC",
-"K$ c #2062A0",
-"L$ c #D8DADB",
-"M$ c #578AB8",
-"N$ c #1C77B4",
-"O$ c #1A78B5",
-"P$ c #0069AE",
-"Q$ c #0070B5",
-"R$ c #0070B6",
-"S$ c #4D97C7",
-"T$ c #5C4F92",
-"U$ c #065BA4",
-"V$ c #006DB1",
-"W$ c #0069AD",
-"X$ c #1A77B5",
-"Y$ c #1C76B4",
-"Z$ c #005399",
-"`$ c #5789B8",
-" % c #93B4D2",
-".% c #005096",
-"+% c #0F6EAF",
-"@% c #2C81BA",
-"#% c #056BAE",
-"$% c #0068AD",
-"%% c #0071B6",
-"&% c #0072B7",
-"*% c #328EC6",
-"=% c #9BC7E3",
-"-% c #9BC7E2",
-";% c #2C529A",
-">% c #026CB3",
-",% c #0071B7",
-"'% c #056BAD",
-")% c #0F6DAE",
-"!% c #004F95",
-"~% c #D3E1EC",
-"{% c #0A5699",
-"]% c #0260A5",
-"^% c #1573B2",
-"/% c #0067AB",
-"(% c #0070B4",
-"_% c #0073B8",
-":% c #0073B9",
-"<% c #0072B8",
-"[% c #0068AC",
-"}% c #025FA4",
-"|% c #0A5598",
-"1% c #E4E3E4",
-"2% c #3A79AF",
-"3% c #0066AB",
-"4% c #3C93C7",
-"5% c #69A6D1",
-"6% c #6AA5CF",
-"7% c #6AA4CF",
-"8% c #3470AF",
-"9% c #0564AC",
-"0% c #0067AC",
-"a% c #3A78AE",
-"b% c #A0BFD9",
-"c% c #005298",
-"d% c #0063A9",
-"e% c #96C4E1",
-"f% c #7F75A9",
-"g% c #0C529E",
-"h% c #0063A8",
-"i% c #005197",
-"j% c #F1F5F9",
-"k% c #286FAA",
-"l% c #0066AA",
-"m% c #96C4E0",
-"n% c #7F74A9",
-"o% c #0C519D",
-"p% c #0065AA",
-"q% c #286FA9",
-"r% c #F7F6F6",
-"s% c #A3C2DB",
-"t% c #96C3E0",
-"u% c #0C519C",
-"v% c #3E80B4",
-"w% c #96C3DF",
-"x% c #0C509B",
-"y% c #3E7FB4",
-"z% c #DCE8F1",
-"A% c #1969A7",
-"B% c #0C4F9B",
-"C% c #1968A7",
-"D% c #AECAE0",
-"E% c #0860A3",
-"F% c #96C2DE",
-"G% c #0C4F9A",
-"H% c #085FA2",
-"I% c #D6D7D8",
-"J% c #E8E8E9",
-"K% c #9ABED9",
-"L% c #61A3CD",
-"M% c #A5C9E1",
-"N% c #A5C8E1",
-"O% c #5270AB",
-"P% c #0758A0",
-"Q% c #9ABFDA",
-"R% c #0864A6",
-"S% c #0061A7",
-"T% c #0963A5",
-"U% c #EEEDED",
-"V% c #ADCCE2",
-"W% c #196FAE",
-"X% c #196EAD",
-"Y% c #ADCCE1",
-"Z% c #DCE9F2",
-"`% c #3D88BC",
-" & c #0063A7",
-".& c #3D87BB",
-"+& c #A3C7DF",
-"@& c #297DB7",
-"#& c #0065AB",
-"$& c #297DB6",
-"%& c #DFDFE0",
-"&& c #E3E3E4",
-"*& c #A0C6DF",
-"=& c #3B8ABF",
-"-& c #0A6EB0",
-";& c #3B8ABE",
-">& c #D3E4F0",
-",& c #93BFDC",
-"'& c #579DCA",
-")& c #207DB9",
-"!& c #579CC9",
-"~& c #F1F6FA",
-"{& c #DAE9F3",
-"]& c #DBE9F3",
-"^& c #E6E6E6",
-" . + @ # $ % & * ",
-" = - ; > , ' ) ! ! ~ { ] ^ / ( _ ",
-" : < [ } | | | | 1 2 2 1 | | | 3 4 5 6 & ",
-" 7 > 8 9 0 a b c d e f f f f e g c b h 0 | ' i % ",
-" j k 4 | l m n o p q r s t u v t s w q p o n m l 3 [ x y ",
-" z A 3 | B C D E F G H I J K L L K J M H N O P D C B | } ^ Q ",
-" R 4 9 S T U V W X Y Z Z ` ` ` ` ` ` ` .Z ..+.@.W U E #.S | $.%. ",
-" &.8 | *.=.-.;.>.,.` '.).).!.!.!.!.!.!.!.~.).{.` ` ,.].^.V /.(.0 _.:. ",
-" <.8 | [.}.|.1.2.{.!.3.3.4.5.5.6.6.6.6.6.6.5.5.7.3.!.).{.8.1.9.0.[.| _.%. ",
-" a.8 | b.c.d.e.f.3.g.h.6.i.j.k.l.m.n.o.p.q.r.s.t.u.v.6.5.7.w.x.y.z.A.b.0 $.B. ",
-" C.D.9 E.F.G.H.I.5.i.j.J.K.L.M.N.0 O.O.9 O.O.9 P.Q.R.S.T.U.V.6.5.I.H.W.X.Y.| ^ y ",
-" Z.| `. +.+++@+i.#+$+%+&+*+=+9 9 9 9 9 9 9 9 9 9 9 9 -+;+>+,+'+j.i.)+++!+~+{+} x ",
-" x ]+| ^+/+(+_+J.:+<+[+}+|+1+9 O.O.9 O.O.9 O.O.9 O.O.9 O.O.2+3+4+5+'+j.6+7+8+9+| [ % ",
-" , | 0+a+b+c+$+<+[+}+d+e+f+O.9 O.O.9 O.O.9 O.O.9 O.O.9 O.O.O.g+h+}+i+5+'+j+k+l+m+3 i ",
-" / 3 n+o+p+q+%+r+}+s+t+u+v+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 w+x+y+z+A+&+B+C+p+j+n+' Q ",
-" 5 9 D+E+F+G+A+H+t+I+J+K+L+O.O.9 O.O.9 O.M+N+O+P+Q+O.O.9 O.O.O.9 R+S+T+U+V+[+W+X+Y+Z+| 6 ",
-" a.8 0 `+ @.@}+d+T++@@@#@$@9 O.O.9 O.O.9 %@&@*@=@-@;@O.O.9 O.O.O.9 >@,@'@I+t+s+A+)@!@~@0 5 _ ",
-" {@| ]@^@/@(@U+I+_@:@<@[@}@9 O.O.9 O.O.9 |@1@2@3@3@4@O.O.9 O.O.O.9 5@6@#@:@+@T+d+7@8@9@0@4 ( ",
-" a@| b@c@d@e@J+f@#@g@h@i@j@k@l@w+9 9 9 m@n@o@p@p@q@r@9 9 9 9 9 9 9 s@t@[@g@u@'@I+v@d@w@x@3 / ",
-" y@| z@A@B@C@D@#@E@D@F@G@H@I@J@K@L@M@N@O@P@Q@R@R@S@T@O.O.9 O.O.O.9 U@V@W@X@E@#@X@Y@Z@`@ #| ^ ",
-"< 8 | .#+#@###$#h@%#&#=@*#3@=#p@-#;#>#,#,#'#'#'#)#!#9 O.O.9 O.O.O.~#{#]#G@F@D@[@^###/#+#(#| ] * ",
-"_#3 | :#<#[#}#|#1#G@*#2#3#4#-#5#,#,#6#7#7#8#9#0#a#9 9 9 9 9 9 9 9 b#c#3#*#d#G@e#}#}#[#f#g#| { h#",
-"6 3 i#j#k#l#m#m#|#n#3@=#o#p#q#'#7#r#s#t#u#v#w#1+O.O.9 O.O.9 O.x#y#z#A#o#3#3@B#C#m###D#E#j#i#~ % ",
-"F#| G#H#I#J#m#m#K#m#1#L#M#,#6#r#s#u#N#O#P#Q#R#9 O.O.9 O.O.9 x#S#T#'#,#U#V#e#W#X#m###Y#Z#`#G#! $ ",
-"; 3 $.$+$@$}#|#K##$$$%$,#7#s#u#N#P#&$*$=$-$9 9 9 9 9 9 9 ~#;$>$u#r#6#,#%$,$#$X#|#}#'$Z#.$ $! # ",
-")$3 i#!$~$l#m#m#K#{$]$^$/$N#($O#&$_$:$<$[$O.O.9 O.O.9 O.}$|$1$&$O#u#u#2$3$4$5$X#m###D#6$!$i#) @ ",
-"; 3 | 7$8$9$m#|#0$a$b$^$c$d$e$_$:$f$g$h$i$O.O.9 O.O.9 j$k$l$f$m$*$n$d$c$^$b$o$0$|###[#p$q$| ' r$",
-"s$t$| u$u#v$}#w$x$d$b$^$c$y$z$^$A$B$B$C$9 9 9 9 9 9 9 D$E$F$n$G$b$z$y$c$3$H$I$x$J$}#/#t#K$| , L$",
-" ) | M$,#N$}#O$P$I$H$3$c$y$z$Q$R$Q$^$S$9 O.O.9 O.O.9 T$U$^$z$Q$Q$z$c$V$b$d$P$W$X$}#Y$Z$`$| > ",
-" , | %.%+%@%#%$%I$H$b$^$c$y$Q$Q$%%&%*%=%-%-%-%-%-%-%;%>%,%%%Q$z$y$c$^$b$d$P$$%'%@%)%!% %| ; ",
-" ^ | ~%{%]%^%/%$%P$d$H$3$c$y$z$(%Q$%%,%&%_%:%:%:%_%<%&%%%%%Q$z$y$c$V$3$d$I$W$[%/%^%}%|%~%} - ",
-" 1%]+0 2%t#3%/%[%P$I$d$b$^$c$y$z$(%Q$4%5%6%6%6%6%6%7%8%9%Q$z$z$y$c$^$b$d$P$$%0%/%3%s#a%0 [ = ",
-" D.9 b%c%d%3%/%$%P$d$H$3$^$c$y$z$Q$e%9 O.O.9 O.O.9 f%g%z$z$y$c$^$b$H$P$P$$%/%3%h%i%b%9 < ",
-" < | j%k%*$l%/%[%$%P$d$H$3$^$c$y$y$m%9 9 9 9 9 9 9 n%o%y$c$c$^$b$H$I$W$$%0%3%p%P#q%j%8 : ",
-" r%9 s%6#2$l%/%$%P$P$d$H$3$^$c$c$t%9 O.O.9 O.O.9 f%u%c$V$^$b$H$d$P$$%[%/%l%B$6#s%| > ",
-" < | | v%O#p%3%0%$%W$P$d$H$b$3$^$w%9 9 9 9 9 9 9 n%x%^$3$b$H$I$P$$%[%/%l%G$N#y%| 4 7 ",
-" _.| z%A%f$p%/%0%$%P$P$d$d$H$b$w%9 O.O.9 O.O.9 f%B%b$H$d$I$W$$%[%/%3%p%:$C%z%3 k ",
-" _#8 9 D%E%e$l%/%0%$%$%P$I$d$H$F%9 O.O.9 O.O.9 f%G%d$I$P$P$$%[%/%3%p%n$H%D%9 A I% ",
-" J%3 | K%_$B$l%3%/%[%$%P$P$I$L%M%M%M%N%M%M%N%O%P%P$P$$%$%0%/%3%p%B$*$K%| 4 z ",
-" > 3 | Q%R%S%p%l%/%/%[%$%$%W$W$P$P$P$P$P$P$W$W$$%$%[%/%/%l%p%B$T%Q%| 8 R ",
-" U%3 | V%W%2$p%l%3%/%/%[%$%$%$%$%$%$%$%$%$%[%0%/%/%3%p%G$B$X%Y%| 8 &. ",
-" > 3 9 Z%`%h%p%p%3%l%/%/%/%[%[%0%[%[%/%/%/%/%3%l%p%G$ &.&Z%9 8 <. ",
-" J%8 | | +&@&3%3%3%#&l%l%l%l%l%l%l%l%l%l%p%3%3%l%$&+&| | D.%& ",
-" &&_.| 9 i#*&=&-&P$P$$%0%0%3%3%0%0%$%$%W$-&;&*&i#| ]+Z.C. ",
-" < r%| 9 0 >&,&'&)&4$^$^$^$3$4$)&!&,&>&0 9 3 , x ",
-" < D.]+| | | | | ~&{&]&~&| | | | | 8 5 / ",
-" F#^ , ) t$3 3 3 | 3 3 8 y@a@^&a. ",
-" s$; )$; F#6 _#< "};
+++ /dev/null
-/* XPM */
-static const char * page_down_xpm[] = {
-"48 48 546 2",
-" c None",
-". c #C6CCD0",
-"+ c #CBD0D4",
-"@ c #CBD1D4",
-"# c #CCD1D5",
-"$ c #CCD2D5",
-"% c #CDD2D5",
-"& c #CAD0D4",
-"* c #CACFD3",
-"= c #C9CFD3",
-"- c #C9CED3",
-"; c #C8CED2",
-"> c #C3C9CE",
-", c #ECEEF0",
-"' c #F8F9F9",
-") c #F9FAFA",
-"! c #FBFBFB",
-"~ c #FCFCFC",
-"{ c #FDFDFD",
-"] c #FAFBFB",
-"^ c #F7F8F9",
-"/ c #F6F7F8",
-"( c #F5F6F6",
-"_ c #F3F4F5",
-": c #F1F3F5",
-"< c #EEF0F1",
-"[ c #C5CBD0",
-"} c #EDEFF1",
-"| c #FBFCFC",
-"1 c #F0F2F4",
-"2 c #DDE1E4",
-"3 c #DCE0E2",
-"4 c #EFF1F2",
-"5 c #FAFAFB",
-"6 c #F4F5F6",
-"7 c #EAEDEF",
-"8 c #D8DCDF",
-"9 c #F1F2F3",
-"0 c #F1F3F4",
-"a c #D2D7DB",
-"b c #FEFEFE",
-"c c #F8F9FA",
-"d c #E8EAEC",
-"e c #FFFFFF",
-"f c #EDEFF0",
-"g c #D5D9DD",
-"h c #E4E7E9",
-"i c #F5F6F7",
-"j c #DCDFE2",
-"k c #D0D5D9",
-"l c #DEE2E4",
-"m c #DFE2E5",
-"n c #E0E3E6",
-"o c #E3E6E8",
-"p c #EAECEE",
-"q c #F2F3F4",
-"r c #D4D8DC",
-"s c #F0F2F3",
-"t c #EBEEF0",
-"u c #E9EBED",
-"v c #E5E9EA",
-"w c #E0E4E6",
-"x c #D9DDE0",
-"y c #D1D6DA",
-"z c #F2F3F5",
-"A c #E8EBED",
-"B c #E5E9EB",
-"C c #E1E5E8",
-"D c #C7CDD1",
-"E c #EFF1F3",
-"F c #E3E7EA",
-"G c #D8DEE1",
-"H c #E5E8EB",
-"I c #D8DDE1",
-"J c #ECEFF0",
-"K c #EAEDEE",
-"L c #E7EBED",
-"M c #F6F7F7",
-"N c #F3F4F6",
-"O c #E9ECEE",
-"P c #E7EAEC",
-"Q c #E4E8EB",
-"R c #E2E6E9",
-"S c #D7DDE1",
-"T c #EBEEEF",
-"U c #E6EAEC",
-"V c #E1E6E8",
-"W c #D7DCE1",
-"X c #E0E5E8",
-"Y c #D7DCE0",
-"Z c #E0E4E7",
-"` c #EDF0F1",
-" . c #E4E8EA",
-".. c #DFE4E7",
-"+. c #D6DBDF",
-"@. c #F2F4F5",
-"#. c #E9EBEC",
-"$. c #E1E2E3",
-"%. c #DEDFDF",
-"&. c #DFDFE0",
-"*. c #E0E0E0",
-"=. c #E0DFE0",
-"-. c #DFDFDF",
-";. c #DCDDDE",
-">. c #D9DBDE",
-",. c #D3D8DB",
-"'. c #EAEAEB",
-"). c #E8E8E8",
-"!. c #E6EDE7",
-"~. c #D1E7D8",
-"{. c #A3D2B0",
-"]. c #90C9A2",
-"^. c #91CAA2",
-"/. c #A6D3B3",
-"(. c #D3E8DA",
-"_. c #E9EFEA",
-":. c #E9E8E9",
-"<. c #D1D5D3",
-"[. c #FCFDFD",
-"}. c #F3F4F4",
-"|. c #E9E9E9",
-"1. c #DAEBDE",
-"2. c #6FBB8A",
-"3. c #249750",
-"4. c #058839",
-"5. c #0B8B40",
-"6. c #108E44",
-"7. c #118E44",
-"8. c #0C8C40",
-"9. c #07893B",
-"0. c #279852",
-"a. c #77BE8F",
-"b. c #DFEEE3",
-"c. c #ECEBEB",
-"d. c #C5D0C8",
-"e. c #EBEDEF",
-"f. c #EFF0F1",
-"g. c #EAF0EB",
-"h. c #7CC193",
-"i. c #098B3C",
-"j. c #109043",
-"k. c #249A53",
-"l. c #30A15C",
-"m. c #31A25D",
-"n. c #31A15D",
-"o. c #269C55",
-"p. c #129144",
-"q. c #0E8E3F",
-"r. c #83C599",
-"s. c #F0F4F1",
-"t. c #D9DBD9",
-"u. c #F0F0F1",
-"v. c #E1E1E1",
-"w. c #E2EEE5",
-"x. c #3FA664",
-"y. c #098F3D",
-"z. c #239C52",
-"A. c #31A35D",
-"B. c #32A55E",
-"C. c #31A55D",
-"D. c #33A65F",
-"E. c #33A75F",
-"F. c #33A65E",
-"G. c #31A45D",
-"H. c #269E55",
-"I. c #0C903F",
-"J. c #4DAD6E",
-"K. c #E5F0E8",
-"L. c #DCDEDC",
-"M. c #E6F0E8",
-"N. c #39A55F",
-"O. c #0B923F",
-"P. c #2BA258",
-"Q. c #31A65D",
-"R. c #32A85D",
-"S. c #33AA5D",
-"T. c #35AB5D",
-"U. c #C9E8D4",
-"V. c #CEEBD9",
-"W. c #B1DDC2",
-"X. c #27A356",
-"Y. c #31A85D",
-"Z. c #32A75E",
-"`. c #2EA45B",
-" + c #0E9341",
-".+ c #43AA66",
-"++ c #EDF4EE",
-"@+ c #D0D8D2",
-"#+ c #E6E9EB",
-"$+ c #E3E3E4",
-"%+ c #EEF0EE",
-"&+ c #54B374",
-"*+ c #08923C",
-"=+ c #2DA55A",
-"-+ c #38AC5D",
-";+ c #40AE5C",
-">+ c #46B05C",
-",+ c #4BB05C",
-"'+ c #F7FBF8",
-")+ c #D8EEE1",
-"!+ c #2CA454",
-"~+ c #47B05C",
-"{+ c #39AC5D",
-"]+ c #34AA5D",
-"^+ c #2FA65B",
-"/+ c #0D9540",
-"(+ c #61B97D",
-"_+ c #F5F5F5",
-":+ c #EEF1F2",
-"<+ c #F3F5F6",
-"[+ c #ECEEEF",
-"}+ c #E5E4E4",
-"|+ c #A7D8B6",
-"1+ c #07933A",
-"2+ c #26A453",
-"3+ c #3AAD5D",
-"4+ c #44AF5C",
-"5+ c #4EB15C",
-"6+ c #54B45C",
-"7+ c #59B55B",
-"8+ c #5DB75B",
-"9+ c #F8FCF8",
-"0+ c #34A754",
-"a+ c #5AB65B",
-"b+ c #55B45C",
-"c+ c #4FB25C",
-"d+ c #46AF5C",
-"e+ c #3BAD5D",
-"f+ c #2BA657",
-"g+ c #07943A",
-"h+ c #B9E0C3",
-"i+ c #E6E6E6",
-"j+ c #E2E6E8",
-"k+ c #EEF0F2",
-"l+ c #F1F2F4",
-"m+ c #E3E4E4",
-"n+ c #F5F4F4",
-"o+ c #2BA453",
-"p+ c #169E44",
-"q+ c #4EB25C",
-"r+ c #57B45C",
-"s+ c #64BA5B",
-"t+ c #68BC5B",
-"u+ c #6BBD5B",
-"v+ c #F9FCF8",
-"w+ c #3BA954",
-"x+ c #69BC5B",
-"y+ c #65BA5B",
-"z+ c #5EB85B",
-"A+ c #58B55C",
-"B+ c #42AE5C",
-"C+ c #1EA149",
-"D+ c #3FAD63",
-"E+ c #F2F5F2",
-"F+ c #E2E2E3",
-"G+ c #BDE2C5",
-"H+ c #189E34",
-"I+ c #3FAC55",
-"J+ c #53B35C",
-"K+ c #65BB5B",
-"L+ c #6CBD5B",
-"M+ c #71BF5E",
-"N+ c #75C060",
-"O+ c #78C163",
-"P+ c #40AB57",
-"Q+ c #75C061",
-"R+ c #6CBD5C",
-"S+ c #66BB5B",
-"T+ c #5EB75B",
-"U+ c #45AF59",
-"V+ c #1FA035",
-"W+ c #CAE8D1",
-"X+ c #DEE3E5",
-"Y+ c #E6E8EA",
-"Z+ c #EBEAEA",
-"`+ c #77C589",
-" @ c #5EB534",
-".@ c #64B958",
-"+@ c #61B85B",
-"@@ c #6ABD5B",
-"#@ c #80C56D",
-"$@ c #73BF63",
-"%@ c #7FC469",
-"&@ c #81C56A",
-"*@ c #FAFCF9",
-"=@ c #44AD5B",
-"-@ c #80C46A",
-";@ c #7CC367",
-">@ c #7FC56D",
-",@ c #6BBD5C",
-"'@ c #62B95B",
-")@ c #69BB58",
-"!@ c #5FB638",
-"~@ c #8ACD98",
-"{@ c #EFEFEF",
-"]@ c #DCE1E4",
-"^@ c #E2E5E6",
-"/@ c #F2F2F2",
-"(@ c #58B667",
-"_@ c #7EC139",
-":@ c #8EC952",
-"<@ c #6DBE5B",
-"[@ c #74C060",
-"}@ c #9ED38F",
-"|@ c #ECF7EC",
-"1@ c #5EB97A",
-"2@ c #6EBC5A",
-"3@ c #75BE57",
-"4@ c #3FAA52",
-"5@ c #78BF5B",
-"6@ c #A8D797",
-"7@ c #E6F4E7",
-"8@ c #59B774",
-"9@ c #6DBD5E",
-"0@ c #6FBF5B",
-"a@ c #90CB51",
-"b@ c #7DC13E",
-"c@ c #62BA67",
-"d@ c #F8F8F8",
-"e@ c #DADFE3",
-"f@ c #E4E7EA",
-"g@ c #DFE2E3",
-"h@ c #EBF1EB",
-"i@ c #52B24F",
-"j@ c #87C53E",
-"k@ c #9BCE4E",
-"l@ c #8BC856",
-"m@ c #A3D593",
-"n@ c #F8FCF7",
-"o@ c #F0F9F4",
-"p@ c #62BA7B",
-"q@ c #71BC58",
-"r@ c #44AB54",
-"s@ c #A5D48D",
-"t@ c #FBFDFA",
-"u@ c #F1F9F4",
-"v@ c #59B674",
-"w@ c #81C453",
-"x@ c #8AC743",
-"y@ c #57B350",
-"z@ c #FAFAFA",
-"A@ c #E2E7E9",
-"B@ c #DEE0E2",
-"C@ c #E9F1E8",
-"D@ c #55B348",
-"E@ c #8AC640",
-"F@ c #9CCF4F",
-"G@ c #A1D158",
-"H@ c #F3F9ED",
-"I@ c #EDF7F1",
-"J@ c #66BB7D",
-"K@ c #D8EEE2",
-"L@ c #7AC48E",
-"M@ c #F8FCF6",
-"N@ c #D3ECDD",
-"O@ c #53B250",
-"P@ c #8EC845",
-"Q@ c #5BB54D",
-"R@ c #DEE2E6",
-"S@ c #DFE3E7",
-"T@ c #E0E5E7",
-"U@ c #DDDFE1",
-"V@ c #EDF2EC",
-"W@ c #63B950",
-"X@ c #88C53E",
-"Y@ c #98CD4A",
-"Z@ c #AAD56A",
-"`@ c #F8FBF3",
-" # c #FAFDFB",
-".# c #F3FAF6",
-"+# c #F5FAF7",
-"@# c #5CB766",
-"## c #89C745",
-"$# c #8CC744",
-"%# c #66BA50",
-"&# c #D5DBDE",
-"*# c #DDE1E5",
-"=# c #DEE2E5",
-"-# c #DEE3E6",
-";# c #F4F4F4",
-"># c #79C368",
-",# c #81C23A",
-"'# c #9ACE4D",
-")# c #8AC531",
-"!# c #83C124",
-"~# c #A5D260",
-"{# c #F6FBF0",
-"]# c #E8F5EE",
-"^# c #5BB665",
-"/# c #7BBE25",
-"(# c #88C42D",
-"_# c #9ACD4C",
-":# c #84C440",
-"<# c #81C66C",
-"[# c #F9F9F9",
-"}# c #D3D9DD",
-"|# c #DAE0E3",
-"1# c #DBE0E3",
-"2# c #DDE2E5",
-"3# c #DADFE2",
-"4# c #EEEEEE",
-"5# c #A0D491",
-"6# c #73BD37",
-"7# c #92C940",
-"8# c #A5D25F",
-"9# c #61B967",
-"0# c #77BD26",
-"a# c #82C023",
-"b# c #90C83B",
-"c# c #77BF3C",
-"d# c #ADD99F",
-"e# c #F3F3F3",
-"f# c #D1D8DC",
-"g# c #D8DEE2",
-"h# c #D9DFE2",
-"i# c #D9DFE3",
-"j# c #DBE1E4",
-"k# c #E4E5E6",
-"l# c #D6ECCF",
-"m# c #67B83A",
-"n# c #82C12A",
-"o# c #A7D363",
-"p# c #F0F8F3",
-"q# c #84C228",
-"r# c #6BBA3E",
-"s# c #DFF0D9",
-"t# c #E7E7E7",
-"u# c #D0D6DA",
-"v# c #D6DCE0",
-"w# c #DADDE0",
-"x# c #F9F8F8",
-"y# c #82C567",
-"z# c #77BD2B",
-"A# c #A4D25F",
-"B# c #F7FBF1",
-"C# c #EAF6EF",
-"D# c #5AB664",
-"E# c #7ABE2B",
-"F# c #8FCB79",
-"G# c #F8F9F7",
-"H# c #CED4D9",
-"I# c #D4DADE",
-"J# c #D4DADF",
-"K# c #D5DBDF",
-"L# c #D5DADE",
-"M# c #D0E8C6",
-"N# c #76BD45",
-"O# c #7FBF25",
-"P# c #ABD56B",
-"Q# c #FAFDF7",
-"R# c #F0F8F4",
-"S# c #66BC72",
-"T# c #74BB26",
-"U# c #80C025",
-"V# c #78BE47",
-"W# c #DBEDD3",
-"X# c #EEEFEC",
-"Y# c #CBD3D8",
-"Z# c #D1D8DD",
-"`# c #D2D8DD",
-" $ c #D2D9DE",
-".$ c #D3D9DE",
-"+$ c #D7DBDE",
-"@$ c #F8F8F7",
-"#$ c #A9D692",
-"$$ c #7ABE3A",
-"%$ c #81C024",
-"&$ c #AED76F",
-"*$ c #F8FCFA",
-"=$ c #62BA70",
-"-$ c #73BB26",
-";$ c #82C024",
-">$ c #7DC03D",
-",$ c #B2DA9D",
-"'$ c #C9D1D6",
-")$ c #CFD6DB",
-"!$ c #D0D7DC",
-"~$ c #E0E2E4",
-"{$ c #F5F9F4",
-"]$ c #A3D385",
-"^$ c #7FC13B",
-"/$ c #80C024",
-"($ c #A8D466",
-"_$ c #7BC36A",
-":$ c #77BC26",
-"<$ c #83C23F",
-"[$ c #ABD78F",
-"}$ c #F8FAF6",
-"|$ c #E3E9DD",
-"1$ c #C7CFD5",
-"2$ c #CCD4D9",
-"3$ c #CDD4D9",
-"4$ c #CED5DA",
-"5$ c #E6E7E8",
-"6$ c #F5F9F3",
-"7$ c #AED88E",
-"8$ c #89C64A",
-"9$ c #7FC028",
-"0$ c #81C029",
-"a$ c #8CC74B",
-"b$ c #B7DC9B",
-"c$ c #F5F9F2",
-"d$ c #ECECEA",
-"e$ c #BAC2C8",
-"f$ c #BCC5CA",
-"g$ c #BDC5CA",
-"h$ c #BDC5CB",
-"i$ c #BEC6CB",
-"j$ c #BEC5CB",
-"k$ c #DFE1E3",
-"l$ c #F8FAF7",
-"m$ c #D0E8BA",
-"n$ c #9CCE68",
-"o$ c #87C43F",
-"p$ c #7FC027",
-"q$ c #80C027",
-"r$ c #8AC642",
-"s$ c #9ED06B",
-"t$ c #D3E9BF",
-"u$ c #FCFCFB",
-"v$ c #EBEBE9",
-"w$ c #DDE3D8",
-"x$ c #CDE7B6",
-"y$ c #B1D988",
-"z$ c #97CC5C",
-"A$ c #90C94D",
-"B$ c #8EC747",
-"C$ c #91C94E",
-"D$ c #98CD5E",
-"E$ c #B2DA89",
-"F$ c #D1E9BB",
-"G$ c #F7FAF4",
-"H$ c #E5E9E0",
-"I$ c #F6F5F5",
-"J$ c #F9FAF7",
-"K$ c #F2F8EC",
-"L$ c #E5F2D9",
-"M$ c #D9ECC7",
-"N$ c #E7F3DB",
-"O$ c #F2F8ED",
-"P$ c #FAFBF9",
-"Q$ c #F6F7F5",
-"R$ c #E8EBE4",
-"S$ c #E5ECDD",
-"T$ c #ECECEC",
-"U$ c #E6EDDF",
-" . + + @ # $ % % % % % % % % $ # @ + & * = - ; > ",
-" , ' ) ! ~ ~ { { { ~ { ~ { { ~ ~ ] ) ^ / ( _ : < [ ",
-" } ) | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | ) ' / ( _ 1 2 3 ",
-" 4 ~ ~ { { ~ { { { ~ { ~ { { ~ { { ~ ~ 5 ' / 6 _ 7 8 _ ",
-" 9 { ~ { { ~ { { { ~ { ~ { { ~ { { ~ { ~ ) ^ / 6 0 a b , ",
-" 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ! c / ( _ a b b d ",
-" 9 { ~ { { ~ { { { { { { { { ~ { { ~ { { ~ ] ^ / 6 a b e b f ",
-" 9 { ~ { { { { b b { b { b { { { { ~ { { ~ | ) ^ ( g b e e b h ",
-" 9 ~ ~ ~ { { { { { { { { { { { ~ ~ ~ ~ ~ ~ ~ ) ^ i g b b b b { j ",
-" 9 { ~ { { { b b b { b { b b { { { ~ { { ~ { ] ^ / k l m n o p q r ",
-" 9 { ~ { { { b b b { b { b b { { { ~ { { ~ { | c / s t u v w x y & ",
-" 9 ~ ~ { { { { { { { { { { { { { { ~ ~ ~ ~ ~ | c / 6 z 4 } 7 A B C D ",
-" 9 { ~ { b { b b b b b { b b { b { ~ { { ~ { | c / 6 z E } 7 A B F G ",
-" 9 { ~ { b { b b b { b { b b { b { ~ { { ~ { | c / 6 z E } 7 A B F G ",
-" 9 ~ ~ { { { { { { { { { { { { { { ~ ~ ~ ~ ~ ! c / 6 z 4 f 7 A H F I ",
-" 9 { ~ { { { b b b { b { b b { { { ~ { { ~ { ] ^ / 6 0 4 J K L H F I ",
-" 9 { ~ { { { b b b { b { b b { { { ~ { { ~ ~ ) ^ M N 1 4 J O P Q R S ",
-" 9 { ~ { { { { b b { b { b { { { { ~ { { ~ | ) ^ ( _ s < T O U Q V W ",
-" 9 ~ ~ ~ ~ ~ ~ { { { { { { ~ ~ ~ ~ ~ ~ ~ ~ ] ^ / 6 0 4 } 7 O B F X Y ",
-" 9 { ~ { { ~ { { { ~ { ~ { { ~ { { ~ { { | ) ^ i _ 1 4 J K A H F Z Y ",
-" 9 { ~ { { ~ { { { ~ { ~ { { ~ { { ~ { ~ ) ^ / 6 z s ` T O P .R ..+. ",
-" 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ] ' / 6 @.#.$.%.&.*.=.-.;.>.,. ",
-" } ] ~ { { ~ { { { ~ { ~ { { ~ { { ~ ] c / 6 '.-.).!.~.{.].^./.(._.:.<. ",
-" , ' ) ! [.~ { { { ~ { ~ { { ~ ~ ! ) ' / }.*.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d. ",
-" e./ ^ c ) ! ~ ~ ~ ~ ~ ~ ~ ~ ! ) c ^ / f.-.g.h.i.j.k.l.m.m.m.m.n.o.p.q.r.s.t. ",
-" u ( M ^ ^ ' ) ) ] ] ] ] ) ) ' ^ / M u.v.w.x.y.z.A.B.C.D.E.E.F.C.B.G.H.I.J.K.L. ",
-" P _ 6 i / / ^ ^ ^ ^ ^ ^ ^ ^ / M 6 _ =.M.N.O.P.Q.R.S.T.U.V.V.W.X.S.Y.Z.`. +.+++@+ ",
-" #+s 0 _ 6 6 ( i M / / M i ( 6 _ _ $+%+&+*+=+S.-+;+>+,+'+b b )+!+~+;+{+]+^+/+(+_+ ",
-" h :+4 1 0 z _ _ <+_ 6 _ _ _ z 0 [+}+|+1+2+3+4+5+6+7+8+9+e e )+0+a+b+c+d+e+f+g+h+i+ ",
-" j+J } k+4 E s 1 1 l+l+1 1 s E 4 m+n+o+p+;+q+r+8+s+t+u+v+e e )+w+x+y+z+A+c+B+C+D+E+ ",
-" Z O 7 t J } < k+4 4 4 4 k+< } , F+G+H+I+J+8+K+L+M+N+O+v+b b )+P+Q+M+R+S+T+b+U+V+W+v. ",
-" X+A O O 7 7 T , , , J t t T 7 Y+Z+`+ @.@+@@@M+#@$@%@&@*@e e )+=@-@;@>@,@@@'@)@!@~@{@ ",
-" ]@B U L A O O O O O O O O O O ^@/@(@_@:@<@[@}@|@1@2@3@v+e e )+4@5@6@7@8@9@0@a@b@c@d@ ",
-" e@F f@Q B B U P P L L P P U B g@h@i@j@k@l@m@n@b o@p@q@v+b b )+r@s@t@b u@v@w@k@x@y@z@ ",
-" I X V A@F F Q Q Q Q Q Q Q .F B@C@D@E@F@G@H@e b e I@J@v+e e K@L@M@b e e N@O@F@P@Q@! ",
-" Y R@S@..T@X V R R R R R R C X U@V@W@X@k@Y@Z@`@b b b u@ #b b .#+#b b b o@@###k@$#%#z@ ",
-" &#]@*#=#R@R@-#S@S@....S@S@-#R@j ;#>#,#'#)#!#~#{#e e b e e e b e e b ]#^#/#(#_#:#<#[# ",
-" }#|#1#]@]@]@*#2#2#2#2#2#2#*#]@3#4#5#6#7#!#!#!#8#`@e b e e e b e e ]#9#0#a#!#b#c#d#e# ",
-" f#S g#h#i#|#1#j#j#j#j#j#j#1#|#i#k#l#m#n#a#!#!#a#o#`@b e e e b e p#^#0#!#a#!#q#r#s#t# ",
-" u#v#v#S S S S g#g#g#g#g#g#S S S w#x#y#z#a#a#a#a#a#A#B#b b b b C#D#/#a#a#a#a#E#F#G# ",
-" H#I#J#K#K#K#v#v#v#v#v#v#v#v#K#K#L#'.M#N#O#!#!#a#!#!#P#Q#e e R#S#T#a#!#!#a#U#V#W#X# ",
-" Y#Z#`# $.$.$J#J#J#J#J#J#J#I#.$.$ $+$@$#$$$%$!#a#!#!#a#&$Q#*$=$-$!#a#!#!#;$>$,$z@ ",
-" '$)$)$!$!$Z#Z#Z#Z#`#`#Z#Z#Z#Z#!$!$)$~${$]$^$/$a#a#a#a#a#($_$:$a#a#a#a#%$<$[$}$|$ ",
-" 1$2$3$4$4$4$)$)$)$)$)$)$)$)$4$4$4$3$3$5$6$7$8$9$;$!#a#!#!#!#a#!#!#;$0$a$b$c$d$ ",
-" e$f$f$g$h$h$h$h$i$i$i$j$h$h$h$h$g$f$f$j$k$l$m$n$o$p$%$!#!#!#a#%$q$r$s$t$u$v$ ",
-" w$_+c$x$y$z$A$B$B$C$D$E$F$G$d@ ",
-" H$I$J$K$L$M$M$N$O$P$Q$R$ ",
-" S$T${@{@T$U$ "};
+++ /dev/null
-/* XPM */
-static const char * remove_xpm[] = {
-"48 48 705 2",
-" c None",
-". c #DDD8D8",
-"+ c #D6D4D4",
-"@ c #D4D3D3",
-"# c #D6D5D5",
-"$ c #D5D4D4",
-"% c #D3D2D2",
-"& c #D5D2D2",
-"* c #DBD6D6",
-"= c #D7D4D4",
-"- c #DCDBDB",
-"; c #E5E4E4",
-"> c #ECECEC",
-", c #F2F2F2",
-"' c #F5F5F5",
-") c #F7F7F7",
-"! c #F8F7F7",
-"~ c #F6F6F6",
-"{ c #F5F4F4",
-"] c #F0F0F0",
-"^ c #EAE9E9",
-"/ c #E1E1E1",
-"( c #D8D7D7",
-"_ c #D2CFCF",
-": c #DAD9D8",
-"< c #E7E7E7",
-"[ c #F3F3F3",
-"} c #FAFAFA",
-"| c #FDFDFD",
-"1 c #FBF3F3",
-"2 c #F5E0DE",
-"3 c #F5E0DF",
-"4 c #FCFCFC",
-"5 c #F8F8F8",
-"6 c #EFEFEF",
-"7 c #E2E1E1",
-"8 c #D4D2D2",
-"9 c #DADADA",
-"0 c #F9F9F9",
-"a c #FEFEFE",
-"b c #FDFCFC",
-"c c #F2D9D8",
-"d c #DEA39F",
-"e c #CA6F69",
-"f c #BA4038",
-"g c #AE271E",
-"h c #AA241B",
-"i c #AD271E",
-"j c #DEA29F",
-"k c #E6E5E5",
-"l c #D9D6D6",
-"m c #E8E7E7",
-"n c #FAF3F2",
-"o c #E3AEAB",
-"p c #C25750",
-"q c #B02D24",
-"r c #AC241B",
-"s c #AD241B",
-"t c #AE261D",
-"u c #AF281F",
-"v c #AF2820",
-"w c #AF2920",
-"x c #AC231A",
-"y c #E2AEAB",
-"z c #E0DFDF",
-"A c #D0CDCD",
-"B c #DEDCDC",
-"C c #F2F1F1",
-"D c #E4B0AD",
-"E c #BD4840",
-"F c #AD231A",
-"G c #AE241B",
-"H c #AF251C",
-"I c #B43129",
-"J c #B83C34",
-"K c #BC443D",
-"L c #BE4943",
-"M c #BF4C46",
-"N c #BF4E47",
-"O c #BB443D",
-"P c #B33129",
-"Q c #AE251C",
-"R c #AD231B",
-"S c #E4B1AD",
-"T c #E1E0E0",
-"U c #F5E1E0",
-"V c #C55952",
-"W c #AF241B",
-"X c #B22B23",
-"Y c #BA3C35",
-"Z c #BF4B44",
-"` c #C14F49",
-" . c #C24E48",
-".. c #C24F49",
-"+. c #C14E48",
-"@. c #B93C35",
-"#. c #C45952",
-"$. c #F1F1F1",
-"%. c #D7D6D6",
-"&. c #E4E3E3",
-"*. c #E7B9B6",
-"=. c #B93932",
-"-. c #B0241B",
-";. c #B32820",
-">. c #BB3B34",
-",. c #C14C46",
-"'. c #C34E48",
-"). c #C44F49",
-"!. c #C54E48",
-"~. c #C54F49",
-"{. c #C64F49",
-"]. c #C44E48",
-"^. c #C34F49",
-"/. c #BA3B34",
-"(. c #B22820",
-"_. c #B83931",
-":. c #F3F2F2",
-"<. c #D9D8D8",
-"[. c #E2E2E2",
-"}. c #E2A9A6",
-"|. c #B42B23",
-"1. c #B2241C",
-"2. c #B73028",
-"3. c #C14841",
-"4. c #C64E48",
-"5. c #C74E48",
-"6. c #C84E48",
-"7. c #C84F48",
-"8. c #C94F48",
-"9. c #C04841",
-"0. c #B1241C",
-"a. c #E0DEDE",
-"b. c #E3A9A5",
-"c. c #B3241C",
-"d. c #B4251D",
-"e. c #BB372F",
-"f. c #C44D47",
-"g. c #C84F49",
-"h. c #C94F49",
-"i. c #CA5049",
-"j. c #CA4F48",
-"k. c #BB362F",
-"l. c #DCDADA",
-"m. c #F4F4F4",
-"n. c #E9B9B7",
-"o. c #B72B23",
-"p. c #B5251D",
-"q. c #BE3932",
-"r. c #C64D47",
-"s. c #CB5049",
-"t. c #CB4F48",
-"u. c #CC5049",
-"v. c #CD5049",
-"w. c #CD4F48",
-"x. c #CE5049",
-"y. c #CE4F48",
-"z. c #CC4F48",
-"A. c #C74F49",
-"B. c #BD3932",
-"C. c #E9BAB7",
-"D. c #D1CDCD",
-"E. c #ECEBEB",
-"F. c #B6241C",
-"G. c #BE362F",
-"H. c #C84D47",
-"I. c #D97B76",
-"J. c #DF908B",
-"K. c #CF4F48",
-"L. c #D04F48",
-"M. c #D97A75",
-"N. c #C74D47",
-"O. c #B5241C",
-"P. c #FBFBFB",
-"Q. c #CA5953",
-"R. c #B7241C",
-"S. c #BD3028",
-"T. c #C94E47",
-"U. c #DB7B76",
-"V. c #FCF6F5",
-"W. c #FDFAFA",
-"X. c #E09692",
-"Y. c #D15049",
-"Z. c #D25049",
-"`. c #D24F48",
-" + c #D34F48",
-".+ c #D35049",
-"++ c #D14F48",
-"@+ c #E49A96",
-"#+ c #FEFBFB",
-"$+ c #FBF4F4",
-"%+ c #D87873",
-"&+ c #CA4F49",
-"*+ c #C84E47",
-"=+ c #BC3028",
-"-+ c #E7B0AD",
-";+ c #B9241C",
-">+ c #BC2920",
-",+ c #C74841",
-"'+ c #CF5049",
-")+ c #DC7E78",
-"!+ c #FBF0F0",
-"~+ c #FFFFFF",
-"{+ c #E1928E",
-"]+ c #D4514A",
-"^+ c #D44F48",
-"/+ c #D55049",
-"(+ c #D54F48",
-"_+ c #D45049",
-":+ c #E59691",
-"<+ c #F9EFEE",
-"[+ c #BB2820",
-"}+ c #B8241C",
-"|+ c #E2E0E0",
-"1+ c #FBF3F2",
-"2+ c #C64740",
-"3+ c #BA241C",
-"4+ c #C43C34",
-"5+ c #DC7B76",
-"6+ c #FCF9F8",
-"7+ c #E2928E",
-"8+ c #D74F48",
-"9+ c #D84F48",
-"0+ c #E79691",
-"a+ c #FDF9F9",
-"b+ c #D97873",
-"c+ c #C33C34",
-"d+ c #E7AEAA",
-"e+ c #BB241C",
-"f+ c #BF2C23",
-"g+ c #CC4D46",
-"h+ c #D05049",
-"i+ c #DE7B76",
-"j+ c #E59592",
-"k+ c #DB4F49",
-"l+ c #DB4E48",
-"m+ c #EA9996",
-"n+ c #DA7873",
-"o+ c #CB4D46",
-"p+ c #E7AEAB",
-"q+ c #CE5750",
-"r+ c #BF251B",
-"s+ c #C73D35",
-"t+ c #E48F8B",
-"u+ c #E5928E",
-"v+ c #DD504A",
-"w+ c #DD4E48",
-"x+ c #DD4F49",
-"y+ c #EA9591",
-"z+ c #FCFAF9",
-"A+ c #C37671",
-"B+ c #C84740",
-"C+ c #BE251C",
-"D+ c #CD5750",
-"E+ c #F4D9D8",
-"F+ c #C12D25",
-"G+ c #D0281C",
-"H+ c #CE4C44",
-"I+ c #D75049",
-"J+ c #E39592",
-"K+ c #FDF9F8",
-"L+ c #E7928E",
-"M+ c #E04E48",
-"N+ c #E04F49",
-"O+ c #EC9592",
-"P+ c #FEF9F9",
-"Q+ c #C57F7B",
-"R+ c #AB2E27",
-"S+ c #D14C45",
-"T+ c #D0271D",
-"U+ c #C02D25",
-"V+ c #EFEEEE",
-"W+ c #E5A39F",
-"X+ c #C3251B",
-"Y+ c #DC3528",
-"Z+ c #D95348",
-"`+ c #D64F48",
-" @ c #D94F48",
-".@ c #E4918D",
-"+@ c #FCF8F8",
-"@@ c #E89691",
-"#@ c #EE9A95",
-"$@ c #FEFBFA",
-"%@ c #FBF8F8",
-"&@ c #C27A75",
-"*@ c #AC2E27",
-"=@ c #D74D47",
-"-@ c #D85248",
-";@ c #DB3428",
-">@ c #C2251B",
-",@ c #F6F5F5",
-"'@ c #D76F69",
-")@ c #CA251B",
-"!@ c #DF4234",
-"~@ c #E15847",
-"{@ c #D65148",
-"]@ c #D84F49",
-"^@ c #DA4F49",
-"/@ c #DE504A",
-"(@ c #E7918D",
-"_@ c #AF312A",
-":@ c #D84C45",
-"<@ c #E15647",
-"[@ c #DF4034",
-"}@ c #C9251B",
-"|@ c #D7706A",
-"1@ c #CC4139",
-"2@ c #D0271C",
-"3@ c #E04B3D",
-"4@ c #E35A47",
-"5@ c #DF5847",
-"6@ c #DC4F49",
-"7@ c #DE4F49",
-"8@ c #DF4E48",
-"9@ c #E14F49",
-"0@ c #E25048",
-"a@ c #E8968F",
-"b@ c #AE2F27",
-"c@ c #DC4C45",
-"d@ c #DF4F49",
-"e@ c #DE5747",
-"f@ c #E35847",
-"g@ c #E0493D",
-"h@ c #CF261C",
-"i@ c #DCD6D6",
-"j@ c #E3E3E2",
-"k@ c #C7281F",
-"l@ c #D4291E",
-"m@ c #E15142",
-"n@ c #E25B46",
-"o@ c #E35F46",
-"p@ c #DE5647",
-"q@ c #DC4E48",
-"r@ c #DE4E48",
-"s@ c #E14F48",
-"t@ c #E25045",
-"u@ c #DF4435",
-"v@ c #DC3320",
-"w@ c #E48275",
-"x@ c #AC251B",
-"y@ c #DD4134",
-"z@ c #E14E46",
-"A@ c #E35D46",
-"B@ c #E25947",
-"C@ c #E14F42",
-"D@ c #C5281F",
-"E@ c #FCF3F3",
-"F@ c #C7251C",
-"G@ c #D72B1F",
-"H@ c #E25445",
-"I@ c #E35C47",
-"J@ c #E35F47",
-"K@ c #E46247",
-"L@ c #E05448",
-"M@ c #E14B3F",
-"N@ c #DD3827",
-"O@ c #DC311B",
-"P@ c #DC321A",
-"Q@ c #DC361B",
-"R@ c #E58575",
-"S@ c #AE291C",
-"T@ c #D7301A",
-"U@ c #DC301B",
-"V@ c #DD3727",
-"W@ c #E14A3F",
-"X@ c #DF5448",
-"Y@ c #E36147",
-"Z@ c #E35E47",
-"`@ c #E25245",
-" # c #D72A1F",
-".# c #C6251C",
-"+# c #FCF4F3",
-"@# c #E4E4E4",
-"## c #F8E1DF",
-"$# c #C9251C",
-"%# c #D92D20",
-"&# c #E25646",
-"*# c #E36047",
-"=# c #E46446",
-"-# c #E46546",
-";# c #E35647",
-"># c #E0483A",
-",# c #DC331F",
-"'# c #DC311A",
-")# c #DB3419",
-"!# c #DC3719",
-"~# c #DC3919",
-"{# c #DC3B19",
-"]# c #E68D7A",
-"^# c #FCFAFA",
-"/# c #AD291A",
-"(# c #D83719",
-"_# c #DC361A",
-":# c #DB3319",
-"<# c #DC301A",
-"[# c #DC311F",
-"}# c #E0463A",
-"|# c #E35547",
-"1# c #E46447",
-"2# c #E36246",
-"3# c #E25447",
-"4# c #D82B20",
-"5# c #C8251C",
-"6# c #F8E0DF",
-"7# c #CB241B",
-"8# c #E25C46",
-"9# c #E36046",
-"0# c #E46746",
-"a# c #E35B34",
-"b# c #DD3A1B",
-"c# c #DB3219",
-"d# c #DC3519",
-"e# c #DC3819",
-"f# c #DD3D18",
-"g# c #DD3F18",
-"h# c #EC917A",
-"i# c #FEFAF9",
-"j# c #CE837A",
-"k# c #DB3D18",
-"l# c #DD3C18",
-"m# c #DC3A19",
-"n# c #DC3419",
-"o# c #DB311A",
-"p# c #DD381C",
-"q# c #E25A34",
-"r# c #E46646",
-"s# c #E35E46",
-"t# c #E25A46",
-"u# c #E25547",
-"v# c #D92C20",
-"w# c #CA251C",
-"x# c #E3E2E2",
-"y# c #CD241C",
-"z# c #D92B1F",
-"A# c #E46346",
-"B# c #E25B37",
-"C# c #DF481A",
-"D# c #DF4817",
-"E# c #DE4218",
-"F# c #DD3B19",
-"G# c #DD3C19",
-"H# c #DE421A",
-"I# c #EB8D74",
-"J# c #FDFAF9",
-"K# c #E68A74",
-"L# c #DD3E19",
-"M# c #DE4018",
-"N# c #DE4717",
-"O# c #DF471A",
-"P# c #E25937",
-"Q# c #E25345",
-"R# c #D82A1F",
-"S# c #CB251C",
-"T# c #D0271F",
-"U# c #D8291E",
-"V# c #E35B47",
-"W# c #E35C3E",
-"X# c #DE441C",
-"Y# c #DE4518",
-"Z# c #DF4917",
-"`# c #DF4D16",
-" $ c #DE4517",
-".$ c #EB8F74",
-"+$ c #FEF9F8",
-"@$ c #FDF8F8",
-"#$ c #E68B74",
-"$$ c #DE4118",
-"%$ c #DE4417",
-"&$ c #DF4B16",
-"*$ c #DE4418",
-"=$ c #DE431C",
-"-$ c #E25A3E",
-";$ c #E35947",
-">$ c #E15042",
-",$ c #D8281E",
-"'$ c #CF271F",
-")$ c #E9E8E8",
-"!$ c #FBFAFA",
-"~$ c #D84039",
-"{$ c #D7261C",
-"]$ c #E14C3D",
-"^$ c #E35C43",
-"/$ c #DE4422",
-"($ c #DD4018",
-"_$ c #DE4817",
-":$ c #DF4C16",
-"<$ c #E05015",
-"[$ c #E05314",
-"}$ c #ED9A78",
-"|$ c #E79678",
-"1$ c #E05214",
-"2$ c #DF4E16",
-"3$ c #DF4A17",
-"4$ c #DE4318",
-"5$ c #DE4223",
-"6$ c #E25A44",
-"7$ c #E25847",
-"8$ c #E14A3D",
-"9$ c #D6261C",
-"0$ c #D74039",
-"a$ c #E26F69",
-"b$ c #D6251B",
-"c$ c #DF4334",
-"d$ c #E04B31",
-"e$ c #DD4019",
-"f$ c #DF4718",
-"g$ c #E05018",
-"h$ c #EC9772",
-"i$ c #FEFBF9",
-"j$ c #E79273",
-"k$ c #DF4E18",
-"l$ c #DE4617",
-"m$ c #E04931",
-"n$ c #E35747",
-"o$ c #DF4134",
-"p$ c #D5241B",
-"q$ c #E16F69",
-"r$ c #EDA29F",
-"s$ c #D7241B",
-"t$ c #DD3629",
-"u$ c #E25342",
-"v$ c #DD381E",
-"w$ c #DE4618",
-"x$ c #DE4917",
-"y$ c #EC9373",
-"z$ c #CF887A",
-"A$ c #E68F73",
-"B$ c #DD371E",
-"C$ c #E25142",
-"D$ c #DD3529",
-"E$ c #D5241C",
-"F$ c #ECA39F",
-"G$ c #F7D9D7",
-"H$ c #D92C25",
-"I$ c #DB291C",
-"J$ c #DE3F2E",
-"K$ c #EC9579",
-"L$ c #C27A76",
-"M$ c #AE3317",
-"N$ c #E05D12",
-"O$ c #E89A71",
-"P$ c #E79179",
-"Q$ c #DD4218",
-"R$ c #DB301A",
-"S$ c #DE3D2E",
-"T$ c #DA271D",
-"U$ c #D82C25",
-"V$ c #E25750",
-"W$ c #DA271B",
-"X$ c #DB2B1B",
-"Y$ c #DD3A19",
-"Z$ c #DD3F19",
-"`$ c #EA876D",
-" % c #C37A76",
-".% c #B0351A",
-"+% c #DD5913",
-"@% c #E25D12",
-"#% c #E25D14",
-"$% c #E89872",
-"%% c #E3836D",
-"&% c #DC3D19",
-"*% c #DB2E1A",
-"=% c #DB2A1B",
-"-% c #DA251B",
-";% c #E15650",
-">% c #F1AEAA",
-",% c #DA291A",
-"'% c #DB2D1A",
-")% c #E66F51",
-"!% c #FBF4F3",
-"~% c #AE3118",
-"{% c #DD5513",
-"]% c #E15913",
-"^% c #E25913",
-"/% c #E25813",
-"(% c #E15713",
-"_% c #E89978",
-":% c #FAF3F3",
-"<% c #B55953",
-"[% c #CD3419",
-"}% c #DC3619",
-"|% c #DB2B1A",
-"1% c #DB281B",
-"2% c #F1AEAB",
-"3% c #FCF3F2",
-"4% c #E14D3F",
-"5% c #E26D51",
-"6% c #FAEEEC",
-"7% c #AE2F18",
-"8% c #DE5314",
-"9% c #E05513",
-"0% c #E05613",
-"a% c #E05514",
-"b% c #E05414",
-"c% c #E79373",
-"d% c #F6EDEC",
-"e% c #B35853",
-"f% c #B92D19",
-"g% c #DB3719",
-"h% c #DB291A",
-"i% c #E04C3F",
-"j% c #F7F6F6",
-"k% c #F2B3AD",
-"l% c #DB2C1A",
-"m% c #E37055",
-"n% c #AF311B",
-"o% c #DB4D15",
-"p% c #E05115",
-"q% c #E05215",
-"r% c #DF4F18",
-"s% c #E69074",
-"t% c #B55C56",
-"u% c #B82D19",
-"v% c #DB3819",
-"w% c #DC341A",
-"x% c #DB2A1A",
-"y% c #F1B3AD",
-"z% c #E46452",
-"A% c #DA2A1A",
-"B% c #AD2C19",
-"C% c #DA4817",
-"D% c #E6917A",
-"E% c #DB3919",
-"F% c #DB3519",
-"G% c #E46352",
-"H% c #F9E3E0",
-"I% c #E04C30",
-"J% c #DC331A",
-"K% c #C4756E",
-"L% c #AD2B19",
-"M% c #DC4518",
-"N% c #DE4A17",
-"O% c #DF4717",
-"P% c #DC351A",
-"Q% c #DC3319",
-"R% c #E04A30",
-"S% c #E5E3E2",
-"T% c #F3BFB6",
-"U% c #DE4421",
-"V% c #D03819",
-"W% c #D93E19",
-"X% c #DD4118",
-"Y% c #DE4221",
-"Z% c #EAE8E8",
-"`% c #F1B2A4",
-" & c #DE4019",
-".& c #DD3919",
-"+& c #F1B1A4",
-"@& c #F1B3A4",
-"#& c #E04B20",
-"$& c #DD3B18",
-"%& c #DC3C18",
-"&& c #DD3E18",
-"*& c #DC3B18",
-"=& c #DD3A18",
-"-& c #DF4A20",
-";& c #EEEDED",
-">& c #FEFDFD",
-",& c #F4C2B5",
-"'& c #E25A2E",
-")& c #DC3119",
-"!& c #DB2F1A",
-"~& c #DC3019",
-"{& c #DE4317",
-"]& c #E2582E",
-"^& c #FAE5DF",
-"/& c #E7754F",
-"(& c #DE4017",
-"_& c #DE3F17",
-":& c #E6744F",
-"<& c #F3BDAC",
-"[& c #E56C3B",
-"}& c #DF4516",
-"|& c #DC3518",
-"1& c #DA2B1A",
-"2& c #DE4516",
-"3& c #E46A3C",
-"4& c #E1DFDE",
-"5& c #FCF4F2",
-"6& c #F3BDA9",
-"7& c #E77B4B",
-"8& c #E35E1C",
-"9& c #E15513",
-"0& c #E04B15",
-"a& c #DE4116",
-"b& c #DD3918",
-"c& c #DC3418",
-"d& c #DC3219",
-"e& c #DF4116",
-"f& c #E15413",
-"g& c #E25D1D",
-"h& c #DDDADA",
-"i& c #F9E0D7",
-"j& c #F2B69C",
-"k& c #EB9164",
-"l& c #E56D31",
-"m& c #E35E15",
-"n& c #E35F12",
-"o& c #E26011",
-"p& c #E25E15",
-"q& c #FCF5F2",
-"r& c #FAE4DE",
-"s& c #E2E1E0",
-"t& c #E5E3E3",
-"u& c #E0DFDE",
-"v& c #E9E9E8",
-" . + @ # $ % & * ",
-" = - ; > , ' ) ! ! ~ { ] ^ / ( _ ",
-" : < [ } | | | | 1 2 3 1 | | | 4 5 6 7 8 ",
-" 9 > 0 a b c d e f g h h h h i f e j c b | ' k % ",
-" l m 5 | n o p q r r s t u v w u t s r x q p y n 4 [ z A ",
-" B C 4 | D E F G H I J K L M N N M L O J P Q G R E S | } ^ & ",
-" T 5 a U V W W X Y Z ` ` ..... ..... ...` +.Z @.X G G #.U | $.%. ",
-" &.0 | *.=.-.;.>.,.'.'.).).!.~.~.!.{.~.!.).).].^.'.,./.(.W _.*.| :.<. ",
-" [.0 | }.|.1.2.3.].!.4.4.5.6.7.7.7.8.8.7.7.7.5.5.4.!.].].9.2.0.|.}.| :.%. ",
-" a.0 | b.c.d.e.f.{.5.g.h.8.i.i.j.i.i.j.i.i.j.i.i.8.h.g.g.5.{.f.k.d.1.b.b $.& ",
-" l.m.a n.o.p.q.r.7.h.8.i.s.t.u.v.w.v.x.y.x.v.w.v.u.z.s.i.i.8.h.A.r.B.p.o.C.| ^ D. ",
-" E.| U q.F.G.H.8.j.t.t.I.J.y.K.K.K.L.L.L.L.L.L.K.K.y.y.J.M.t.j.j.8.N.G.O.B.U } z ",
-" z P.| Q.R.S.T.i.s.z.x.U.V.W.X.Y.Z.`.Z.Z. +.+Z.`.Z.Z.++@+#+$+%+v.u.j.&+*+=+R.Q.| [ % ",
-" , | -+;+>+,+s.u.x.'+)+!+~+~+W.{+]+^+/+/+(+/+/+(+_+]+:+#+~+~+<+I.'+w.u.i.,+[+}+-+4 k ",
-" |+4 1+2+3+4+z.y.K.L.5+!+a a a a 6+7+8+9+9+9+9+9+9+8+0+a+a a a a <+b+K.y.w.t.c+3+2+1+' 8 ",
-" 6 a d+e+f+g+y.h+Y.i+V.~+a ~+~+a ~+W.j+k+k+l+k+k+l+m+#+a ~+~+~+a ~+$+n+h+'+y.o+f+3+p+| 7 ",
-" a.0 b q+r+s+K.L.Z..+t+W.~+a ~+~+a ~+~+W.u+v+w+x+v+y+#+~+a ~+~+~+a ~+z+A+B+Y.K.y.s+C+D+b 6 _ ",
-" k | E+F+G+H+Y.`._+/+I+J+W.a ~+~+a ~+~+a K+L+M+N+O+P+~+~+a ~+~+~+a z+Q+R+S+.+`.h+H+T+U+E+5 ( ",
-" V+| W+X+Y+Z+ +^+`+9+ @l+.@+@a a a a a a a W.@@#@$@a a a a a a a %@&@*@=@8+(+^+`.-@;@>@W+4 / ",
-" ,@| '@)@!@~@{@`+]@^@k+w+/@(@W.~+a ~+~+a ~+~+W.$@~+a ~+~+a ~+~+z+&@_@:@l+^@]@`+{@<@[@}@|@| ^ ",
-"< 0 | 1@2@3@4@5@ @k+6@7@8@9@0@a@W.a ~+~+a ~+~+a ~+~+a ~+~+a ~+z+Q+b@c@d@w+k+^@9+e@f@g@h@1@| ] i@",
-"j@4 | k@l@m@n@o@p@q@r@M+s@t@u@v@w@+@a a a a a a a a a a a a +@&@x@y@z@s@8@r@q@p@A@B@C@l@D@| { & ",
-"7 4 E@F@G@H@I@J@K@L@s@0@M@N@O@P@Q@R@W.~+a ~+~+a ~+~+a ~+~+z+&@S@T@U@V@W@s@N+X@Y@Z@4@`@ #.#+#~ % ",
-"@#| ##$#%#&#I@*#=#-#;#>#,#'#)#!#~#{#]#W.a ~+~+a ~+~+a ~+^#Q+/#(#_#:#<#[#}#|#1#2#Z@4@3#4#5###! $ ",
-"; 4 6#7#%##9#=#0#a#b#c#d#e#{#f#g#h#i#a a a a a a a a z+j#k#l#m#!#n#o#p#q#r#2#s#t#u#v#w#6#! # ",
-"x#4 E@y#z#H@I@*#A#B#C#D#E#F#G#g#H#I#i#~+a ~+~+a ~+~+a ~+~+J#K#H#L#{#~#M#N#O#P#2#Z@4@Q#R#S#E@) @ ",
-"; 4 | T#U#m@V#o@W#X#Y#Z#`#`# $E#.$+$~+~+a ~+~+a ~+~+a ~+~+a @$#$$$%$&$&$N#*$=$-$s#;$>$,$'$| ' = ",
-")$!$| ~${$]$t#^$/$($*$_$:$<$[$}$i#a a a a a a a a a a a a a a J#|$1$2$3$N#4$g#5$6$7$8$9$0$| , . ",
-" ) | a$b$c$;$d$F#e$4$f$3$g$h$i$~+a ~+~+a ~+~+z+^#~+a ~+~+a ~+~+J#j$k$Z#l$$$L#~#m$n$o$p$q$| > ",
-" , | r$s$t$u$v$~#L#E#w$x$y$+$~+~+a ~+~+a ~+^#Q+z$J#a ~+~+a ~+~+~+K+A$D#*$M#G#!#B$C$D$E$F$| ; ",
-" ^ | G$H$I$J$c#!#l#($*$K$i#a a a a a a a +@L$M$N$O$6+a a a a a a a J#P$Q$g#m#d#R$S$T$U$G$} - ",
-" &.P.b V$W$X$R$d#Y$Z$`$i#~+a ~+~+a ~+~+z+ %.%+%@%#%$%J#~+a ~+~+~+a ~+J#%%&%e#:#*%=%-%;%b [ = ",
-" m.a >%,%=%'%:#e#G#)%!%~+a ~+~+a ~+^#Q+~%{%]%^%/%(%_%J#a ~+~+~+a ~+:%<%[%}%o#|%1%W$2%a < ",
-" m | 3%4%'%|%R$d#~#f#5%6%a a a a +@L$7%8%9%0%9%a%b%[$c%6+a a a a d%e%f%g%:#*%h%|%i%3%0 : ",
-" j%a k%P@|%l%P@}%Y$L#m%6%~+~+z+ %n%o%p%q%1$q%q%p%<$r%s%W.~+~+d%t%u%v%w%R$|%x%<#y%| > ",
-" < | | z%w%A%*%:#!#m#L#5%!%z+Q+B%C%:$`#2$2$2$`#:$&$3$_$D%J#:%e%u%E%F%o#l%,%P@G%| 5 9 ",
-" :.| H%I%n#x%*%J%!#Y$f#5%K%L%M%f$_$Z#Z#N%3$Z#_$O%f$Y#4$%%<%f%v%P%o#'%h%Q%R%H%4 m ",
-" S%0 a T%U%n#|%*%:#}%~#G#V%W%E#4$*$Y#w$l$w$w$Y#*$E#X%e$&%[%g%d#'#'%x%P@Y%T%a C l ",
-" Z%4 | `%X%}%x%*%P@d#e#Y$l#L#e$($$$E#Q$E#$$X% &Z$f#F#.&}%)#R$l%h%n#e$+&| 5 B ",
-" > 4 | @&#&$&|%l%R$:#d#!#~#m#%&f#f#&&&&f#%&*&m#~#!#n#c#*%|%x%=&-&@&| 0 T ",
-" ;&4 >&,&'&%$)&|%'%R$c#w%}%!#e#e#~#~#e#e#!#d#n#P@!&l%x%~&{&]&,&>&0 &. ",
-" > 4 a ^&/&2$(&*%|%'%!&'#c#J%J%)#w%J%:#'#R$*%l%=%'%_&:$:&^&a 0 [. ",
-" Z%0 | | <&[&b%}&|&|%1&1&l%'%'%'%'%l%1&A%|%|&2&[$3&<&| | m.4& ",
-" S%:.| a 5&6&7&8&9&0&a&b&c&d&)&c&b&e&0&f&g&7&6&5&| P.E.h& ",
-" < j%| a b i&j&k&l&m&n&o&n&n&p&l&k&j&i&b a 4 , z ",
-" m m.P.| | | | | q&r&r&5&| | | | | 0 6 s& ",
-" t&^ , ) !$4 4 4 | 4 4 0 ,@V+k u& ",
-" v&; x#; @#7 j@< "};
+++ /dev/null
-/* XPM */
-static const char * save_xpm[] = {
-"20 20 107 2",
-" c #FFFFFF",
-". c #E4E4FB",
-"+ c #C2C2F5",
-"@ c #ACABEF",
-"# c #A2A1EA",
-"$ c #9B9AE7",
-"% c #9493E4",
-"& c #8F8EE0",
-"* c #8D8CDE",
-"= c #A1A0E3",
-"- c #D1D1F1",
-"; c #DBDBFF",
-"> c #9392F8",
-", c #F6F8FB",
-"' c #4B58BE",
-") c #A4A3D4",
-"! c #E2E2FA",
-"~ c #BEBDFF",
-"{ c #8A89EF",
-"] c #EAEEF6",
-"^ c #3F52B8",
-"/ c #333367",
-"( c #C4C4E1",
-"_ c #BDBCF2",
-": c #8180E6",
-"< c #DEE5F0",
-"[ c #344DB3",
-"} c #7A79DF",
-"| c #7E7DBB",
-"1 c #A3A2EA",
-"2 c #7776DC",
-"3 c #D2DBEA",
-"4 c #2847AD",
-"5 c #7271D7",
-"6 c #5857A3",
-"7 c #9897E5",
-"8 c #6E6DD3",
-"9 c #C6D1E5",
-"0 c #1C41A7",
-"a c #6767CC",
-"b c #4D4D9A",
-"c c #9291E2",
-"d c #6766CC",
-"e c #BDCAE1",
-"f c #113BA1",
-"g c #5C5DC2",
-"h c #4A4A94",
-"i c #8B8ADF",
-"j c #BCBBFF",
-"k c #B7B6FF",
-"l c #6063C9",
-"m c #565EC4",
-"n c #5C5DC1",
-"o c #5456BA",
-"p c #47478F",
-"q c #8483DB",
-"r c #B4B3FF",
-"s c #AEADFF",
-"t c #A4A3FC",
-"u c #8F8EF4",
-"v c #8786EC",
-"w c #6C6BD1",
-"x c #4C50B2",
-"y c #444489",
-"z c #8281D9",
-"A c #AAA9FF",
-"B c #A09FFB",
-"C c #9493F5",
-"D c #4B5B71",
-"E c #526276",
-"F c #5B6A7D",
-"G c #4C4FB2",
-"H c #4449AA",
-"I c #494988",
-"J c #9898DF",
-"K c #A09FFF",
-"L c #9190F5",
-"M c #000000",
-"N c #343C47",
-"O c #CED9E9",
-"P c #D4DDEC",
-"Q c #677485",
-"R c #434BAE",
-"S c #3C42A3",
-"T c #6E6E9E",
-"U c #CDCDEF",
-"V c #9A99FF",
-"W c #68788D",
-"X c #D8E0ED",
-"Y c #E0E7F1",
-"Z c #737F8F",
-"` c #3541A3",
-" . c #3C42A2",
-".. c #353D9C",
-"+. c #BBBBD0",
-"@. c #C2C1F8",
-"#. c #2444AA",
-"$. c #213247",
-"%. c #ABB4C3",
-"&. c #B3BBC6",
-"*. c #BCC1CA",
-"=. c #C4C8CE",
-"-. c #484D56",
-";. c #333E9E",
-">. c #363D9C",
-",. c #8E92C6",
-"'. c #6D6C9A",
-" ",
-" ",
-" ",
-" . + @ # $ % & * = - ",
-" ; > , ' ) ",
-" ! ~ { , ] ^ / ( ",
-" _ ~ : , ] < [ } | ",
-" 1 ~ 2 , ] < 3 4 5 6 ",
-" 7 ~ 8 , ] < 3 9 0 a b ",
-" c ~ d , ] < 3 9 e f g h ",
-" i j k l m ' ^ [ 4 0 f n o p ",
-" q r s t u v : } 5 w n o x y ",
-" z A B C D D D D E F o G H I ",
-" J K L v D M N O P Q R H S T ",
-" U V v : D N W X Y Z ` ...+. ",
-" @.: #.$.%.&.*.=.-.;.>.,. ",
-" ( | 6 b h p y I '.+. ",
-" ",
-" ",
-" "};
+++ /dev/null
-/* XPM */
-static const char *settings_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"40 40 69 1",
-" c #474A4A",
-". c #494D4D",
-"X c #575B5B",
-"o c #5B5F5F",
-"O c #5D6262",
-"+ c #626565",
-"@ c #656969",
-"# c #696D6D",
-"$ c #6D7171",
-"% c #727777",
-"& c #757A7A",
-"* c #7A7E7E",
-"= c #7C8282",
-"- c #828787",
-"; c #858A8A",
-": c #898E8E",
-"> c #818E92",
-", c #859295",
-"< c #8C9292",
-"1 c #899699",
-"2 c #8D999C",
-"3 c #919696",
-"4 c #949A9B",
-"5 c #9A9E9E",
-"6 c #949FA1",
-"7 c #999FA0",
-"8 c #95A2A4",
-"9 c #9CA3A3",
-"0 c #99A6A9",
-"q c #9DAAAD",
-"w c #A1A6A6",
-"e c #A4AAAB",
-"r c #A9ADAD",
-"t c #A2AEB1",
-"y c #A5B2B4",
-"u c #ABB2B3",
-"i c #ACB7B9",
-"p c #AEBABC",
-"a c #B1B6B6",
-"s c #B4BBBC",
-"d c #BABEBE",
-"f c #B4BEC0",
-"g c #B8BFC0",
-"h c #B6C1C3",
-"j c #BBC3C4",
-"k c #BBC6C8",
-"l c #BEC9CB",
-"z c #C2C5C5",
-"x c #C5CBCB",
-"c c #CACDCD",
-"v c #C3CED0",
-"b c #C6D1D3",
-"n c #CCD3D4",
-"m c #CCD7D9",
-"M c #CED9DB",
-"N c #D2D5D5",
-"B c #D5DADB",
-"V c #DBDDDD",
-"C c #D5DFE0",
-"Z c #D7E1E3",
-"A c #DDE1E1",
-"S c #E2E5E5",
-"D c #E5E8E8",
-"F c #EAEDED",
-"G c #EEF1F1",
-"H c #F3F5F5",
-"J c #F6F9F9",
-"K c #FAFBFB",
-"L c None",
-/* pixels */
-"LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLLLihlbmxLLLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLLLhbmVANLLLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLLLlmCSSVdLLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLLjmAAASAzLLLLLLLLLLLLLLLL",
-"LLLLLLLL80eLLLLkbVSSSSSVcLLLLxVVLLLLLLLL",
-"LLLLLL8880yiihMCAAAVBASSSSccBDDDScLLLLLL",
-"LLLLLL68qyphlnZANhewwrdNSSSSDDDDDSzLLLLL",
-"LLLLL40qypklmndw<;------5dVDDDDDDDaLLLLL",
-"LLLLL<tyfhlbzw<<3:;;;;;;;:rNDDDDDV-LLLLL",
-"LLLLLL4pkxmh<::3raaw53<;<<3wNDDDSrLLLLLL",
-"LLLLLL=uvmj6<:<9VDVVNNcu37wwaNDDn-LLLLLL",
-"LLLLLLLkmn53<<rNDDNzaarjzrrrrdSDBrLLLLLL",
-"LLLLLLsmMs444wcVKJxw55-*5arraaNSSxLLLLLL",
-"LLLLLLbCxw55wsrxjLLLLLL@#&aaaszVDVLLLLLL",
-"LLLLsjVAdw99r54;LLLLLLLLO+<addzNDSNnLLLL",
-"LrhbNVSVrwee5&LLLLLLLLLLLL%wdzzcDDDDAAhL",
-"LibmAAANurra*+LLLLLLLLLLLL@3zzccDDDDDZkL",
-"LsBZASSNauas+LLLLLLLLLLLLLL*ccccAFDAZMpL",
-"LsAAAAAcaaaa+LLLLLLLLLLLLLL&ccNcADAZMbyL",
-"LdAASVSNaddd+LLLLLLLLLLLLLL*NNNcSAZMlkeL",
-"LwNVASAVazdd&LLLLLLLLLLLLLL3NVNcZZmlkf4L",
-"L#*:rdAAazzze$LLLLLLLLLLLL&aVVNcMbdy9=@L",
-"LLLL$-VAzzccz;LLLLLLLLLLLL5NVAccbl<*LLLL",
-"LLLLLLdANacNVc:LLLLLLLLLL5VSSVdzksLLLLLL",
-"LLLLLL4VSazVVScrLLLLLLLLsNSDSchjp5LLLLLL",
-"LLLLLL:cVSaNSSSSnzLLLLxNDDDDnfgpy=LLLLLL",
-"LLLLLLdBSSNaVSDDDSASFGFFDDDNsgiyq4LLLLLL",
-"LLLLLLVSSVVSdcSDDFFFHJHGDAxffiq068LLLLLL",
-"LLLLLcSVVSSVVczNDFDHHJHGBlffyt06216LLLLL",
-"LLLLLzVVSVVSSVVNzcBSGHGClhfy0861,>,LLLLL",
-"LLLL+-BSVVSVNVVSVVNVSFZmffyy061,>1%LLLLL",
-"LLLLL.-zVVx4o:xNVAAAZZBliy:O;21>2= LLLLL",
-"LLLLLL+5Bz:oL+:<cVCBmMmk;=XLO:q04#LLLLLL",
-"LLLLLLL:a:LLLLLLeVMbllbqLLLLLLea%LLLLLLL",
-"LLLLLLLLLLLLLLLL4bxkhpk4LLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLL;ghpyqs9LLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLLLeshshxLLLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLLL#4ryzNLLLLLLLLLLLLLLLLL",
-"LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
-};
+++ /dev/null
-/* XPM */
-static const char *synchronize_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"48 50 155 2",
-" c #2FBF25",
-". c #32BF28",
-"X c #37BF2D",
-"o c #38BF2E",
-"O c #39A631",
-"+ c #3ABF31",
-"@ c #3BBE32",
-"# c #41B339",
-"$ c #47B13F",
-"% c #42BF39",
-"& c #2BC81F",
-"* c #2AE01D",
-"= c #29E31C",
-"- c #2AE31C",
-"; c #2AE21D",
-": c #2CE21F",
-"> c #2BE41D",
-", c #2AE61C",
-"< c #2BE41E",
-"1 c #27E819",
-"2 c #26ED18",
-"3 c #28EB19",
-"4 c #28EC1A",
-"5 c #29ED1B",
-"6 c #2AED1B",
-"7 c #2AE81D",
-"8 c #2BEB1D",
-"9 c #2DE91F",
-"0 c #2CEA1E",
-"q c #2DEA1F",
-"w c #2AEF1C",
-"e c #2BEF1D",
-"r c #2CEF1D",
-"t c #2CED1E",
-"y c #2CEE1E",
-"u c #2DEE1F",
-"i c #25F116",
-"p c #25F616",
-"a c #25F716",
-"s c #26F616",
-"d c #25F815",
-"f c #25F915",
-"g c #25FA15",
-"h c #24FB15",
-"j c #25FB15",
-"k c #25F816",
-"l c #26F816",
-"z c #26F916",
-"x c #27F917",
-"c c #25FB16",
-"v c #26FA16",
-"b c #26FB16",
-"n c #26FA17",
-"m c #27FA17",
-"M c #26FB17",
-"N c #24FD14",
-"B c #24FC15",
-"V c #25FC15",
-"C c #24FD15",
-"Z c #25FD15",
-"A c #24FE14",
-"S c #24FF14",
-"D c #24FE15",
-"F c #25FD16",
-"G c #26FC16",
-"H c #27F318",
-"J c #27F419",
-"K c #28F019",
-"L c #28F119",
-"P c #29F01A",
-"I c #28F519",
-"U c #28F619",
-"Y c #28F719",
-"T c #29F51A",
-"R c #29F71A",
-"E c #2AF61B",
-"W c #2BF11D",
-"Q c #2DF01E",
-"! c #2BF41D",
-"~ c #2BF61D",
-"^ c #27FA18",
-"/ c #28F818",
-"( c #28F919",
-") c #28FA19",
-"_ c #2CC321",
-"` c #2DC122",
-"' c #2DC222",
-"] c #2FC424",
-"[ c #34C22A",
-"{ c #35C32A",
-"} c #37C12C",
-"| c #34CD29",
-" . c #35CD29",
-".. c #34CE29",
-"X. c #37C82C",
-"o. c #39CD2F",
-"O. c #2ED622",
-"+. c #2FD623",
-"@. c #2EDC21",
-"#. c #2EDE21",
-"$. c #31D625",
-"%. c #33D427",
-"&. c #30DB23",
-"*. c #31D824",
-"=. c #31DB24",
-"-. c #31DC24",
-";. c #31DF24",
-":. c #33DD26",
-">. c #33DD27",
-",. c #34DF27",
-"<. c #33D028",
-"1. c #34D028",
-"2. c #35D32A",
-"3. c #3AD02F",
-"4. c #39D22E",
-"5. c #38D52C",
-"6. c #36DF2A",
-"7. c #37DF2B",
-"8. c #3BDB2F",
-"9. c #3BCB30",
-"0. c #3CC932",
-"q. c #3BCE30",
-"w. c #3CCF32",
-"e. c #3FD434",
-"r. c #2EE021",
-"t. c #2FE222",
-"y. c #2DE420",
-"u. c #2DE620",
-"i. c #2DE720",
-"p. c #2EE721",
-"a. c #2FE522",
-"s. c #2DEA20",
-"d. c #30E023",
-"f. c #30E123",
-"g. c #31E024",
-"h. c #33E326",
-"j. c #31E823",
-"k. c #37E32A",
-"l. c #41C137",
-"z. c #41CB37",
-"x. c #41C038",
-"c. c #45C63C",
-"v. c #41D236",
-"b. c #42D637",
-"n. c #4BAD44",
-"m. c #50AD49",
-"M. c #4EB346",
-"N. c #49BB40",
-"B. c #4ABC41",
-"V. c #54B34D",
-"C. c #55B34E",
-"Z. c #52B94B",
-"A. c #5AB354",
-"S. c #699C65",
-"D. c None",
-/* pixels */
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.O D.D.S.A.A.A.A.V.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.e.e N S S S S O.. 4 S N N N S y v.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.8 N N S S S b ..D.D.D.o.N N N S S S P D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.@ h S S S S S Q D.D.D.D.D.D.D.S S S S S S b X D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.% S S S S S S S D.D.D.D.D.D.D.D.D.b S S S S S S { D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.b S S S S S S D.D.D.D.D.D.D.D.D.D.X.S S S S S S b D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.b S S S S S S *.D.D.D.D.D.D.D.D.D.D.D.f.S S S S S S Y D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.#.S S S S S S b D.D.D.D.D.D.D.D.D.D.D.D.D.( S S S S S S $.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.S S S S S S S z.D.D.D.D.D.D.D.D.D.D.D.D.D.b.S S S S S S b D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.- S S S S S S b D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.( S S S S S S 6.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.b S S S S S S 6.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.f.S S S S S S ^ D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.<.S S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.S S S S S S S w.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.a.S S S S S S 0 D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.e S S S S S S a.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.S S S S S S S $.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.- S S S S S S Y D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.S S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.D...s s b S S S S S S S b s s _ D.D.D.D.D.D.",
-"D.D.D.D.6.S S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.x.Y N N S S S S S S S S D.D.D.D.D.D.D.D.",
-"D.D.D.D.8 S S S S S S P D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.2 N S S S S S S b Z.D.D.D.D.D.D.D.D.",
-"D.D.D.D.;.S S S S S S 0 D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.f.S S S S N b D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.i S S S S S S -.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D...b S S b D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D., S S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.y b D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.M.B.B.B.B.B.B.$ D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.V.s.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.b f s b b s d m.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.( S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.S S S S S S S D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.` S S S S S 5.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.$ S S S S S S S D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.] b S S S S S S t.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.* S S S S S S S D.D.D.D.D.D.D.D.",
-"D.D.D.D.c.S S S S S S S S S P D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.6.S S S S S S b D.D.D.D.D.D.D.D.",
-"D.D.D.- b S S S S S S S S S S S 0.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.j.S S S S S S 4 D.D.D.D.D.D.D.D.",
-"D.D.D.` _ ` y S S S S S S b ` ` D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.Y S S S S S S #.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.4.S S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.S S S S S S S { D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.N S S S S S S f.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.$.S S S S S S S D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.4 S S S S S S W D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.J S S S S S S : D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.e.S S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.S S S S S S S D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.~ S S S S S S k.D.D.D.D.D.D.D.D.D.D.D.D.D.D.a.S S S S S S y D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.v.S S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.S S S S S S S D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.y S S S S S S s.D.D.D.D.D.D.D.D.D.D.D.D.4 S S S S S S y D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.S S S S S S S 0.D.D.D.D.D.D.D.D.D.D.$.S S S S S S Y D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.@ S S S S S S b D.D.D.D.D.D.D.D.D.} S S S S S S S # D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.& S S S S S S ~ D.D.D.D.D.D.D.n.Y S S S S S S D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.% J S S S S S Y D.D.D.D.D.1.! S S S S S P D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.3 S S S S S N *.D.D.a.N N N S S S a.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.t.8.1 1 3 > ..} - ;.2.-.;.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.",
-"D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D.D."
-};
+++ /dev/null
-/* XPM */
-static const char *tools_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"48 48 254 2",
-" c #435C69",
-". c #47606D",
-"X c #49626E",
-"o c #4B6370",
-"O c #546D7A",
-"+ c #57707D",
-"@ c #59717E",
-"# c #008636",
-"$ c #058D3A",
-"% c #0C8E3E",
-"& c #029037",
-"* c #0B933D",
-"= c #0E9B3C",
-"- c #20A23E",
-"; c #4CAE3D",
-": c #52B030",
-"> c #5DB435",
-", c #56B33D",
-"< c #7EBF25",
-"1 c #74BC2D",
-"2 c #7DBF2B",
-"3 c #73BC34",
-"4 c #78BE3B",
-"5 c #7FC028",
-"6 c #7FC136",
-"7 c #7DC03D",
-"8 c #128F41",
-"9 c #139344",
-"0 c #199346",
-"q c #119941",
-"w c #1C9B4D",
-"e c #21974D",
-"r c #20994F",
-"t c #249B53",
-"y c #2A9F57",
-"u c #1BA04A",
-"i c #29A440",
-"p c #21A04F",
-"a c #3BAA4D",
-"s c #29A256",
-"d c #2DA35A",
-"f c #3AA957",
-"g c #32A55D",
-"h c #33AA5D",
-"j c #3CAD5D",
-"k c #4EAF41",
-"l c #57B44C",
-"z c #41AC57",
-"x c #43AE5B",
-"c c #47B05C",
-"v c #4CB15D",
-"b c #5AB557",
-"n c #53B35C",
-"m c #5AB65B",
-"M c #5FB85B",
-"N c #6CBB43",
-"B c #76BF42",
-"V c #74BD49",
-"C c #66BB55",
-"Z c #6BBC54",
-"A c #64BA5B",
-"S c #6BBD5B",
-"D c #71BF5E",
-"F c #43A567",
-"G c #48A86C",
-"H c #4DB36E",
-"J c #5EB862",
-"K c #5BB76A",
-"L c #57B375",
-"P c #62BC7D",
-"I c #79C044",
-"U c #7EC150",
-"Y c #75C061",
-"T c #7AC265",
-"R c #7FC469",
-"E c #76C172",
-"W c #70C07C",
-"Q c #82C024",
-"! c #83C229",
-"~ c #8BC536",
-"^ c #83C33B",
-"/ c #85C443",
-"( c #8CC745",
-") c #87C64B",
-"_ c #8AC74B",
-"` c #8DC84D",
-"' c #96CB45",
-"] c #91C94D",
-"[ c #9BCE4E",
-"{ c #8ECA51",
-"} c #92CA50",
-"| c #95CB5B",
-" . c #98CD5D",
-".. c #82C66B",
-"X. c #99CD66",
-"o. c #9FD06C",
-"O. c #81C771",
-"+. c #8CCA75",
-"@. c #8ACA7A",
-"#. c #A2D36E",
-"$. c #ABD669",
-"%. c #5D7582",
-"&. c #5F7988",
-"*. c #5E7F91",
-"=. c #617580",
-"-. c #617986",
-";. c #647C89",
-":. c #687F8C",
-">. c #607F91",
-",. c #6B818D",
-"<. c #638495",
-"1. c #6B8694",
-"2. c #6E8897",
-"3. c #668698",
-"4. c #6C8B9C",
-"5. c #728793",
-"6. c #758A95",
-"7. c #768C9A",
-"8. c #798E9A",
-"9. c #7E929E",
-"0. c #66B881",
-"q. c #69BB82",
-"w. c #728FA0",
-"e. c #7592A4",
-"r. c #7C96A5",
-"t. c #7B98A9",
-"y. c #75C08C",
-"u. c #7AC391",
-"i. c #82939D",
-"p. c #8496A1",
-"a. c #8399A7",
-"s. c #8C9BA4",
-"d. c #819DAE",
-"f. c #8C9DA8",
-"g. c #909EA5",
-"h. c #8FA1AC",
-"j. c #93A3AD",
-"k. c #9AA7AD",
-"l. c #9BA8AF",
-"z. c #87A1B1",
-"x. c #8BA5B5",
-"c. c #93A5B0",
-"v. c #94A8B5",
-"b. c #9AA9B2",
-"n. c #93ACBB",
-"m. c #99AFBD",
-"M. c #99B0BF",
-"N. c #A2AEB4",
-"B. c #A2B2BC",
-"V. c #ABB5BB",
-"C. c #AEB8BE",
-"Z. c #B1BABF",
-"A. c #82C786",
-"S. c #97D087",
-"D. c #9BD084",
-"F. c #90CE9B",
-"G. c #A4D387",
-"H. c #B1D986",
-"J. c #B3DA8A",
-"K. c #AFD993",
-"L. c #A5D79C",
-"P. c #A7D89C",
-"I. c #ADD99D",
-"U. c #B1DA94",
-"Y. c #BADE9E",
-"T. c #90CEA2",
-"R. c #98CEA9",
-"E. c #93D1A0",
-"W. c #A0D5A6",
-"Q. c #ADD9A2",
-"!. c #B1DBA6",
-"~. c #BCDFA9",
-"^. c #A2D5B3",
-"/. c #A3D9B6",
-"(. c #ADDBB4",
-"). c #B0DABC",
-"_. c #BFE2B4",
-"`. c #C1E2AD",
-"'. c #CBE5A8",
-"]. c #CEE7B6",
-"[. c #D1E9BC",
-"{. c #9DB4C2",
-"}. c #A1B6C3",
-"|. c #A4B9C7",
-" X c #ABBAC3",
-".X c #A6BAC9",
-"XX c #ABBECD",
-"oX c #B3BDC2",
-"OX c #ABC1C0",
-"+X c #AEC1CE",
-"@X c #B9C2C7",
-"#X c #B3C2CC",
-"$X c #BCC5CB",
-"%X c #AFDEC1",
-"&X c #B7DCC1",
-"*X c #B9DDC3",
-"=X c #B5C7D3",
-"-X c #B9C7D0",
-";X c #B7C8D4",
-":X c #BACBD5",
-">X c #BFCFD9",
-",X c #C0C7CC",
-"<X c #C3CBCE",
-"1X c #C7D1CB",
-"2X c #CCD4CE",
-"3X c #C3CDD3",
-"4X c #C8CFD3",
-"5X c #CAD1D5",
-"6X c #C2D1DB",
-"7X c #CAD6DD",
-"8X c #CFD9DF",
-"9X c #D7DDD3",
-"0X c #DADDD5",
-"qX c #D1D7DA",
-"wX c #D4DADE",
-"eX c #D9DCDC",
-"rX c #C6E4CE",
-"tX c #D7ECC5",
-"yX c #D8ECC6",
-"uX c #D7ECCF",
-"iX c #D1EAD7",
-"pX c #DCEED6",
-"aX c #D4EADA",
-"sX c #E2E4DE",
-"dX c #E6EBDE",
-"fX c #E4F2DA",
-"gX c #CDD8E0",
-"hX c #D3DDE4",
-"jX c #D9DDE0",
-"kX c #D6E0E6",
-"lX c #DBE1E5",
-"zX c #DCE4E9",
-"xX c #E3E4E4",
-"cX c #E2EFE5",
-"vX c #E1E7EB",
-"bX c #E4EAEE",
-"nX c #EBECED",
-"mX c #E2F2E4",
-"MX c #EEF6E4",
-"NX c #E6F4EC",
-"BX c #EDF4ED",
-"VX c #EFF8ED",
-"CX c #F1F8E7",
-"ZX c #F2F8ED",
-"AX c #E6ECF0",
-"SX c #EAEEF1",
-"DX c #EDF1F3",
-"FX c #F2F4F5",
-"GX c #F5F9F4",
-"HX c #F9FBF7",
-"JX c #F4F6F8",
-"KX c #F7F9FA",
-"LX c #FDFDFD",
-"PX c None",
-/* pixels */
-"PXPXPXPXPXPXPXPXPXPXPXPXPXPX@XoXoXoX@X$X$XoXoXC.@XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXPXPXPXPXPXPX X4XjXnXnXbXlXqX4X<X,X,X,X,X<X5XeXvXnXbXlX5XV.PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXPXPXPXoXjXDXjXoXN.N.N.C.@X,X4X5X5X4X:X$X#X XB.b.j.j.l. XqXnXlX@XPXPXPXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXPX@XSXwXV.l.oXgXAXDXFXJXJXFXDXSXbXzXzXhXgXgX7X>X;X=X+X}.v.s.k.4XFX$XPXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPX5XnXV. X7XlXvXbXSXDXKXKXKXJXDXDXAXzXzXhXgXgXgX>X:X=X#XXXXX|.{.x.j.lXjXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXLX X3XgXhXlXzXAXSXDXJXKXKXJXDXSXAXvXzXkXgXgX6X>X:X=X+XXX.X|.|.{.m.j.LXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXLXhXgXhXhXkXzXbXSXDXJXJXJXJXDXAXAXzXkXhXhXgX6X>X:X=X+XXXXX|.|.{.{.{.KXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPX>XJXhXgXhXkXzXbXAXSXDXSXDXDXDXAXvXzXkXhXgXgX6X>X:X=X+XXX.X|.}.{.|.AXSXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPX<.XXGXDXzXkXzXzXvXAXAXSXSXAXAXbXvXzXhXgXgXgX6X:X;X+X+XXX{..X+XhXKXzX+XPXPXPXPXPXPXPXPXPXPXPX",
-"PXPX;.<.4..XvXKXDXDXAXAXvXAXAXAXvXzXzXkXhXgXgXgX6X:X;X;X>XgXkXJXKXvX>X+X|.PXPXPXPXPXPXPXPXPXPXPX",
-"PXPX<.<.3.4.w.z..XhXAXJXKXKXJXSXDXDXDXAXAXbXAXAXAXDXJXKXKXKXDXvXhXgX:X+X|.PXPXPXPXPXPXPXPXPXPXPX",
-"PXPX&.<.3.4.4.e.r.t.t.n.|.+X:XgXkXzXvXAXAXDXDXJXKXLXLXJXDXAXvXkXgXgX:X+X|.PXPXPXPXPXPXPXPXPXPXPX",
-"PXPX*.<.<.4.4.e.e.t.d.x.x.{.{.{..X+X=X>XgXkXzXSXFXLXKXJXDXAXzXkXhXgX:X+X|.PXPXPXPXPXPXPXPXPXPXPX",
-"PXPX*.<.3.3.4.w.e.t.d.z.x.n.{.{..X+X=X>XgXkXvXSXFXLXLXJXDXAXzXzXhX6X:XXX|.PXPXPXPXPXPXPXPXPXPXPX",
-"PXPX<.<.3.4.4.e.t.t.d.z.x.n.{.{..X+X=X>XgXkXvXSXFXLXLXJXDXAXvXkXhXgX:X+X|.PXPXPXPXPXPXPXPXPXPXPX",
-"PXPXPX<.3.4.4.e.e.t.d.x.x.{.{.{..X+X=X6XgXkXvXAXFXLXKXJXDXAXzXzXhX7X:X+XPXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXPXPX7.r.w.e.e.t.d.x.z.{.{.}..X+X=X6XgXhXbXSXJXKXKXJXDXbXvXhXjXgX-XPXPXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXPXC.bX5Xw.>.w.t.d.x.x.x.{.}..XXX=X>XgXhXbXSXJXLXLXJXDXAXzXoXN.<XSXoXPXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPX,XnXg.=. . %.&.:.r.d.x.{.|.XX=X6XhXhXjXxXzXjX7XC.s.5.o X @ i.xXeXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXLXg.%.O %.%.O %.O %.O %.%.=.&.;.>.<.:.:.:.;.-.%.+ + O O O %.@ O @ 6.LXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPXLXs.:.:.:.:.-.:.:.:.:.:.:.:.:.:.:.:.:.:.;.:.:.:.:.:.:.:.:.:.:.:.:.5.KXPXPXPXPXPXPXPXPXPXPXPX",
-"PXPX7XbXj.i.i.i.r.w.i.i.i.i.r.8.8.r.i.i.i.r.r.i.9.9.9.9.p.j.C.$X<X4X,X5XnXOXPXPXPXPXPXPXPXPXPXPX",
-"PXPX<.#XSXgX Xv.c.j.j.j.j.j.c.c.c.j.c.c.f.j.c.c.c.c.l.@XxXFXnXaX*X).iXcXFXxX1XPXPXPXPXPXPXPXPXPX",
-"PXPX*.<.p.XXnXDXjX3XXX}.}.}.}.}.}.}.}.B.}.}.}.V.}.$XnXGX^.G 8 # # # # % F R.VXxXPXPXPXPXPXPXPXPX",
-"PXPX*.<.<.4.w.x.XXhXSXFXDXAXvXzXhXhXhXgXhXhXhXjXjXKX).e $ 8 w y d d d t 0 $ 0 ^.nX2XPXPXPXPXPXPX",
-"PXPX*.<.3.3.4.e.e.t.z.{.|.=X6XgXhXzXbXSXSXDXJXFXLXq.$ 9 s g g g h g g g g d w $ q.BX2XPXPXPXPXPX",
-"PXPX*.<.3.3.4.e.t.t.t.x.x.{.{.{..XXX=X6XgXhXbXHXq.* w g h h h /.%X%X/.d g h g s % L GX1XPXPXPXPX",
-"PXPX*.<.4.3.4.e.t.t.d.z.x.{.x.{.|.=X=X6XgXzXHXT.$ p h j c c v BXLXLXNXg F c h h d * u.nXPXPXPXPX",
-"PXPX*.<.3.4.4.e.t.t.d.x.x.n.{.{.|.XX;X6XgXSXaXq u j c v n m M BXLXLXBXf m n v c j s = rX0XPXPXPX",
-"PXPXPX<.3.3.4.e.e.t.d.z.x.n.{.{..XXX;X6XhXKXP = c v m m A S Y VXLXLXNXz S M M m v j w H FXPXPXPX",
-"PXPXPXPX4.w.4.e.e.t.t.z.x.{.{.{..XXX;X>XcXmXu a n b A Y U Y Y NXLXLXNXc Y Y A J m n z - iX2XPXPX",
-"PXPXPXV.zX4X9.1.e.t.d.z.x.n.{.}..XXX=X6XDX(.: I M Y Y T E R ..VXLXLXNXv T T Y U A A A , E.xXPXPX",
-"PXPX@XDXk.@ o O %.2.r.z.n.}..XXX;X7XJXA.3 [ T P.Q.!.!.!.!.HXLXLXGXF.!.!.Q.Q.P.J { I W nXPXPX",
-"PXPXLXs.+ O + O O O O O O O O + %.-.:.p.LXD ^ [ #.GXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXK [ ) b FXPXPX",
-"PXPXLXp.-.;.;.;.;.;.;.;.;.-.;.;.;.;.;.i.KXD / [ $.HXLXLXLXLXLXLXLXLXLXLXLXLXLXLXKXK [ ` l FXPXPX",
-"PXPXqXcXs.7.7.7.8.8.8.7.8.8.8.8.7.7.8.s.LXO.^ [ $.HXLXLXLXLXLXLXLXLXLXLXLXLXLXLXKXK [ ` C FXPXPX",
-"PXPX<.:XFX5XB.h.j.f.f.f.f.f.x.g.h.h.h.b.JXS.6 [ ' J.J.J.J.Y.'.GXLXLXGXR.Y.J.H.H.H.N [ / +.FXPXPX",
-"PXPX*.<.t.-XSXbXjX:X X}.B.B.B.B.B.B.M.B.SX_.4 ' Q Q Q Q Q Q ~ CXLXLXNXk ! ! Q Q Q Q ~ B I.xXPXPX",
-"PXPX*.<.3.4.e.v.=XzXJXJXSXvXhXhXhX7X7X7XnXmXV ! Q Q Q Q Q Q Q CXLXLXBX; Q Q Q Q Q Q ! N pX9XPXPX",
-"PXPX*.<.3.4.4.e.e.t.d.v.XX:XgXhXzXvXbXDXDXLXD.2 Q Q Q Q Q Q Q CXLXLXNX; Q Q Q Q Q Q 1 +.FXPXPXPX",
-"PXPX*.<.3.4.w.w.e.t.d.z.n.n.{.{..XXX;X6XgXDXdXU Q Q Q Q Q Q Q MXLXLXNX; Q Q Q Q Q 5 B uXxXPXPXPX",
-"PXPX*.<.3.4.4.w.e.t.d.z.x.{.{.{..XXX;X6XgXzXKX~./ Q Q Q Q Q Q CXLXHXNX; Q Q Q Q 5 4 I.FXPXPXPXPX",
-"PXPX<.<.3.3.4.e.r.t.d.x.x.n.{.{.|.XX=X6XgXhXSXLXK./ Q Q Q Q Q '.[.[.`.> Q Q Q < 7 G.GX0XPXPXPXPX",
-"PXPX1.<.3.4.4.e.e.t.d.x.x.x.{.{.|.XX=X6XgXhXbXJXHXY.} Q Q Q Q Q Q Q Q Q Q Q < ) K.GXsXPXPXPXPXPX",
-"PXPXPX5.5.4.4.w.e.t.d.x.x.x.{.{..XXX;X6XgXzXvXSXFXHXyXo.( Q Q Q Q Q Q Q < / X.[.HXsXPXPXPXPXPXPX",
-"PXPXPXPXPX6.7.7.e.t.d.z.n.{.{.{..XXX;X6XgXhXvXnXFXKXKXHX[.J. .] ( ( ` .H.].GXFXPXPXPXPXPXPXPXPX",
-"PXPXPXPXPXPXPXPX8.8.r.a.z.x.{.{.|.XX=X6XgXhXzXbXnXFXvXeXFXHXZXfXyXyXfXZXKXGXsXPXPXPXPXPXPXPXPXPX",
-"PXPXPXPXPXPXPXPXPXPXPXPXPXPXp.w.i.i.p.s.s.s.s.s.N.PXPXPXPXPXdXnXnXnXnXdXPXPXPXPXPXPXPXPXPXPXPXPX"
-};