<commit_before>/******************************************************************************
 * Copyright (c) 2014-2016 Leandro T. C. Melo (ltcmelo@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 *****************************************************************************/

/*--------------------------*/
/*--- The UaiSo! Project ---*/
/*--------------------------*/

#include "Haskell/HsLexer.h"
#include "Haskell/HsKeywords.h"
#include "Haskell/HsLang.h"
#include "Common/Assert.h"
#include "Common/Trace__.h"
#include "Parsing/ParsingContext.h"
#include "parsing/Lexeme.h"
#include <cctype>

#define TRACE_NAME "HsLexer"

using namespace uaiso;

namespace {

const HsLang hsLang;

} // anonymous

HsLexer::HsLexer()
    : bits_(0)
{
    bit_.atLineStart_ = true;
}

HsLexer::~HsLexer()
{}

Token HsLexer::lex()
{
    Token tk = TK_INVALID;
    updatePos();

LexNextToken:
    mark_ = curr_; // Mark the start of the upcoming token.

    char ch = peekChar();

    // If an opening brace is found, consume it and continue. Otherwise,
    // auto-insert one and keep track of the scope.
    if (bit_.wantBrace_) {
        maybeSkipSpaces(ch);
        bit_.wantBrace_ = false;
        if (ch == '{') {
            consumeChar();
            layoutStack_.push(std::make_pair(false, -1));
        } else {
            bit_.waitOffsetMark_ = true;
            layoutStack_.push(std::make_pair(true, -1));
        }
        tk = TK_LBRACE;
        goto LexDone;
    }

    // At a line start the layout must be checked. Either a semicolon may be
    // inserted as a separator or a scope delimiting closing brace (in the case
    // the matching opening brace has been auto-inserted).
    if (bit_.atLineStart_ && !bit_.waitOffsetMark_ && !layoutStack_.empty()) {
        const Layout& layout = layoutStack_.top();
        if (layout.first) {
            maybeSkipSpaces(ch);
            if (ch != '\n') {
                if (col_ == layout.second) {
                    tk = TK_SEMICOLON;
                    goto LexDone;
                }
                if (col_ < layout.second) {
                    layoutStack_.pop();
                    tk = TK_RBRACE;
                    goto LexDone;
                }
            }
        }
    }

    switch (ch) {
    case 0:
        // TODO: Clarify braces/semicolon rule on "invalid" lexeme.
        return TK_EOP;

    case '\n':
        bit_.atLineStart_ = true;
        consumeChar();
        handleNewLine();
        updatePos();
        goto LexNextToken;

    case '\f':
    case '\t':
    case ' ':
        skipSpaces(ch);
        goto LexNextToken;

    case '(':
    case ')':
    case ',':
    case ';':
    case '[':
    case ']':
    case '`':
        tk = lexSpecial(ch);
        break;

    case '{':
        layoutStack_.push(std::make_pair(false, -1));
        tk = lexSpecial(ch);
        break;

    case '}':
        if (!layoutStack_.empty() && !layoutStack_.top().first)
            layoutStack_.pop();
        tk = lexSpecial(ch);
        break;

    case '!':
    case '#':
    case '$':
    case '%':
    case '&':
    case '*':
    case '+':
    case '/':
    case '>':
    case '?':
    case '@':
    case '\\':
    case '^':
    case '|':
    case '~':
        tk = lexAscSymbol(ch);
        break;

    case '.':
        tk = lexAscSymbolMaybe2(ch, '.', TK_DOT_DOT);
        break;

    case '-':
        tk = lexAscSymbolMaybe2(ch, '>', TK_DASH_ARROW);
        break;

    case '=':
        tk = lexAscSymbolMaybe2(ch, '>', TK_EQ_ARROW);
        break;

    case '<':
        tk = lexAscSymbolMaybe2(ch, '-', TK_ARROW_DASH);
        break;

    case ':':
        tk = lexAscSymbolMaybe2(ch, ':', TK_COLON_COLON);
        break;

    case '"':
    case '\'':
        tk = lexStrLit(ch, false, &hsLang);
        context_->trackLexeme<StrLit>(mark_, curr_ - mark_, LineCol(line_, col_));
        break;

    default:
        if (hsLang.isIdentFirstChar(ch)) {
            tk = lexIdentOrKeyword(ch, &hsLang);
            break;
        }

        if (std::isdigit(ch)) {
            tk = lexNumLit(ch, &hsLang);
            context_->trackLexeme<NumLit>(mark_, curr_ - mark_, LineCol(line_, col_));
            break;
        }

        // Don't know what this is.
        consumeChar();
        PRINT_TRACE("Unknown char %c at %d,%d\n", ch, 0, 0);
        break;
    }

    if (bit_.waitOffsetMark_) {
        bit_.waitOffsetMark_ = false;
        UAISO_ASSERT(!layoutStack_.empty(), return TK_INVALID);
        layoutStack_.top().second = col_;
    }

LexDone:
    bit_.atLineStart_ = false;

    LineCol lineCol(line_, col_);
    context_->trackToken(tk, lineCol);
    context_->trackPhrase(tk, lineCol, curr_ - mark_);

    return tk;
}

namespace {

// A few tokens indexed by their corresponding ASCII value.
const int oprtrTable[] =
{
    // Category `special`
    TK_LPAREN,                                             // 0
    TK_RPAREN,
    TK_COMMA,
    TK_SEMICOLON,
    TK_LBRACKET,
    TK_RBRACKET,
    TK_BACKTICK,
    TK_LBRACE,
    TK_RBRACE,                                             // 8

    // Category `ascSymbol`
    TK_EXCLAM,                                             // 9
    TK_POUND,
    TK_DOLLAR,
    TK_PERCENT,
    TK_AMPER,
    TK_ASTERISK,
    TK_PLUS,                                               // 15
    TK_MINUS,
    TK_DOT,
    TK_SLASH,
    TK_COLON,
    TK_LS,
    TK_EQ,
    TK_GR,
    TK_QUESTION,                                           // 23
    TK_AT,
    TK_BACKSLASH,
    TK_CARET,
    TK_PIPE,
    TK_TILDE,                                              // 28

    // Indexing
    -1, -1, -1, -1,
    9,                                                     // 33
    -1,
    10, 11, 12, 13,
    -1,                                                    // 39
    0, 1, 14, 15, 2, 16, 17, 18,
    -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1,                            // 51...57
    19, 3, 20, 21, 22, 23, 24,
    -1, -1, -1, -1, -1, -1,                                // 65...70
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 71...80
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 81...90
    4, 25, 5, 26,
    -1,
    6,
    -1, -1, -1, -1,                                        // 97...100
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 101...110
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 111...120
    -1, -1,
    7, 27, 8, 28
};

} // anonymous

Token HsLexer::lexOprtrTable(char& ch)
{
    UAISO_ASSERT(ch >= 33 && ch <= 126, return TK_INVALID);

    const char index = oprtrTable[ch];
    ch = consumeCharPeekNext();

    return Token(oprtrTable[index]);
}

Token HsLexer::lexSpecial(char& ch)
{
    return lexOprtrTable(ch);
}

Token HsLexer::lexAscSymbol(char& ch)
{
    Token tk = lexOprtrTable(ch);
    return lexAscSymbolMaybeMore(ch, tk);
}

Token HsLexer::lexAscSymbolMaybe2(char& ch, const char& match, Token reserved)
{
    Token tk = lexOprtrTable(ch);
    if (ch == match) {
        ch = consumeCharPeekNext();
        tk = reserved;
    }

    return lexAscSymbolMaybeMore(ch, tk);
}

Token HsLexer::lexAscSymbolMaybeMore(char &ch, Token tk)
{
    if (!isAscSymbol(ch))
        return tk;

    do {
        ch = consumeCharPeekNext();
    } while (isAscSymbol(ch));

    return TK_CUSTOM_OPRTR;
}

bool HsLexer::isAscSymbol(const char ch) const
{
    switch (ch) {
    case '!':
    case '#':
    case '$':
    case '%':
    case '&':
    case '*':
    case '+':
    case '/':
    case '>':
    case '?':
    case '@':
    case '\\':
    case '^':
    case '|':
    case '~':
    case '.':
    case '=':
    case '<':
    case ':':
        return true;

    default:
        return false;
    }
}

Token HsLexer::filterKeyword(const char* spell, size_t len) const
{
    return HsKeywords::filter(spell, len);
}

void HsLexer::inspectKeyword(Token tk)
{
    switch (tk) {
    case TK_WHERE:
    case TK_LET:
    case TK_DO:
    case TK_OF:
        bit_.wantBrace_ = true;
        break;

    default:
        break;
    }
}

Token HsLexer::classifyIdent(char& ch)
{
    if (mark_[0] >= 97) {
        context_->trackLexeme<Ident>(mark_, curr_ - mark_, LineCol(line_, col_));
        return TK_IDENT;
    }

    // We have a capitalized identifier. However, we must check what comes
    // after it because it can actually be a qualified name or a qualified
    // operator, which are lexed entirely as a single lexeme.
    Token tk = TK_CAPITAL_IDENT;

    std::function<void ()> classifyRecursively = [&]() {
        if (ch != '.') {
            context_->trackLexeme<Ident>(mark_, curr_ - mark_, LineCol(line_, col_));
            return;
        }

        // The presence of the `.` is not sufficient condition to characterize
        // a qualification. It must be followed by an identifier or operator.
        char next = peekChar(1);

        if (hsLang.isIdentChar(next)) {
            ch = consumeCharPeekNext(1);
            while (hsLang.isIdentChar(ch))
                ch = consumeCharPeekNext();
            tk = TK_CAPITAL_IDENT_LIST;
            classifyRecursively();
        }

        if (isAscSymbol(next)) {
            ch = consumeCharPeekNext(1);
            while (isAscSymbol(ch))
                ch = consumeCharPeekNext();
            context_->trackLexeme<Ident>(mark_, curr_ - mark_, LineCol(line_, col_));
            tk = TK_QUALIFIED_OPRTR;
        }
    };
    classifyRecursively();

    return tk;
}
<commit_msg>Fix case in #include<commit_after>/******************************************************************************
 * Copyright (c) 2014-2016 Leandro T. C. Melo (ltcmelo@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 * USA
 *****************************************************************************/

/*--------------------------*/
/*--- The UaiSo! Project ---*/
/*--------------------------*/

#include "Haskell/HsLexer.h"
#include "Haskell/HsKeywords.h"
#include "Haskell/HsLang.h"
#include "Common/Assert.h"
#include "Common/Trace__.h"
#include "Parsing/ParsingContext.h"
#include "Parsing/Lexeme.h"
#include <cctype>

#define TRACE_NAME "HsLexer"

using namespace uaiso;

namespace {

const HsLang hsLang;

} // anonymous

HsLexer::HsLexer()
    : bits_(0)
{
    bit_.atLineStart_ = true;
}

HsLexer::~HsLexer()
{}

Token HsLexer::lex()
{
    Token tk = TK_INVALID;
    updatePos();

LexNextToken:
    mark_ = curr_; // Mark the start of the upcoming token.

    char ch = peekChar();

    // If an opening brace is found, consume it and continue. Otherwise,
    // auto-insert one and keep track of the scope.
    if (bit_.wantBrace_) {
        maybeSkipSpaces(ch);
        bit_.wantBrace_ = false;
        if (ch == '{') {
            consumeChar();
            layoutStack_.push(std::make_pair(false, -1));
        } else {
            bit_.waitOffsetMark_ = true;
            layoutStack_.push(std::make_pair(true, -1));
        }
        tk = TK_LBRACE;
        goto LexDone;
    }

    // At a line start the layout must be checked. Either a semicolon may be
    // inserted as a separator or a scope delimiting closing brace (in the case
    // the matching opening brace has been auto-inserted).
    if (bit_.atLineStart_ && !bit_.waitOffsetMark_ && !layoutStack_.empty()) {
        const Layout& layout = layoutStack_.top();
        if (layout.first) {
            maybeSkipSpaces(ch);
            if (ch != '\n') {
                if (col_ == layout.second) {
                    tk = TK_SEMICOLON;
                    goto LexDone;
                }
                if (col_ < layout.second) {
                    layoutStack_.pop();
                    tk = TK_RBRACE;
                    goto LexDone;
                }
            }
        }
    }

    switch (ch) {
    case 0:
        // TODO: Clarify braces/semicolon rule on "invalid" lexeme.
        return TK_EOP;

    case '\n':
        bit_.atLineStart_ = true;
        consumeChar();
        handleNewLine();
        updatePos();
        goto LexNextToken;

    case '\f':
    case '\t':
    case ' ':
        skipSpaces(ch);
        goto LexNextToken;

    case '(':
    case ')':
    case ',':
    case ';':
    case '[':
    case ']':
    case '`':
        tk = lexSpecial(ch);
        break;

    case '{':
        layoutStack_.push(std::make_pair(false, -1));
        tk = lexSpecial(ch);
        break;

    case '}':
        if (!layoutStack_.empty() && !layoutStack_.top().first)
            layoutStack_.pop();
        tk = lexSpecial(ch);
        break;

    case '!':
    case '#':
    case '$':
    case '%':
    case '&':
    case '*':
    case '+':
    case '/':
    case '>':
    case '?':
    case '@':
    case '\\':
    case '^':
    case '|':
    case '~':
        tk = lexAscSymbol(ch);
        break;

    case '.':
        tk = lexAscSymbolMaybe2(ch, '.', TK_DOT_DOT);
        break;

    case '-':
        tk = lexAscSymbolMaybe2(ch, '>', TK_DASH_ARROW);
        break;

    case '=':
        tk = lexAscSymbolMaybe2(ch, '>', TK_EQ_ARROW);
        break;

    case '<':
        tk = lexAscSymbolMaybe2(ch, '-', TK_ARROW_DASH);
        break;

    case ':':
        tk = lexAscSymbolMaybe2(ch, ':', TK_COLON_COLON);
        break;

    case '"':
    case '\'':
        tk = lexStrLit(ch, false, &hsLang);
        context_->trackLexeme<StrLit>(mark_, curr_ - mark_, LineCol(line_, col_));
        break;

    default:
        if (hsLang.isIdentFirstChar(ch)) {
            tk = lexIdentOrKeyword(ch, &hsLang);
            break;
        }

        if (std::isdigit(ch)) {
            tk = lexNumLit(ch, &hsLang);
            context_->trackLexeme<NumLit>(mark_, curr_ - mark_, LineCol(line_, col_));
            break;
        }

        // Don't know what this is.
        consumeChar();
        PRINT_TRACE("Unknown char %c at %d,%d\n", ch, 0, 0);
        break;
    }

    if (bit_.waitOffsetMark_) {
        bit_.waitOffsetMark_ = false;
        UAISO_ASSERT(!layoutStack_.empty(), return TK_INVALID);
        layoutStack_.top().second = col_;
    }

LexDone:
    bit_.atLineStart_ = false;

    LineCol lineCol(line_, col_);
    context_->trackToken(tk, lineCol);
    context_->trackPhrase(tk, lineCol, curr_ - mark_);

    return tk;
}

namespace {

// A few tokens indexed by their corresponding ASCII value.
const int oprtrTable[] =
{
    // Category `special`
    TK_LPAREN,                                             // 0
    TK_RPAREN,
    TK_COMMA,
    TK_SEMICOLON,
    TK_LBRACKET,
    TK_RBRACKET,
    TK_BACKTICK,
    TK_LBRACE,
    TK_RBRACE,                                             // 8

    // Category `ascSymbol`
    TK_EXCLAM,                                             // 9
    TK_POUND,
    TK_DOLLAR,
    TK_PERCENT,
    TK_AMPER,
    TK_ASTERISK,
    TK_PLUS,                                               // 15
    TK_MINUS,
    TK_DOT,
    TK_SLASH,
    TK_COLON,
    TK_LS,
    TK_EQ,
    TK_GR,
    TK_QUESTION,                                           // 23
    TK_AT,
    TK_BACKSLASH,
    TK_CARET,
    TK_PIPE,
    TK_TILDE,                                              // 28

    // Indexing
    -1, -1, -1, -1,
    9,                                                     // 33
    -1,
    10, 11, 12, 13,
    -1,                                                    // 39
    0, 1, 14, 15, 2, 16, 17, 18,
    -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1,                            // 51...57
    19, 3, 20, 21, 22, 23, 24,
    -1, -1, -1, -1, -1, -1,                                // 65...70
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 71...80
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 81...90
    4, 25, 5, 26,
    -1,
    6,
    -1, -1, -1, -1,                                        // 97...100
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 101...110
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                // 111...120
    -1, -1,
    7, 27, 8, 28
};

} // anonymous

Token HsLexer::lexOprtrTable(char& ch)
{
    UAISO_ASSERT(ch >= 33 && ch <= 126, return TK_INVALID);

    const char index = oprtrTable[ch];
    ch = consumeCharPeekNext();

    return Token(oprtrTable[index]);
}

Token HsLexer::lexSpecial(char& ch)
{
    return lexOprtrTable(ch);
}

Token HsLexer::lexAscSymbol(char& ch)
{
    Token tk = lexOprtrTable(ch);
    return lexAscSymbolMaybeMore(ch, tk);
}

Token HsLexer::lexAscSymbolMaybe2(char& ch, const char& match, Token reserved)
{
    Token tk = lexOprtrTable(ch);
    if (ch == match) {
        ch = consumeCharPeekNext();
        tk = reserved;
    }

    return lexAscSymbolMaybeMore(ch, tk);
}

Token HsLexer::lexAscSymbolMaybeMore(char &ch, Token tk)
{
    if (!isAscSymbol(ch))
        return tk;

    do {
        ch = consumeCharPeekNext();
    } while (isAscSymbol(ch));

    return TK_CUSTOM_OPRTR;
}

bool HsLexer::isAscSymbol(const char ch) const
{
    switch (ch) {
    case '!':
    case '#':
    case '$':
    case '%':
    case '&':
    case '*':
    case '+':
    case '/':
    case '>':
    case '?':
    case '@':
    case '\\':
    case '^':
    case '|':
    case '~':
    case '.':
    case '=':
    case '<':
    case ':':
        return true;

    default:
        return false;
    }
}

Token HsLexer::filterKeyword(const char* spell, size_t len) const
{
    return HsKeywords::filter(spell, len);
}

void HsLexer::inspectKeyword(Token tk)
{
    switch (tk) {
    case TK_WHERE:
    case TK_LET:
    case TK_DO:
    case TK_OF:
        bit_.wantBrace_ = true;
        break;

    default:
        break;
    }
}

Token HsLexer::classifyIdent(char& ch)
{
    if (mark_[0] >= 97) {
        context_->trackLexeme<Ident>(mark_, curr_ - mark_, LineCol(line_, col_));
        return TK_IDENT;
    }

    // We have a capitalized identifier. However, we must check what comes
    // after it because it can actually be a qualified name or a qualified
    // operator, which are lexed entirely as a single lexeme.
    Token tk = TK_CAPITAL_IDENT;

    std::function<void ()> classifyRecursively = [&]() {
        if (ch != '.') {
            context_->trackLexeme<Ident>(mark_, curr_ - mark_, LineCol(line_, col_));
            return;
        }

        // The presence of the `.` is not sufficient condition to characterize
        // a qualification. It must be followed by an identifier or operator.
        char next = peekChar(1);

        if (hsLang.isIdentChar(next)) {
            ch = consumeCharPeekNext(1);
            while (hsLang.isIdentChar(ch))
                ch = consumeCharPeekNext();
            tk = TK_CAPITAL_IDENT_LIST;
            classifyRecursively();
        }

        if (isAscSymbol(next)) {
            ch = consumeCharPeekNext(1);
            while (isAscSymbol(ch))
                ch = consumeCharPeekNext();
            context_->trackLexeme<Ident>(mark_, curr_ - mark_, LineCol(line_, col_));
            tk = TK_QUALIFIED_OPRTR;
        }
    };
    classifyRecursively();

    return tk;
}
<|endoftext|>


<commit_before>#include <string.h>
#include "ImageFile.h"

#ifdef PNG_FOUND
#  include "ImageLoaderPNG.h"
#endif

ImageFile::ImageFile(const char *filename) :
  m_PixelData(0),
  m_FileFormat(  DetectFileFormat(filename) )
{
  unsigned char *rawData = ReadFileData(filename);
  LoadImage(rawData);
  delete [] rawData;
}

ImageFile::ImageFile(const char *filename, EImageFileFormat format) :
  m_FileFormat(format),
  m_PixelData(0)
{
  unsigned char *rawData = ReadFileData(filename);
  LoadImage(rawData);
  delete [] rawData;
}

ImageFile::~ImageFile() {
  if(m_PixelData) {
    delete [] m_PixelData;
  }
}

EImageFileFormat ImageFile::DetectFileFormat(const char *filename) {

  int len = strlen(filename);
  if(len >= 256) {
    // !FIXME! Report Error...
    return kNumImageFileFormats;
  }

  int dotPos = len - 1;

  while(dotPos >= 0 && filename[dotPos--] != '.');

  if(dotPos < 0) {
    // !FIXME! Report Error.....
    return kNumImageFileFormats;
  }

  const char *ext = &filename[dotPos];

  if(strcmp(ext, ".png") == 0) {
    return eFileFormat_PNG;
  }
  return kNumImageFileFormats;
}

bool ImageFile::LoadImage(const unsigned char *rawImageData) {
  return false;
}

#ifdef _MSC_VER
unsigned char *ImageFile::ReadFileData(const char *filename) {

}
#else
unsigned char *ImageFile::ReadFileData(const char *filename) {

}
#endif
<commit_msg>Added code to load the contents of a file to memory on not-windows.<commit_after>#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include "ImageFile.h"

#ifdef PNG_FOUND
#  include "ImageLoaderPNG.h"
#endif

ImageFile::ImageFile(const char *filename) :
  m_PixelData(0),
  m_FileFormat(  DetectFileFormat(filename) )
{
  unsigned char *rawData = ReadFileData(filename);
  if(rawData) {
    LoadImage(rawData);
    delete [] rawData;
  }
}

ImageFile::ImageFile(const char *filename, EImageFileFormat format) :
  m_FileFormat(format),
  m_PixelData(0)
{
  unsigned char *rawData = ReadFileData(filename);
  if(rawData) {
    LoadImage(rawData);
    delete [] rawData;
  }
}

ImageFile::~ImageFile() {
  if(m_PixelData) {
    delete [] m_PixelData;
  }
}

EImageFileFormat ImageFile::DetectFileFormat(const char *filename) {

  int len = strlen(filename);
  if(len >= 256) {
    // !FIXME! Report Error...
    return kNumImageFileFormats;
  }

  int dotPos = len - 1;

  while(dotPos >= 0 && filename[dotPos--] != '.');

  if(dotPos < 0) {
    // !FIXME! Report Error.....
    return kNumImageFileFormats;
  }

  const char *ext = &filename[dotPos];

  if(strcmp(ext, ".png") == 0) {
    return eFileFormat_PNG;
  }
  return kNumImageFileFormats;
}

bool ImageFile::LoadImage(const unsigned char *rawImageData) {
  return false;
}

#ifdef _MSC_VER
unsigned char *ImageFile::ReadFileData(const char *filename) {
  //!FIXME! - Actually, implement me
  assert(!"Not implemented!");
}
#else
unsigned char *ImageFile::ReadFileData(const char *filename) {
  FILE *fp = fopen(filename, "rb");
  if(!fp) {
    fprintf(stderr, "Error opening file for reading: %s\n", filename);
    return 0;
  }

  // Check filesize
  long fileSize = 0;
  fseek(fp, 0, SEEK_END);
  fileSize = ftell(fp);

  // Allocate data for file contents
  unsigned char *rawData = new unsigned char[fileSize];

  // Return stream to beginning of file
  fseek(fp, 0, SEEK_SET);
  assert(ftell(fp) == 0);

  // Read all of the data
  size_t bytesRead = fread(rawData, 1, fileSize, fp);
  if(bytesRead != fileSize) {
    assert(!"We didn't read as much data as we thought we had!");
    fprintf(stderr, "Internal error: Incorrect file size assumption\n");
    return 0;
  }

  // Close the file pointer
  fclose(fp);

  // Return the data..
  return rawData;
}
#endif
<|endoftext|>


<commit_before>#include "boost/filesystem.hpp"

#include <assert.h>
#include "itkCenteredSimilarity2DTransform.h"

// my files
#include "Stack.hpp"
#include "NormalizeImages.hpp"
#include "StackInitializers.hpp"
#include "RegistrationBuilder.hpp"
#include "StackAligner.hpp"
#include "StackIOHelpers.hpp"
#include "IOHelpers.hpp"
#include "Dirs.hpp"
#include "Parameters.hpp"
#include "StackTransforms.hpp"
#include "OptimizerConfig.hpp"
#include "Profiling.hpp"

void checkUsage(int argc, char const *argv[]) {
  if( argc < 3 )
  {
    cerr << "\nUsage: " << endl;
    cerr << argv[0] << " dataSet outputDir (slice)\n\n";
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char const *argv[]) {
	// Verify the number of parameters in the command line
	checkUsage(argc, argv);

	// Process command line arguments
  Dirs::SetDataSet(argv[1]);
  Dirs::SetOutputDirName(argv[2]);

  // basenames is either single name from command line
  // or list from config file
  vector< string > basenames = argc >= 4 ?
                               vector< string >(1, argv[3]) :
                               getFileNames(Dirs::ImageList());

  // prepend directory to each filename in list
  vector< string > LoResFilePaths = constructPaths(Dirs::BlockDir(), basenames, ".bmp");
  vector< string > HiResFilePaths = constructPaths(Dirs::SliceDir(), basenames, ".bmp");

  // initialise stack objects with correct spacings, sizes etc
  typedef Stack< float, itk::ResampleImageFilter, itk::LinearInterpolateImageFunction > StackType;
  StackType::SliceVectorType LoResImages = readImages< StackType >(LoResFileNames);
  StackType::SliceVectorType HiResImages = readImages< StackType >(HiResFileNames);
  normalizeImages< StackType >(LoResImages);
  normalizeImages< StackType >(HiResImages);
  boost::shared_ptr< StackType > LoResStack = InitializeLoResStack<StackType>(LoResImages, "ROI");
  boost::shared_ptr< StackType > HiResStack = InitializeHiResStack<StackType>(HiResImages, "ROI");

  // initialise stacks' transforms with saved transform files
  Load(*LoResStack, Dirs::LoResTransformsDir(), basenames);
  Load(*HiResStack, Dirs::HiResTransformsDir(), basenames);

  // move stack origins to ROI
  itk::Vector< double, 2 > translation = StackTransforms::GetLoResTranslation("ROI") - StackTransforms::GetLoResTranslation("whole_heart");
  StackTransforms::Translate(*LoResStack, translation);
  StackTransforms::Translate(*HiResStack, translation);
  StackTransforms::SetMovingStackCenterWithFixedStack( *LoResStack, *HiResStack );

  // Generate fixed images to register against
  LoResStack->updateVolumes();
  if( argc < 4)
  {
    writeImage< StackType::VolumeType >( LoResStack->GetVolume(), Dirs::ResultsDir() + "LoResROI.mha" );
    HiResStack->updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack->GetVolume(), Dirs::ResultsDir() + "HiResInitialROI.mha" );
  }

  // initialise registration framework
  typedef RegistrationBuilder< StackType > RegistrationBuilderType;
  RegistrationBuilderType registrationBuilder;
  RegistrationBuilderType::RegistrationType::Pointer registration = registrationBuilder.GetRegistration();
  StackAligner< StackType > stackAligner(*LoResStack, *HiResStack, registration);

  // make sure loaded transforms are centered affine
  typedef itk::CenteredAffineTransform< double, 2 > AffineTransformType;
  AffineTransformType::Pointer affineTransform = dynamic_cast< AffineTransformType* >( HiResStack->GetTransform(0).GetPointer() );
  assert( affineTransform );

  // Scale parameter space
  OptimizerConfig::SetOptimizerScalesForCenteredAffineTransform( registration->GetOptimizer() );

  itkProbesCreate();
  itkProbesStart( "Aligning stacks" );
  stackAligner.Update();
  itkProbesStop( "Aligning stacks" );
  itkProbesReport( std::cout );

  if(argc < 4)
  {
    HiResStack->updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack->GetVolume(), Dirs::ResultsDir() + "HiResAffineROI.mha" );
    // writeImage< StackType::MaskVolumeType >( HiResStack->Get3DMask()->GetImage(), Dirs::ResultsDir() + "HiResAffineMask.mha" );
  }

  // Update LoRes as the masks might have shrunk
  LoResStack->updateVolumes();

  // write transforms to directories labeled by both ds ratios
  using namespace boost::filesystem;
  create_directory(Dirs::LoResTransformsDir());
  create_directory(Dirs::HiResTransformsDir());
  Save(*LoResStack, Dirs::LoResTransformsDir(), basenames);
  Save(*HiResStack, Dirs::HiResTransformsDir(), basenames);

  return EXIT_SUCCESS;
}
<commit_msg>Bugfix.<commit_after>#include "boost/filesystem.hpp"

#include <assert.h>
#include "itkCenteredSimilarity2DTransform.h"

// my files
#include "Stack.hpp"
#include "NormalizeImages.hpp"
#include "StackInitializers.hpp"
#include "RegistrationBuilder.hpp"
#include "StackAligner.hpp"
#include "StackIOHelpers.hpp"
#include "IOHelpers.hpp"
#include "Dirs.hpp"
#include "Parameters.hpp"
#include "StackTransforms.hpp"
#include "OptimizerConfig.hpp"
#include "Profiling.hpp"

void checkUsage(int argc, char const *argv[]) {
  if( argc < 3 )
  {
    cerr << "\nUsage: " << endl;
    cerr << argv[0] << " dataSet outputDir (slice)\n\n";
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char const *argv[]) {
	// Verify the number of parameters in the command line
	checkUsage(argc, argv);

	// Process command line arguments
  Dirs::SetDataSet(argv[1]);
  Dirs::SetOutputDirName(argv[2]);

  // basenames is either single name from command line
  // or list from config file
  vector< string > basenames = argc >= 4 ?
                               vector< string >(1, argv[3]) :
                               getFileNames(Dirs::ImageList());

  // prepend directory to each filename in list
  vector< string > LoResFilePaths = constructPaths(Dirs::BlockDir(), basenames, ".bmp");
  vector< string > HiResFilePaths = constructPaths(Dirs::SliceDir(), basenames, ".bmp");

  // initialise stack objects with correct spacings, sizes etc
  typedef Stack< float, itk::ResampleImageFilter, itk::LinearInterpolateImageFunction > StackType;
  StackType::SliceVectorType LoResImages = readImages< StackType >(LoResFilePaths);
  StackType::SliceVectorType HiResImages = readImages< StackType >(HiResFilePaths);
  normalizeImages< StackType >(LoResImages);
  normalizeImages< StackType >(HiResImages);
  boost::shared_ptr< StackType > LoResStack = InitializeLoResStack<StackType>(LoResImages, "ROI");
  boost::shared_ptr< StackType > HiResStack = InitializeHiResStack<StackType>(HiResImages, "ROI");

  // initialise stacks' transforms with saved transform files
  Load(*LoResStack, Dirs::LoResTransformsDir(), basenames);
  Load(*HiResStack, Dirs::HiResTransformsDir(), basenames);

  // move stack origins to ROI
  itk::Vector< double, 2 > translation = StackTransforms::GetLoResTranslation("ROI") - StackTransforms::GetLoResTranslation("whole_heart");
  StackTransforms::Translate(*LoResStack, translation);
  StackTransforms::Translate(*HiResStack, translation);
  StackTransforms::SetMovingStackCenterWithFixedStack( *LoResStack, *HiResStack );

  // Generate fixed images to register against
  LoResStack->updateVolumes();
  if( argc < 4)
  {
    writeImage< StackType::VolumeType >( LoResStack->GetVolume(), Dirs::ResultsDir() + "LoResROI.mha" );
    HiResStack->updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack->GetVolume(), Dirs::ResultsDir() + "HiResInitialROI.mha" );
  }

  // initialise registration framework
  typedef RegistrationBuilder< StackType > RegistrationBuilderType;
  RegistrationBuilderType registrationBuilder;
  RegistrationBuilderType::RegistrationType::Pointer registration = registrationBuilder.GetRegistration();
  StackAligner< StackType > stackAligner(*LoResStack, *HiResStack, registration);

  // make sure loaded transforms are centered affine
  typedef itk::CenteredAffineTransform< double, 2 > AffineTransformType;
  AffineTransformType::Pointer affineTransform = dynamic_cast< AffineTransformType* >( HiResStack->GetTransform(0).GetPointer() );
  assert( affineTransform );

  // Scale parameter space
  OptimizerConfig::SetOptimizerScalesForCenteredAffineTransform( registration->GetOptimizer() );

  itkProbesCreate();
  itkProbesStart( "Aligning stacks" );
  stackAligner.Update();
  itkProbesStop( "Aligning stacks" );
  itkProbesReport( std::cout );

  if(argc < 4)
  {
    HiResStack->updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack->GetVolume(), Dirs::ResultsDir() + "HiResAffineROI.mha" );
    // writeImage< StackType::MaskVolumeType >( HiResStack->Get3DMask()->GetImage(), Dirs::ResultsDir() + "HiResAffineMask.mha" );
  }

  // Update LoRes as the masks might have shrunk
  LoResStack->updateVolumes();

  // write transforms to directories labeled by both ds ratios
  using namespace boost::filesystem;
  create_directory(Dirs::LoResTransformsDir());
  create_directory(Dirs::HiResTransformsDir());
  Save(*LoResStack, Dirs::LoResTransformsDir(), basenames);
  Save(*HiResStack, Dirs::HiResTransformsDir(), basenames);

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)

Copyright (c) 2014-2016 Kim Kulling

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#include <cppcore/Random/RandomGenerator.h>
#include <stdlib.h>
#include <time.h>

namespace CPPCore {

RandomGenerator::RandomGenerator( GeneratorType type )
: m_type( type ) {
    ::srand( static_cast< unsigned int >( time( NULL ) ) );
}

RandomGenerator::~RandomGenerator() {
    // empty
}

int RandomGenerator::get( int lower, int upper ) {
    int ret( 0 );
    if ( GeneratorType::Standard == m_type ) {
        ret = ::rand() % upper + lower;
    }

    return ret;
}

} // Namespace CPPCore
<commit_msg>Fix the build: add missing noexcept<commit_after>/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)

Copyright (c) 2014-2016 Kim Kulling

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#include <cppcore/Random/RandomGenerator.h>
#include <stdlib.h>
#include <time.h>

namespace CPPCore {

RandomGenerator::RandomGenerator( GeneratorType type ) noexcept
: m_type( type ) {
    ::srand( static_cast< unsigned int >( time( NULL ) ) );
}

RandomGenerator::~RandomGenerator() {
    // empty
}

int RandomGenerator::get( int lower, int upper ) {
    int ret( 0 );
    if ( GeneratorType::Standard == m_type ) {
        ret = ::rand() % upper + lower;
    }

    return ret;
}

} // Namespace CPPCore
<|endoftext|>


<commit_before>// Copyright 2016-2020 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

#include "literals.h"

#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace cl_protobufs {

const std::string LispSimpleFtoa(float value) {
  std::string result = SimpleFtoa(value);
  if (result == "inf") {
    GOOGLE_LOG(FATAL) << "single-float-positive-infinity";
  } else if (result == "-inf") {
    GOOGLE_LOG(FATAL) <<  "single-float-negative-infinity";
  } else if (result == "nan") {
    GOOGLE_LOG(FATAL) <<  "single-float-nan";
  }

  std::string::size_type pos = result.find("e", 0);
  if (pos != std::string::npos) {
    result.replace(pos, 1, "f");
    return result;
  }
  return result + "f0";
}

const std::string LispSimpleDtoa(double value) {
  std::string result = SimpleDtoa(value);
  if (result == "inf") {
    GOOGLE_LOG(FATAL) << "double-float-positive-infinity";
  } else if (result == "-inf") {
    GOOGLE_LOG(FATAL) <<  "doubl-float-negative-infinity";
  } else if (result == "nan") {
    GOOGLE_LOG(FATAL) <<  "double-float-nan";
  }

  std::string::size_type pos = result.find("e", 0);
  if (pos != std::string::npos) {
    result.replace(pos, 1, "d");
    return result;
  }

  return result + "d0";
}

const std::string LispEscapeString(const std::string& str) {
  std::string lisp;
  lisp.append(1, '"');
  for (char c : str) {
    if (c == '"') lisp.append(1, '\\');
    lisp.append(1, c);
  }
  lisp.append(1, '"');
  return lisp;
}

const std::string StringOctets(const std::string& str) {
  std::string octets;
  for (char c : str) {
    if (!octets.empty()) octets += " ";
    octets += StrCat(c & 0xff);
  }
  return octets;
}

const std::string LispBool(bool value) { return value ? "cl:t" : "cl:nil"; }

}  // namespace cl_protobufs
}  // namespace protobuf
}  // namespace google
<commit_msg>Optimize calls to std::string::find() and friends for a single char.<commit_after>// Copyright 2016-2020 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

#include "literals.h"

#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace cl_protobufs {

const std::string LispSimpleFtoa(float value) {
  std::string result = SimpleFtoa(value);
  if (result == "inf") {
    GOOGLE_LOG(FATAL) << "single-float-positive-infinity";
  } else if (result == "-inf") {
    GOOGLE_LOG(FATAL) <<  "single-float-negative-infinity";
  } else if (result == "nan") {
    GOOGLE_LOG(FATAL) <<  "single-float-nan";
  }

  std::string::size_type pos = result.find('e', 0);
  if (pos != std::string::npos) {
    result.replace(pos, 1, "f");
    return result;
  }
  return result + "f0";
}

const std::string LispSimpleDtoa(double value) {
  std::string result = SimpleDtoa(value);
  if (result == "inf") {
    GOOGLE_LOG(FATAL) << "double-float-positive-infinity";
  } else if (result == "-inf") {
    GOOGLE_LOG(FATAL) <<  "doubl-float-negative-infinity";
  } else if (result == "nan") {
    GOOGLE_LOG(FATAL) <<  "double-float-nan";
  }

  std::string::size_type pos = result.find('e', 0);
  if (pos != std::string::npos) {
    result.replace(pos, 1, "d");
    return result;
  }

  return result + "d0";
}

const std::string LispEscapeString(const std::string& str) {
  std::string lisp;
  lisp.append(1, '"');
  for (char c : str) {
    if (c == '"') lisp.append(1, '\\');
    lisp.append(1, c);
  }
  lisp.append(1, '"');
  return lisp;
}

const std::string StringOctets(const std::string& str) {
  std::string octets;
  for (char c : str) {
    if (!octets.empty()) octets += " ";
    octets += StrCat(c & 0xff);
  }
  return octets;
}

const std::string LispBool(bool value) { return value ? "cl:t" : "cl:nil"; }

}  // namespace cl_protobufs
}  // namespace protobuf
}  // namespace google
<|endoftext|>


<commit_before>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 *Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
 *contact: immarespond at gmail dot com
 *
 */

#include "Gui/KnobGuiFile.h"

#include <QLabel> // in QtGui on Qt4, in QtWidgets on Qt5
#include <QGridLayout> // in QtGui on Qt4, in QtWidgets on Qt5
#include <QHBoxLayout> // in QtGui on Qt4, in QtWidgets on Qt5

#include "Engine/Settings.h"
#include "Engine/KnobFile.h"

#include "Gui/GuiApplicationManager.h"
#include "Gui/Button.h"
#include "Gui/SequenceFileDialog.h"
#include "Gui/LineEdit.h"
#include "Gui/KnobUndoCommand.h"
#include "Gui/Gui.h"

using namespace Natron;

//===========================FILE_KNOB_GUI=====================================
File_KnobGui::File_KnobGui(boost::shared_ptr<Knob> knob, DockablePanel *container)
: KnobGui(knob, container)
{
    boost::shared_ptr<File_Knob> fk = boost::dynamic_pointer_cast<File_Knob>(knob);
    assert(fk);
    QObject::connect(fk.get(), SIGNAL(openFile(bool)), this, SLOT(open_file(bool)));
}

File_KnobGui::~File_KnobGui()
{
    delete _lineEdit;
    delete _descriptionLabel;
    delete _openFileButton;
}

void File_KnobGui::createWidget(QGridLayout *layout, int row)
{

    _descriptionLabel = new QLabel(QString(QString(getKnob()->getDescription().c_str()) + ":"), layout->parentWidget());
    if(hasToolTip()) {
        _descriptionLabel->setToolTip(toolTip());
    }
    layout->addWidget(_descriptionLabel, row, 0, Qt::AlignRight);

    _lineEdit = new LineEdit(layout->parentWidget());
    _lineEdit->setPlaceholderText("File path...");
    _lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    if(hasToolTip()) {
        _lineEdit->setToolTip(toolTip());
    }
    QObject::connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));

    _openFileButton = new Button(layout->parentWidget());

    QPixmap pix;
    appPTR->getIcon(NATRON_PIXMAP_OPEN_FILE, &pix);
    _openFileButton->setIcon(QIcon(pix));
    _openFileButton->setFixedSize(20, 20);
    QObject::connect(_openFileButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));

    QWidget *container = new QWidget(layout->parentWidget());
    QHBoxLayout *containerLayout = new QHBoxLayout(container);
    container->setLayout(containerLayout);
    containerLayout->setContentsMargins(0, 0, 0, 0);
    containerLayout->addWidget(_lineEdit);
    containerLayout->addWidget(_openFileButton);

    layout->addWidget(container, row, 1);
}

void File_KnobGui::onButtonClicked() {
    boost::shared_ptr<File_Knob> fk = boost::dynamic_pointer_cast<File_Knob>(getKnob());
    assert(fk);
    open_file(fk->isSequencesDialogEnabled());
}

void File_KnobGui::open_file(bool openSequence)
{

    std::vector<std::string> filters;

    boost::shared_ptr<File_Knob> fk = boost::dynamic_pointer_cast<File_Knob>(getKnob());
    if (!fk->isInputImageFile()) {
        filters.push_back("*");
    } else {
        std::map<std::string,std::string> readersForFormat;
        appPTR->getCurrentSettings()->getFileFormatsForReadingAndReader(&readersForFormat);
        for (std::map<std::string,std::string>::const_iterator it = readersForFormat.begin(); it!=readersForFormat.end(); ++it) {
            filters.push_back(it->first);
        }
    }
    QStringList files;

    QString pathWhereToOpen;
    QStringList currentFiles = fk->getValue<QStringList>();
    if (currentFiles.isEmpty()) {
        pathWhereToOpen = _lastOpened;
    } else {
        QString first = currentFiles.at(0);
        pathWhereToOpen = SequenceFileDialog::getFilePath(first);
    }

    SequenceFileDialog dialog(_lineEdit->parentWidget(), filters, openSequence, SequenceFileDialog::OPEN_DIALOG, pathWhereToOpen.toStdString());
    if (dialog.exec()) {
        files = dialog.selectedFiles();
    }
    if (!files.isEmpty()) {
        updateLastOpened(files.at(0));
        pushValueChangedCommand(Variant(files));
    }
}

void File_KnobGui::updateLastOpened(const QString &str)
{
    QString withoutPath = SequenceFileDialog::removePath(str);
    int pos = str.indexOf(withoutPath);
    _lastOpened = str.left(pos);
    getGui()->updateLastSequenceOpenedPath(_lastOpened);

}

void File_KnobGui::updateGUI(int /*dimension*/, const Variant &variant)
{
    std::string pattern = SequenceFileDialog::patternFromFilesList(variant.toStringList()).toStdString();
    _lineEdit->setText(pattern.c_str());
}

void File_KnobGui::onReturnPressed()
{
    QString str = _lineEdit->text();
    if (str.isEmpty()) {
        return;
    }
    QStringList newList = SequenceFileDialog::filesListFromPattern(str);
    if (newList.isEmpty()) {
        return;
    }
    pushValueChangedCommand(Variant(newList));
}

void File_KnobGui::_hide()
{
    _openFileButton->hide();
    _descriptionLabel->hide();
    _lineEdit->hide();
}

void File_KnobGui::_show()
{
    _openFileButton->show();
    _descriptionLabel->show();
    _lineEdit->show();
}

void File_KnobGui::setEnabled() {
    bool enabled = getKnob()->isEnabled();
    _openFileButton->setEnabled(enabled);
    _descriptionLabel->setEnabled(enabled);
    _lineEdit->setEnabled(enabled);

}

//============================OUTPUT_FILE_KNOB_GUI====================================
OutputFile_KnobGui::OutputFile_KnobGui(boost::shared_ptr<Knob> knob, DockablePanel *container)
: KnobGui(knob, container)
{
    boost::shared_ptr<OutputFile_Knob> fk = boost::dynamic_pointer_cast<OutputFile_Knob>(knob);
    assert(fk);
    QObject::connect(fk.get(), SIGNAL(openFile(bool)), this, SLOT(open_file(bool)));
}

OutputFile_KnobGui::~OutputFile_KnobGui()
{
    delete _descriptionLabel;
    delete _lineEdit;
    delete _openFileButton;
}

void OutputFile_KnobGui::createWidget(QGridLayout *layout, int row)
{
    _descriptionLabel = new QLabel(QString(QString(getKnob()->getDescription().c_str()) + ":"), layout->parentWidget());
    if(hasToolTip()) {
        _descriptionLabel->setToolTip(toolTip());
    }
    layout->addWidget(_descriptionLabel, row, 0, Qt::AlignRight);

    _lineEdit = new LineEdit(layout->parentWidget());
    QObject::connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
    _lineEdit->setPlaceholderText(QString("File path..."));
    if(hasToolTip()) {
        _lineEdit->setToolTip(toolTip());
    }
    _lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    _openFileButton = new Button(layout->parentWidget());

    QPixmap pix;
    appPTR->getIcon(NATRON_PIXMAP_OPEN_FILE, &pix);
    _openFileButton->setIcon(QIcon(pix));
    _openFileButton->setFixedSize(20, 20);
    QObject::connect(_openFileButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));

    QWidget *container = new QWidget(layout->parentWidget());
    QHBoxLayout *containerLayout = new QHBoxLayout(container);
    container->setLayout(containerLayout);
    containerLayout->setContentsMargins(0, 0, 0, 0);

    containerLayout->addWidget(_lineEdit);
    containerLayout->addWidget(_openFileButton);

    layout->addWidget(container, row, 1);
}

void OutputFile_KnobGui::onButtonClicked() {
    boost::shared_ptr<OutputFile_Knob> fk = boost::dynamic_pointer_cast<OutputFile_Knob>(getKnob());
    assert(fk);
    open_file(fk->isSequencesDialogEnabled());
}

void OutputFile_KnobGui::open_file(bool openSequence)
{

    std::vector<std::string> filters;

    boost::shared_ptr<OutputFile_Knob> fk = boost::dynamic_pointer_cast<OutputFile_Knob>(getKnob());
    if (!fk->isOutputImageFile()) {
        filters.push_back("*");
    } else {
        std::map<std::string,std::string> writersForFormat;
        appPTR->getCurrentSettings()->getFileFormatsForWritingAndWriter(&writersForFormat);
        for (std::map<std::string,std::string>::const_iterator it = writersForFormat.begin(); it!=writersForFormat.end(); ++it) {
            filters.push_back(it->first);
        }

    }

    SequenceFileDialog dialog(_lineEdit->parentWidget(), filters, openSequence, SequenceFileDialog::SAVE_DIALOG, _lastOpened.toStdString());
    if (dialog.exec()) {
        QString oldPattern = _lineEdit->text();
        QString newPattern = dialog.filesToSave();
        updateLastOpened(SequenceFileDialog::removePath(oldPattern));

        pushValueChangedCommand(Variant(newPattern));
    }
}

void OutputFile_KnobGui::updateLastOpened(const QString &str)
{
    QString withoutPath = SequenceFileDialog::removePath(str);
    int pos = str.indexOf(withoutPath);
    _lastOpened = str.left(pos);
    getGui()->updateLastSequenceSavedPath(_lastOpened);

}

void OutputFile_KnobGui::updateGUI(int /*dimension*/, const Variant &variant)
{
    _lineEdit->setText(variant.toString());
}

void OutputFile_KnobGui::onReturnPressed()
{
    QString newPattern = _lineEdit->text();

    pushValueChangedCommand(Variant(newPattern));
}

void OutputFile_KnobGui::_hide()
{
    _openFileButton->hide();
    _descriptionLabel->hide();
    _lineEdit->hide();
}

void OutputFile_KnobGui::_show()
{
    _openFileButton->show();
    _descriptionLabel->show();
    _lineEdit->show();
}

void OutputFile_KnobGui::setEnabled() {
    bool enabled = getKnob()->isEnabled();
    _openFileButton->setEnabled(enabled);
    _descriptionLabel->setEnabled(enabled);
    _lineEdit->setEnabled(enabled);

}

//============================PATH_KNOB_GUI====================================
Path_KnobGui::Path_KnobGui(boost::shared_ptr<Knob> knob, DockablePanel *container)
: KnobGui(knob, container)
{
    boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(knob);
    assert(fk);
    QObject::connect(fk.get(), SIGNAL(openFile()), this, SLOT(open_file()));
}

Path_KnobGui::~Path_KnobGui()
{
    delete _descriptionLabel;
    delete _lineEdit;
    delete _openFileButton;
}

void Path_KnobGui::createWidget(QGridLayout *layout, int row)
{
    _descriptionLabel = new QLabel(QString(QString(getKnob()->getDescription().c_str()) + ":"), layout->parentWidget());
    if(hasToolTip()) {
        _descriptionLabel->setToolTip(toolTip());
    }
    layout->addWidget(_descriptionLabel, row, 0, Qt::AlignRight);

    _lineEdit = new LineEdit(layout->parentWidget());
    QObject::connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
    if(hasToolTip()) {
        _lineEdit->setToolTip(toolTip());
    }
    _lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    _openFileButton = new Button(layout->parentWidget());
    _openFileButton->setToolTip("Click to select a path to append to/replace this variable.");
    QPixmap pix;
    appPTR->getIcon(NATRON_PIXMAP_OPEN_FILE, &pix);
    _openFileButton->setIcon(QIcon(pix));
    _openFileButton->setFixedSize(20, 20);
    QObject::connect(_openFileButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));

    QWidget *container = new QWidget(layout->parentWidget());
    QHBoxLayout *containerLayout = new QHBoxLayout(container);
    container->setLayout(containerLayout);
    containerLayout->setContentsMargins(0, 0, 0, 0);

    containerLayout->addWidget(_lineEdit);
    containerLayout->addWidget(_openFileButton);

    layout->addWidget(container, row, 1);
}

void Path_KnobGui::onButtonClicked() {
    boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(getKnob());
    assert(fk);
    open_file();
}

void Path_KnobGui::open_file()
{

    std::vector<std::string> filters;

    SequenceFileDialog dialog(_lineEdit->parentWidget(), filters, false, SequenceFileDialog::DIR_DIALOG, _lastOpened.toStdString());
    if (dialog.exec()) {
        QString dirPath = dialog.currentDirectory().absolutePath();
        updateLastOpened(dirPath);
        boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(getKnob());

        if (fk->isMultiPath()) {
            QString existingPath = fk->getValue<QString>();
            if (!existingPath.isEmpty()) {
                existingPath.append(QChar(';'));
                dirPath.prepend(existingPath);
            }

        }
        pushValueChangedCommand(Variant(dirPath));
    }
}

void Path_KnobGui::updateLastOpened(const QString &str)
{
    QString withoutPath = SequenceFileDialog::removePath(str);
    int pos = str.indexOf(withoutPath);
    _lastOpened = str.left(pos);
}

void Path_KnobGui::updateGUI(int /*dimension*/, const Variant &variant)
{
    _lineEdit->setText(variant.toString());
}

void Path_KnobGui::_hide()
{
    _openFileButton->hide();
    _descriptionLabel->hide();
    _lineEdit->hide();
}

void Path_KnobGui::_show()
{
    _openFileButton->show();
    _descriptionLabel->show();
    _lineEdit->show();
}

void Path_KnobGui::onReturnPressed()
{
    QString dirPath = _lineEdit->text();
    boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(getKnob());

    if (fk->isMultiPath()) {
        QString existingPath = fk->getValue<QString>();
        if (!existingPath.isEmpty() && !dirPath.isEmpty()) {
            existingPath.append(QChar(';'));
            dirPath.prepend(existingPath);
        }
    }
    pushValueChangedCommand(Variant(dirPath));
}

void Path_KnobGui::setEnabled() {
    bool enabled = getKnob()->isEnabled();
    _openFileButton->setEnabled(enabled);
    _descriptionLabel->setEnabled(enabled);
    _lineEdit->setEnabled(enabled);

}

<commit_msg>Bug fi in File_KnobGui<commit_after>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 *Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
 *contact: immarespond at gmail dot com
 *
 */

#include "Gui/KnobGuiFile.h"

#include <QLabel> // in QtGui on Qt4, in QtWidgets on Qt5
#include <QGridLayout> // in QtGui on Qt4, in QtWidgets on Qt5
#include <QHBoxLayout> // in QtGui on Qt4, in QtWidgets on Qt5

#include "Engine/Settings.h"
#include "Engine/KnobFile.h"

#include "Gui/GuiApplicationManager.h"
#include "Gui/Button.h"
#include "Gui/SequenceFileDialog.h"
#include "Gui/LineEdit.h"
#include "Gui/KnobUndoCommand.h"
#include "Gui/Gui.h"

using namespace Natron;

//===========================FILE_KNOB_GUI=====================================
File_KnobGui::File_KnobGui(boost::shared_ptr<Knob> knob, DockablePanel *container)
: KnobGui(knob, container)
{
    boost::shared_ptr<File_Knob> fk = boost::dynamic_pointer_cast<File_Knob>(knob);
    assert(fk);
    QObject::connect(fk.get(), SIGNAL(openFile(bool)), this, SLOT(open_file(bool)));
}

File_KnobGui::~File_KnobGui()
{
    delete _lineEdit;
    delete _descriptionLabel;
    delete _openFileButton;
}

void File_KnobGui::createWidget(QGridLayout *layout, int row)
{

    _descriptionLabel = new QLabel(QString(QString(getKnob()->getDescription().c_str()) + ":"), layout->parentWidget());
    if(hasToolTip()) {
        _descriptionLabel->setToolTip(toolTip());
    }
    layout->addWidget(_descriptionLabel, row, 0, Qt::AlignRight);

    _lineEdit = new LineEdit(layout->parentWidget());
    _lineEdit->setPlaceholderText("File path...");
    _lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    if(hasToolTip()) {
        _lineEdit->setToolTip(toolTip());
    }
    QObject::connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));

    _openFileButton = new Button(layout->parentWidget());

    QPixmap pix;
    appPTR->getIcon(NATRON_PIXMAP_OPEN_FILE, &pix);
    _openFileButton->setIcon(QIcon(pix));
    _openFileButton->setFixedSize(20, 20);
    QObject::connect(_openFileButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));

    QWidget *container = new QWidget(layout->parentWidget());
    QHBoxLayout *containerLayout = new QHBoxLayout(container);
    container->setLayout(containerLayout);
    containerLayout->setContentsMargins(0, 0, 0, 0);
    containerLayout->addWidget(_lineEdit);
    containerLayout->addWidget(_openFileButton);

    layout->addWidget(container, row, 1);
}

void File_KnobGui::onButtonClicked() {
    boost::shared_ptr<File_Knob> fk = boost::dynamic_pointer_cast<File_Knob>(getKnob());
    assert(fk);
    open_file(fk->isSequencesDialogEnabled());
}

void File_KnobGui::open_file(bool openSequence)
{

    std::vector<std::string> filters;

    boost::shared_ptr<File_Knob> fk = boost::dynamic_pointer_cast<File_Knob>(getKnob());
    if (!fk->isInputImageFile()) {
        filters.push_back("*");
    } else {
        std::map<std::string,std::string> readersForFormat;
        appPTR->getCurrentSettings()->getFileFormatsForReadingAndReader(&readersForFormat);
        for (std::map<std::string,std::string>::const_iterator it = readersForFormat.begin(); it!=readersForFormat.end(); ++it) {
            filters.push_back(it->first);
        }
    }
    QStringList files;

    QString pathWhereToOpen;
    QStringList currentFiles = fk->getValue<QStringList>();
    if (currentFiles.isEmpty()) {
        pathWhereToOpen = _lastOpened;
    } else {
        QString first = currentFiles.at(0);
        pathWhereToOpen = SequenceFileDialog::getFilePath(first);
    }

    SequenceFileDialog dialog(_lineEdit->parentWidget(), filters, openSequence, SequenceFileDialog::OPEN_DIALOG, pathWhereToOpen.toStdString());
    if (dialog.exec()) {
        files = dialog.selectedFiles();
    }
    if (!files.isEmpty()) {
        updateLastOpened(files.at(0));
        pushValueChangedCommand(Variant(files));
    }
}

void File_KnobGui::updateLastOpened(const QString &str)
{
    QString withoutPath = SequenceFileDialog::removePath(str);
    int pos = str.indexOf(withoutPath);
    _lastOpened = str.left(pos);
    getGui()->updateLastSequenceOpenedPath(_lastOpened);

}

void File_KnobGui::updateGUI(int /*dimension*/, const Variant &variant)
{
    QStringList list = variant.toStringList();
    QString str;
    if (list.size() > 1) {
        str = SequenceFileDialog::patternFromFilesList(list);
    } else if(list.size() == 1) {
        str = list.at(0);
    }
    _lineEdit->setText(str);
}

void File_KnobGui::onReturnPressed()
{
    QString str = _lineEdit->text();
    if (str.isEmpty()) {
        return;
    }
    QStringList newList = SequenceFileDialog::filesListFromPattern(str);
    if (newList.isEmpty()) {
        return;
    }
    pushValueChangedCommand(Variant(newList));
}

void File_KnobGui::_hide()
{
    _openFileButton->hide();
    _descriptionLabel->hide();
    _lineEdit->hide();
}

void File_KnobGui::_show()
{
    _openFileButton->show();
    _descriptionLabel->show();
    _lineEdit->show();
}

void File_KnobGui::setEnabled() {
    bool enabled = getKnob()->isEnabled();
    _openFileButton->setEnabled(enabled);
    _descriptionLabel->setEnabled(enabled);
    _lineEdit->setEnabled(enabled);

}

//============================OUTPUT_FILE_KNOB_GUI====================================
OutputFile_KnobGui::OutputFile_KnobGui(boost::shared_ptr<Knob> knob, DockablePanel *container)
: KnobGui(knob, container)
{
    boost::shared_ptr<OutputFile_Knob> fk = boost::dynamic_pointer_cast<OutputFile_Knob>(knob);
    assert(fk);
    QObject::connect(fk.get(), SIGNAL(openFile(bool)), this, SLOT(open_file(bool)));
}

OutputFile_KnobGui::~OutputFile_KnobGui()
{
    delete _descriptionLabel;
    delete _lineEdit;
    delete _openFileButton;
}

void OutputFile_KnobGui::createWidget(QGridLayout *layout, int row)
{
    _descriptionLabel = new QLabel(QString(QString(getKnob()->getDescription().c_str()) + ":"), layout->parentWidget());
    if(hasToolTip()) {
        _descriptionLabel->setToolTip(toolTip());
    }
    layout->addWidget(_descriptionLabel, row, 0, Qt::AlignRight);

    _lineEdit = new LineEdit(layout->parentWidget());
    QObject::connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
    _lineEdit->setPlaceholderText(QString("File path..."));
    if(hasToolTip()) {
        _lineEdit->setToolTip(toolTip());
    }
    _lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    _openFileButton = new Button(layout->parentWidget());

    QPixmap pix;
    appPTR->getIcon(NATRON_PIXMAP_OPEN_FILE, &pix);
    _openFileButton->setIcon(QIcon(pix));
    _openFileButton->setFixedSize(20, 20);
    QObject::connect(_openFileButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));

    QWidget *container = new QWidget(layout->parentWidget());
    QHBoxLayout *containerLayout = new QHBoxLayout(container);
    container->setLayout(containerLayout);
    containerLayout->setContentsMargins(0, 0, 0, 0);

    containerLayout->addWidget(_lineEdit);
    containerLayout->addWidget(_openFileButton);

    layout->addWidget(container, row, 1);
}

void OutputFile_KnobGui::onButtonClicked() {
    boost::shared_ptr<OutputFile_Knob> fk = boost::dynamic_pointer_cast<OutputFile_Knob>(getKnob());
    assert(fk);
    open_file(fk->isSequencesDialogEnabled());
}

void OutputFile_KnobGui::open_file(bool openSequence)
{

    std::vector<std::string> filters;

    boost::shared_ptr<OutputFile_Knob> fk = boost::dynamic_pointer_cast<OutputFile_Knob>(getKnob());
    if (!fk->isOutputImageFile()) {
        filters.push_back("*");
    } else {
        std::map<std::string,std::string> writersForFormat;
        appPTR->getCurrentSettings()->getFileFormatsForWritingAndWriter(&writersForFormat);
        for (std::map<std::string,std::string>::const_iterator it = writersForFormat.begin(); it!=writersForFormat.end(); ++it) {
            filters.push_back(it->first);
        }

    }

    SequenceFileDialog dialog(_lineEdit->parentWidget(), filters, openSequence, SequenceFileDialog::SAVE_DIALOG, _lastOpened.toStdString());
    if (dialog.exec()) {
        QString oldPattern = _lineEdit->text();
        QString newPattern = dialog.filesToSave();
        updateLastOpened(SequenceFileDialog::removePath(oldPattern));

        pushValueChangedCommand(Variant(newPattern));
    }
}

void OutputFile_KnobGui::updateLastOpened(const QString &str)
{
    QString withoutPath = SequenceFileDialog::removePath(str);
    int pos = str.indexOf(withoutPath);
    _lastOpened = str.left(pos);
    getGui()->updateLastSequenceSavedPath(_lastOpened);

}

void OutputFile_KnobGui::updateGUI(int /*dimension*/, const Variant &variant)
{
    _lineEdit->setText(variant.toString());
}

void OutputFile_KnobGui::onReturnPressed()
{
    QString newPattern = _lineEdit->text();

    pushValueChangedCommand(Variant(newPattern));
}

void OutputFile_KnobGui::_hide()
{
    _openFileButton->hide();
    _descriptionLabel->hide();
    _lineEdit->hide();
}

void OutputFile_KnobGui::_show()
{
    _openFileButton->show();
    _descriptionLabel->show();
    _lineEdit->show();
}

void OutputFile_KnobGui::setEnabled() {
    bool enabled = getKnob()->isEnabled();
    _openFileButton->setEnabled(enabled);
    _descriptionLabel->setEnabled(enabled);
    _lineEdit->setEnabled(enabled);

}

//============================PATH_KNOB_GUI====================================
Path_KnobGui::Path_KnobGui(boost::shared_ptr<Knob> knob, DockablePanel *container)
: KnobGui(knob, container)
{
    boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(knob);
    assert(fk);
    QObject::connect(fk.get(), SIGNAL(openFile()), this, SLOT(open_file()));
}

Path_KnobGui::~Path_KnobGui()
{
    delete _descriptionLabel;
    delete _lineEdit;
    delete _openFileButton;
}

void Path_KnobGui::createWidget(QGridLayout *layout, int row)
{
    _descriptionLabel = new QLabel(QString(QString(getKnob()->getDescription().c_str()) + ":"), layout->parentWidget());
    if(hasToolTip()) {
        _descriptionLabel->setToolTip(toolTip());
    }
    layout->addWidget(_descriptionLabel, row, 0, Qt::AlignRight);

    _lineEdit = new LineEdit(layout->parentWidget());
    QObject::connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
    if(hasToolTip()) {
        _lineEdit->setToolTip(toolTip());
    }
    _lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    _openFileButton = new Button(layout->parentWidget());
    _openFileButton->setToolTip("Click to select a path to append to/replace this variable.");
    QPixmap pix;
    appPTR->getIcon(NATRON_PIXMAP_OPEN_FILE, &pix);
    _openFileButton->setIcon(QIcon(pix));
    _openFileButton->setFixedSize(20, 20);
    QObject::connect(_openFileButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));

    QWidget *container = new QWidget(layout->parentWidget());
    QHBoxLayout *containerLayout = new QHBoxLayout(container);
    container->setLayout(containerLayout);
    containerLayout->setContentsMargins(0, 0, 0, 0);

    containerLayout->addWidget(_lineEdit);
    containerLayout->addWidget(_openFileButton);

    layout->addWidget(container, row, 1);
}

void Path_KnobGui::onButtonClicked() {
    boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(getKnob());
    assert(fk);
    open_file();
}

void Path_KnobGui::open_file()
{

    std::vector<std::string> filters;

    SequenceFileDialog dialog(_lineEdit->parentWidget(), filters, false, SequenceFileDialog::DIR_DIALOG, _lastOpened.toStdString());
    if (dialog.exec()) {
        QString dirPath = dialog.currentDirectory().absolutePath();
        updateLastOpened(dirPath);
        boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(getKnob());

        if (fk->isMultiPath()) {
            QString existingPath = fk->getValue<QString>();
            if (!existingPath.isEmpty()) {
                existingPath.append(QChar(';'));
                dirPath.prepend(existingPath);
            }

        }
        pushValueChangedCommand(Variant(dirPath));
    }
}

void Path_KnobGui::updateLastOpened(const QString &str)
{
    QString withoutPath = SequenceFileDialog::removePath(str);
    int pos = str.indexOf(withoutPath);
    _lastOpened = str.left(pos);
}

void Path_KnobGui::updateGUI(int /*dimension*/, const Variant &variant)
{
    _lineEdit->setText(variant.toString());
}

void Path_KnobGui::_hide()
{
    _openFileButton->hide();
    _descriptionLabel->hide();
    _lineEdit->hide();
}

void Path_KnobGui::_show()
{
    _openFileButton->show();
    _descriptionLabel->show();
    _lineEdit->show();
}

void Path_KnobGui::onReturnPressed()
{
    QString dirPath = _lineEdit->text();
    boost::shared_ptr<Path_Knob> fk = boost::dynamic_pointer_cast<Path_Knob>(getKnob());

    if (fk->isMultiPath()) {
        QString existingPath = fk->getValue<QString>();
        if (!existingPath.isEmpty() && !dirPath.isEmpty()) {
            existingPath.append(QChar(';'));
            dirPath.prepend(existingPath);
        }
    }
    pushValueChangedCommand(Variant(dirPath));
}

void Path_KnobGui::setEnabled() {
    bool enabled = getKnob()->isEnabled();
    _openFileButton->setEnabled(enabled);
    _descriptionLabel->setEnabled(enabled);
    _lineEdit->setEnabled(enabled);

}

<|endoftext|>


<commit_before>#include "AConfig.h"
#if(HAS_BNO055)

#include "NDataManager.h"
#include "CBNO055.h"
#include "CAdaBNO055.h"
#include "CTimer.h"

namespace
{
	CTimer bno055_sample_timer;
	CTimer report_timer;
	CTimer imuTimer;

	bool initalized				= false;
	bool inFusionMode			= false;

	CAdaBNO055 bno;

	imu::Vector<3> euler;

	void InitializeSensor()
	{
		// Attempt to initialize. If this fails, we try every 30 seconds in its update loop
		if( !bno.Initialize() )
		{
			Serial.println( "BNO_INIT_STATUS:FAILED;" );
			initalized = false;
		}
		else
		{
			Serial.println( "BNO_INIT_STATUS:SUCCESS;" );

			Serial.print( "BNO055.SW_Revision_ID:" );
			Serial.print( bno.m_softwareVersionMajor, HEX );
			Serial.print( "." );
			Serial.print( bno.m_softwareVersionMinor, HEX );
			Serial.println( ";" );

			Serial.print( "BNO055.bootloader:" );
			Serial.print( bno.m_bootloaderRev );
			Serial.println( ";" );

			initalized = true;
			inFusionMode = true;
		}
	}
}

void CBNO055::Initialize()
{
	// Reset timers
	bno055_sample_timer.Reset();
	report_timer.Reset();
	imuTimer.Reset();

	InitializeSensor();
}

void CBNO055::Update( CCommand& commandIn )
{
	if( commandIn.Equals( "imumode" ) )
	{
		if( initalized && commandIn.m_arguments[ 0 ] != 0 )
		{
			if( commandIn.m_arguments[ 1 ] == 0 )
			{
				// Turn off override
				inFusionMode	= true;
				bno.EnterNDOFMode();

			}

			if( commandIn.m_arguments[ 1 ] == 12 )
			{
				// Override to NDOF
				inFusionMode	= true;
				bno.EnterNDOFMode();
			}

			if( commandIn.m_arguments[ 1 ] == 8 )
			{
				// Override to IMU mode
				inFusionMode	= false;
				bno.EnterIMUMode();
			}
		}
		else
		{
			Serial.println( "log:Can't enter override, IMU is not initialized yet!;" );
		}
	}

	// 1000 / 21
	if( bno055_sample_timer.HasElapsed( 47 ) )
	{
		if( !initalized )
		{
			// Attempt every 10 secs
			if( report_timer.HasElapsed( 10000 ) )
			{
				// Attempt to initialize the chip again
				InitializeSensor();
			}

			return;
		}

		// System status checks
		if( report_timer.HasElapsed( 1000 ) )
		{
			// System calibration
			if( bno.GetCalibration() )
			{
				Serial.print( "BNO055.CALIB_MAG:" );
				Serial.print( bno.m_magCal );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_ACC:" );
				Serial.print( bno.m_accelCal );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_GYR:" );
				Serial.print( bno.m_gyroCal );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_SYS:" );
				Serial.print( bno.m_systemCal );
				Serial.println( ';' );

				// Get offsets
				bno.GetGyroOffsets();
				bno.GetAccelerometerOffsets();
				bno.GetMagnetometerOffsets();
			}
			else
			{
				Serial.print( "BNO055.CALIB_MAG:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_ACC:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_GYR:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_SYS:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
			}

			// Operating mode
			if( bno.GetOperatingMode() )
			{
				Serial.print( "BNO055.MODE:" );
				Serial.print( bno.m_operatingMode );
				Serial.println( ';' );
			}
			else
			{
				Serial.print( "BNO055.MODE:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
			}

			// System status
			if( bno.GetSystemStatus() )
			{
				Serial.print( "BNO055_STATUS:" );
				Serial.print( bno.m_systemStatus, HEX );
				Serial.println( ";" );
			}
			else
			{
				Serial.print( "BNO055_STATUS:" );
				Serial.print( "N/A" );
				Serial.println( ";" );
			}

			// System Error
			if( bno.GetSystemError() )
			{
				Serial.print( "BNO055_ERROR_FLAG:" );
				Serial.print( bno.m_systemError );
				Serial.println( ";" );
			}
			else
			{
				Serial.print( "BNO055_ERROR_FLAG:" );
				Serial.print( "N/A" );
				Serial.println( ";" );
			}

		}

		// Get orientation data
        if( bno.GetVector( CAdaBNO055::VECTOR_EULER, euler ) )
        {
            // Throw out exactly zero heading values that are all zeroes - necessary when switching modes
            if( euler.x() != 0.0f  )
            {
                // These may need adjusting

                NDataManager::m_navData.YAW		= euler.x();
                NDataManager::m_navData.HDGD	= euler.x();
            }

			NDataManager::m_navData.PITC	= euler.z();
			NDataManager::m_navData.ROLL	= -euler.y();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_ACCELEROMETER, accel ) )
        {
           // Values are now stored in accel.x, accel.y, accel.z
           NDataManager::m_navData.ACCLX = accel.x();
           NDataManager::m_navData.ACCLY = accel.y();
           NDataManager::m_navData.ACCLZ = accel.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_MAGNETOMETER, mag ) )
        {
           // Values are now stored in mag.x, mag.y, mag.z
           NDataManager::m_navData.MAGX = mag.x();
           NDataManager::m_navData.MAGY = mag.y();
           NDataManager::m_navData.MAGZ = mag.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_GYROSCOPE, gyro ) )
        {
           // Values are now stored in gyro.x, gyro.y, gyro.z
           NDataManager::m_navData.GYROX = gyro.x();
           NDataManager::m_navData.GYROY = gyro.y();
           NDataManager::m_navData.GYROZ = gyro.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_LINEARACCEL, linAccel ) )
        {
           // Values are now stored in linAccel.x, linAccel.y, linAccel.z
           NDataManager::m_navData.LACCLX = linAccel.x();
           NDataManager::m_navData.LACCLY = linAccel.y();
           NDataManager::m_navData.LACCLZ = linAccel.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_GRAVITY, grav ) )
        {
           // Values are now stored in grav.x, grav.y, grav.z
           NDataManager::m_navData.GRAVX = grav.x();
           NDataManager::m_navData.GRAVY = grav.y();
           NDataManager::m_navData.GRAVZ = grav.z();
        }
	}
}
#endif
<commit_msg>FIX: missing variables<commit_after>#include "AConfig.h"
#if(HAS_BNO055)

#include "NDataManager.h"
#include "CBNO055.h"
#include "CAdaBNO055.h"
#include "CTimer.h"

namespace
{
	CTimer bno055_sample_timer;
	CTimer report_timer;
	CTimer imuTimer;

	bool initalized				= false;
	bool inFusionMode			= false;

	CAdaBNO055 bno;

	imu::Vector<3> euler;
	imu::Vector<3> mag;
    imu::Vector<3> gyro;
    imu::Vector<3> accel;
    imu::Vector<3> linAccel;
    imu::Vector<3> grav;

	void InitializeSensor()
	{
		// Attempt to initialize. If this fails, we try every 30 seconds in its update loop
		if( !bno.Initialize() )
		{
			Serial.println( "BNO_INIT_STATUS:FAILED;" );
			initalized = false;
		}
		else
		{
			Serial.println( "BNO_INIT_STATUS:SUCCESS;" );

			Serial.print( "BNO055.SW_Revision_ID:" );
			Serial.print( bno.m_softwareVersionMajor, HEX );
			Serial.print( "." );
			Serial.print( bno.m_softwareVersionMinor, HEX );
			Serial.println( ";" );

			Serial.print( "BNO055.bootloader:" );
			Serial.print( bno.m_bootloaderRev );
			Serial.println( ";" );

			initalized = true;
			inFusionMode = true;
		}
	}
}

void CBNO055::Initialize()
{
	// Reset timers
	bno055_sample_timer.Reset();
	report_timer.Reset();
	imuTimer.Reset();

	InitializeSensor();
}

void CBNO055::Update( CCommand& commandIn )
{
	if( commandIn.Equals( "imumode" ) )
	{
		if( initalized && commandIn.m_arguments[ 0 ] != 0 )
		{
			if( commandIn.m_arguments[ 1 ] == 0 )
			{
				// Turn off override
				inFusionMode	= true;
				bno.EnterNDOFMode();

			}

			if( commandIn.m_arguments[ 1 ] == 12 )
			{
				// Override to NDOF
				inFusionMode	= true;
				bno.EnterNDOFMode();
			}

			if( commandIn.m_arguments[ 1 ] == 8 )
			{
				// Override to IMU mode
				inFusionMode	= false;
				bno.EnterIMUMode();
			}
		}
		else
		{
			Serial.println( "log:Can't enter override, IMU is not initialized yet!;" );
		}
	}

	// 1000 / 21
	if( bno055_sample_timer.HasElapsed( 47 ) )
	{
		if( !initalized )
		{
			// Attempt every 10 secs
			if( report_timer.HasElapsed( 10000 ) )
			{
				// Attempt to initialize the chip again
				InitializeSensor();
			}

			return;
		}

		// System status checks
		if( report_timer.HasElapsed( 1000 ) )
		{
			// System calibration
			if( bno.GetCalibration() )
			{
				Serial.print( "BNO055.CALIB_MAG:" );
				Serial.print( bno.m_magCal );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_ACC:" );
				Serial.print( bno.m_accelCal );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_GYR:" );
				Serial.print( bno.m_gyroCal );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_SYS:" );
				Serial.print( bno.m_systemCal );
				Serial.println( ';' );

				// Get offsets
				bno.GetGyroOffsets();
				bno.GetAccelerometerOffsets();
				bno.GetMagnetometerOffsets();
			}
			else
			{
				Serial.print( "BNO055.CALIB_MAG:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_ACC:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_GYR:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
				Serial.print( "BNO055.CALIB_SYS:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
			}

			// Operating mode
			if( bno.GetOperatingMode() )
			{
				Serial.print( "BNO055.MODE:" );
				Serial.print( bno.m_operatingMode );
				Serial.println( ';' );
			}
			else
			{
				Serial.print( "BNO055.MODE:" );
				Serial.print( "N/A" );
				Serial.println( ';' );
			}

			// System status
			if( bno.GetSystemStatus() )
			{
				Serial.print( "BNO055_STATUS:" );
				Serial.print( bno.m_systemStatus, HEX );
				Serial.println( ";" );
			}
			else
			{
				Serial.print( "BNO055_STATUS:" );
				Serial.print( "N/A" );
				Serial.println( ";" );
			}

			// System Error
			if( bno.GetSystemError() )
			{
				Serial.print( "BNO055_ERROR_FLAG:" );
				Serial.print( bno.m_systemError );
				Serial.println( ";" );
			}
			else
			{
				Serial.print( "BNO055_ERROR_FLAG:" );
				Serial.print( "N/A" );
				Serial.println( ";" );
			}

		}

		// Get orientation data
        if( bno.GetVector( CAdaBNO055::VECTOR_EULER, euler ) )
        {
            // Throw out exactly zero heading values that are all zeroes - necessary when switching modes
            if( euler.x() != 0.0f  )
            {
                // These may need adjusting

                NDataManager::m_navData.YAW		= euler.x();
                NDataManager::m_navData.HDGD	= euler.x();
            }

			NDataManager::m_navData.PITC	= euler.z();
			NDataManager::m_navData.ROLL	= -euler.y();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_ACCELEROMETER, accel ) )
        {
           // Values are now stored in accel.x, accel.y, accel.z
           NDataManager::m_navData.ACCLX = accel.x();
           NDataManager::m_navData.ACCLY = accel.y();
           NDataManager::m_navData.ACCLZ = accel.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_MAGNETOMETER, mag ) )
        {
           // Values are now stored in mag.x, mag.y, mag.z
           NDataManager::m_navData.MAGX = mag.x();
           NDataManager::m_navData.MAGY = mag.y();
           NDataManager::m_navData.MAGZ = mag.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_GYROSCOPE, gyro ) )
        {
           // Values are now stored in gyro.x, gyro.y, gyro.z
           NDataManager::m_navData.GYROX = gyro.x();
           NDataManager::m_navData.GYROY = gyro.y();
           NDataManager::m_navData.GYROZ = gyro.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_LINEARACCEL, linAccel ) )
        {
           // Values are now stored in linAccel.x, linAccel.y, linAccel.z
           NDataManager::m_navData.LACCLX = linAccel.x();
           NDataManager::m_navData.LACCLY = linAccel.y();
           NDataManager::m_navData.LACCLZ = linAccel.z();
        }

        if( bno.GetVector( CAdaBNO055::VECTOR_GRAVITY, grav ) )
        {
           // Values are now stored in grav.x, grav.y, grav.z
           NDataManager::m_navData.GRAVX = grav.x();
           NDataManager::m_navData.GRAVY = grav.y();
           NDataManager::m_navData.GRAVZ = grav.z();
        }
	}
}
#endif
<|endoftext|>