Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef T_FILEPATH_INCLUDED
Toshihiro Shimizu 890ddd
#define T_FILEPATH_INCLUDED
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcommon.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TSYSTEM_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
shun-iwasawa ef0f8b
#include <qstring></qstring>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
/*
Toshihiro Shimizu 890ddd
  This is an example of how to use TFilePath and TFrameId classes.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\include frameid_ex.cpp
Shinya Kitaoka 120a6e
//! The class TFrameId describes a frame identified by an integer number of four
Shinya Kitaoka 120a6e
//! figures and, in case, by a character (necessary for added frames)
Shinya Kitaoka 120a6e
class DVAPI TFrameId {
Shinya Kitaoka 120a6e
  int m_frame;
shun-iwasawa ef0f8b
  QString m_letter;  // serve per i frame "aggiunti" del tipo pippo.0001a.tzp =>
shun-iwasawa ef0f8b
                     // f=1 c='a'
manongjohn 4ee91c
  int m_zeroPadding;
manongjohn 4ee91c
  char m_startSeqInd;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  enum {
Shinya Kitaoka 120a6e
    EMPTY_FRAME = -1,  // es. pippo..tif
Shinya Kitaoka 120a6e
    NO_FRAME    = -2   // es. pippo.tif
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  enum FrameFormat {
Shinya Kitaoka 120a6e
    FOUR_ZEROS,
Shinya Kitaoka 120a6e
    NO_PAD,
Shinya Kitaoka 120a6e
    UNDERSCORE_FOUR_ZEROS,  // pippo_0001.tif
manongjohn 4ee91c
    UNDERSCORE_NO_PAD,
manongjohn 4ee91c
    CUSTOM_PAD,
manongjohn 4ee91c
    UNDERSCORE_CUSTOM_PAD,
manongjohn 4ee91c
    USE_CURRENT_FORMAT
Shinya Kitaoka 120a6e
  };  // pippo_1.tif
Shinya Kitaoka 120a6e
manongjohn 4ee91c
  TFrameId(int f = EMPTY_FRAME)
shun-iwasawa ef0f8b
      : m_frame(f), m_letter(""), m_zeroPadding(4), m_startSeqInd('.') {}
shun-iwasawa ef0f8b
  TFrameId(int f, char c, int p = 4, char s = '.')
shun-iwasawa ef0f8b
      : m_frame(f), m_zeroPadding(p), m_startSeqInd(s) {
shun-iwasawa ef0f8b
    m_letter = (c == '\0') ? "" : QString(c);
shun-iwasawa ef0f8b
  }
shun-iwasawa ef0f8b
  TFrameId(int f, QString str, int p = 4, char s = '.')
shun-iwasawa ef0f8b
      : m_frame(f), m_letter(str), m_zeroPadding(p), m_startSeqInd(s) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline bool operator==(const TFrameId &f) const {
Shinya Kitaoka 120a6e
    return f.m_frame == m_frame && f.m_letter == m_letter;
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
  inline bool operator!=(const TFrameId &f) const {
Shinya Kitaoka 120a6e
    return (m_frame != f.m_frame || m_letter != f.m_letter);
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
  inline bool operator<(const TFrameId &f) const {
Shinya Kitaoka 120a6e
    return (m_frame < f.m_frame ||
shun-iwasawa ef0f8b
            (m_frame == f.m_frame &&
shun-iwasawa ef0f8b
             QString::localeAwareCompare(m_letter, f.m_letter) < 0));
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
  inline bool operator>(const TFrameId &f) const { return f < *this; }
Shinya Kitaoka 120a6e
  inline bool operator>=(const TFrameId &f) const { return !operator<(f); }
Shinya Kitaoka 120a6e
  inline bool operator<=(const TFrameId &f) const { return !operator>(f); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const TFrameId &operator++();
Shinya Kitaoka 120a6e
  const TFrameId &operator--();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFrameId &operator=(const TFrameId &f) {
shun-iwasawa e2180e
    m_frame       = f.m_frame;
shun-iwasawa e2180e
    m_letter      = f.m_letter;
shun-iwasawa e2180e
    m_zeroPadding = f.m_zeroPadding;
shun-iwasawa e2180e
    m_startSeqInd = f.m_startSeqInd;
Shinya Kitaoka 120a6e
    return *this;
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
jabarrera 52918b
  bool isEmptyFrame() const { return m_frame == EMPTY_FRAME; }
jabarrera 52918b
  bool isNoFrame() const { return m_frame == NO_FRAME; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // operator string() const;
Shinya Kitaoka 120a6e
  std::string expand(FrameFormat format = FOUR_ZEROS) const;
jabarrera 52918b
  int getNumber() const { return m_frame; }
shun-iwasawa ef0f8b
  QString getLetter() const { return m_letter; }
manongjohn 4ee91c
manongjohn 4ee91c
  void setZeroPadding(int p) { m_zeroPadding = p; }
manongjohn 4ee91c
  int getZeroPadding() const { return m_zeroPadding; }
manongjohn 4ee91c
manongjohn 4ee91c
  void setStartSeqInd(char c) { m_startSeqInd = c; }
manongjohn 4ee91c
  char getStartSeqInd() const { return m_startSeqInd; }
manongjohn 4ee91c
manongjohn 4ee91c
  FrameFormat getCurrentFormat() const {
manongjohn 4ee91c
    switch (m_zeroPadding) {
manongjohn 4ee91c
    case 0:
manongjohn 4ee91c
      return (m_startSeqInd == '.' ? NO_PAD : UNDERSCORE_NO_PAD);
manongjohn 4ee91c
    case 4:
manongjohn 4ee91c
      return (m_startSeqInd == '.' ? FOUR_ZEROS : UNDERSCORE_FOUR_ZEROS);
manongjohn 4ee91c
    default:
manongjohn 4ee91c
      break;
manongjohn 4ee91c
    }
manongjohn 4ee91c
manongjohn 4ee91c
    return (m_startSeqInd == '.' ? CUSTOM_PAD : UNDERSCORE_CUSTOM_PAD);
manongjohn 4ee91c
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! \relates TFrameId*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TFrameId &f) {
Shinya Kitaoka 120a6e
  if (f.isNoFrame())
Shinya Kitaoka 120a6e
    out << "<noframe>";</noframe>
Shinya Kitaoka 120a6e
  else if (f.isEmptyFrame())
Shinya Kitaoka 120a6e
    out << "''";
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    out << f.expand().c_str();
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
/*!The class TFilePath defines a file path.Its constructor creates a string
Shinya Kitaoka 120a6e
   according
Shinya Kitaoka 120a6e
   to the platform and to certain rules.For more information see the
Shinya Kitaoka 120a6e
   constructor.*/
Shinya Kitaoka 120a6e
class DVAPI TFilePath {
Shinya Kitaoka 120a6e
  static bool m_underscoreFormatAllowed;
shun-iwasawa ef0f8b
shun-iwasawa ef0f8b
  // specifies file path condition for sequential image for each project.
shun-iwasawa ef0f8b
  // See filepathproperties.h
shun-iwasawa ef0f8b
  static bool m_useStandard;
shun-iwasawa ef0f8b
  static bool m_acceptNonAlphabetSuffix;
shun-iwasawa ef0f8b
  static int m_letterCountForSuffix;
shun-iwasawa ef0f8b
Shinya Kitaoka 120a6e
  std::wstring m_path;
shun-iwasawa ef0f8b
shun-iwasawa ef0f8b
  struct TFilePathInfo {
shun-iwasawa ef0f8b
    QString parentDir;  // with slash
shun-iwasawa ef0f8b
    QString levelName;
shun-iwasawa ef0f8b
    QChar sepChar;  // either "." or "_"
shun-iwasawa ef0f8b
    TFrameId fId;
shun-iwasawa ef0f8b
    QString extension;
shun-iwasawa ef0f8b
  };
shun-iwasawa ef0f8b
Shinya Kitaoka 120a6e
  void setPath(std::wstring path);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  /*! this static method allows correct reading of levels in the form
Shinya Kitaoka 120a6e
   * pippo_0001.tif (represented  always as pippo..tif) */
Shinya Kitaoka 120a6e
  static void setUnderscoreFormatAllowed(bool state) {
Shinya Kitaoka 120a6e
    m_underscoreFormatAllowed = state;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa ef0f8b
  // called from TProjectManager::getCurrentProject() and
shun-iwasawa ef0f8b
  // ProjectPopup::updateProjectFromFields
shun-iwasawa ef0f8b
  // returns true if something changed
shun-iwasawa ef0f8b
  static bool setFilePathProperties(bool useStandard, bool acceptNonAlphaSuffix,
shun-iwasawa ef0f8b
                                    int letterCountForSuffix) {
shun-iwasawa ef0f8b
    if (m_useStandard == useStandard &&
shun-iwasawa ef0f8b
        m_acceptNonAlphabetSuffix == acceptNonAlphaSuffix &&
shun-iwasawa ef0f8b
        m_letterCountForSuffix == letterCountForSuffix)
shun-iwasawa ef0f8b
      return false;
shun-iwasawa ef0f8b
    m_useStandard             = useStandard;
shun-iwasawa ef0f8b
    m_acceptNonAlphabetSuffix = acceptNonAlphaSuffix;
shun-iwasawa ef0f8b
    m_letterCountForSuffix    = letterCountForSuffix;
shun-iwasawa ef0f8b
    return true;
shun-iwasawa ef0f8b
  }
shun-iwasawa ef0f8b
  static bool useStandard() { return m_useStandard; }
shun-iwasawa ef0f8b
  static QString fidRegExpStr();
shun-iwasawa ef0f8b
Shinya Kitaoka 120a6e
  /*!This constructor creates a string removing redundances ('//', './',etc.)
Shinya Kitaoka 120a6e
and final slashes,
Shinya Kitaoka 120a6e
      correcting (redressing) the "twisted" slashes.
Shinya Kitaoka 120a6e
      Note that if the current directory is ".", it becomes "".
Shinya Kitaoka 120a6e
If the path is "<alpha>:" a slash will be added*/</alpha>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  explicit TFilePath(const char *path = "");
Shinya Kitaoka 120a6e
  explicit TFilePath(const std::string &path);
Shinya Kitaoka 120a6e
  explicit TFilePath(const std::wstring &path);
Shinya Kitaoka 120a6e
  explicit TFilePath(const QString &path);
Shinya Kitaoka 120a6e
jabarrera 52918b
  ~TFilePath() {}
Shinya Kitaoka 120a6e
  TFilePath(const TFilePath &fp) : m_path(fp.m_path) {}
Shinya Kitaoka 120a6e
  TFilePath &operator=(const TFilePath &fp) {
Shinya Kitaoka 120a6e
    m_path = fp.m_path;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const TFilePath &fp) const;
Shinya Kitaoka 120a6e
  inline bool operator!=(const TFilePath &fp) const {
Shinya Kitaoka 120a6e
    return !(m_path == fp.m_path);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool operator<(const TFilePath &fp) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const std::wstring getWideString() const;
Shinya Kitaoka 120a6e
  QString getQString() const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Returns:
Shinya Kitaoka 120a6e
   a.  "" if there is no filename extension
Shinya Kitaoka 120a6e
   b. "." if there is a filename extension but no frame
Shinya Kitaoka 120a6e
   c.".." if there are both filename extension and frame */
Shinya Kitaoka 120a6e
  std::string getDots() const;  // ritorna ""(no estensione), "."(estensione, no
Shinya Kitaoka 120a6e
                                // frame) o ".."(estensione e frame)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Returns the filename extension, including leading period (.).
Shinya Kitaoka 120a6e
      Returns "" if there is no filename extension.*/
Shinya Kitaoka 120a6e
  std::string getDottedType() const;  // ritorna l'estensione con il PUNTO (se
Shinya Kitaoka 120a6e
                                      // non c'e' estensione ritorna "")
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Returns the filename extension, escluding leading period (.).
Shinya Kitaoka 120a6e
      Returns "" if there is no filename extension.*/
Shinya Kitaoka 120a6e
  std::string getUndottedType() const;  // ritorna l'estensione senza PUNTO
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!It is equal to getUndottedType():
Shinya Kitaoka 120a6e
      Returns the filename extension, excluding leading period (.).
Shinya Kitaoka 120a6e
      Returns "" if there is no filename extension.*/
Shinya Kitaoka 120a6e
  std::string getType() const {
Shinya Kitaoka 120a6e
    return getUndottedType();
jabarrera 52918b
  }  // ritorna l'estensione SENZA PUNTO
shun-iwasawa ef0f8b
Shinya Kitaoka 120a6e
  /*!Returns the base filename (no extension, no dots, no slash)*/
Shinya Kitaoka 120a6e
  std::string getName() const;       // noDot! noSlash!
Shinya Kitaoka 120a6e
  std::wstring getWideName() const;  // noDot! noSlash!
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Returns the filename (with extension, escluding in case the frame number).
Shinya Kitaoka 120a6e
      ex.: TFilePath("/pippo/pluto.0001.gif").getLevelName() == "pluto..gif"
Shinya Kitaoka 120a6e
   */
Shinya Kitaoka 120a6e
  std::string getLevelName()
Shinya Kitaoka 120a6e
      const;  // es. TFilePath("/pippo/pluto.0001.gif").getLevelName() ==
Shinya Kitaoka 120a6e
              // "pluto..gif"
Shinya Kitaoka 120a6e
  std::wstring getLevelNameW()
Shinya Kitaoka 120a6e
      const;  // es. TFilePath("/pippo/pluto.0001.gif").getLevelName() ==
Shinya Kitaoka 120a6e
              // "pluto..gif"
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Returns the parent directory escluding the eventual final slash.*/
Shinya Kitaoka 120a6e
  TFilePath getParentDir() const;  // noSlash!;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFrameId getFrame() const;
Jeremy Bullock d8339e
  bool isFfmpegType() const;
Shinya Kitaoka 120a6e
  bool isLevelName()
Shinya Kitaoka 120a6e
      const;  //{return getFrame() == TFrameId(TFrameId::EMPTY_FRAME);};
Shinya Kitaoka 120a6e
  bool isAbsolute() const;
Shinya Kitaoka 120a6e
  bool isRoot() const;
jabarrera 52918b
  bool isEmpty() const { return m_path == L""; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Return a TFilePath with extension type.
Shinya Kitaoka 120a6e
type is a string that indicate the filename extension(ex:. bmp or .bmp)*/
Shinya Kitaoka 120a6e
  TFilePath withType(const std::string &type) const;
Shinya Kitaoka 120a6e
  /*!Return a TFilePath with filename "name".*/
Shinya Kitaoka 120a6e
  TFilePath withName(const std::string &name) const;
Shinya Kitaoka 120a6e
  /*!Return a TFilePath with filename "name". Unicode*/
Shinya Kitaoka 120a6e
  TFilePath withName(const std::wstring &name) const;
Shinya Kitaoka 120a6e
  /*!Return a TFilePath with parent directory "dir".*/
Shinya Kitaoka 120a6e
  TFilePath withParentDir(const TFilePath &dir) const;
Shinya Kitaoka 120a6e
  /*!Return a TFilePath without parent directory */
Shinya Kitaoka 120a6e
  TFilePath withoutParentDir() const { return withParentDir(TFilePath()); }
Shinya Kitaoka 120a6e
  /*!Return a TFilePath with frame "frame".*/
manongjohn 4ee91c
  TFilePath withFrame(
manongjohn 4ee91c
      const TFrameId &frame,
manongjohn 4ee91c
      TFrameId::FrameFormat format = TFrameId::USE_CURRENT_FORMAT) const;
Shinya Kitaoka 120a6e
  /*!Return a TFilePath with a frame identified by an integer number "f".*/
jabarrera 52918b
  TFilePath withFrame(int f) const { return withFrame(TFrameId(f)); }
Shinya Kitaoka 120a6e
  /*!Return a TFilePath with a frame identified by an integer and by a
Shinya Kitaoka 120a6e
   * character*/
Shinya Kitaoka 120a6e
  TFilePath withFrame(int f, char letter) const {
Shinya Kitaoka 120a6e
    return withFrame(TFrameId(f, letter));
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath withFrame() const {
Shinya Kitaoka 120a6e
    return withFrame(TFrameId(TFrameId::EMPTY_FRAME));
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
  TFilePath withNoFrame() const {
Shinya Kitaoka 120a6e
    return withFrame(TFrameId(TFrameId::NO_FRAME));
jabarrera 52918b
  }  // pippo.tif
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath operator+(const TFilePath &fp) const;
Shinya Kitaoka 120a6e
  TFilePath &operator+=(const TFilePath &fp) /*{*this=*this+fp;return *this;}*/;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline TFilePath operator+(const std::string &s) const {
Shinya Kitaoka 120a6e
    return operator+(TFilePath(s));
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
  inline TFilePath &operator+=(const std::string &s) {
Shinya Kitaoka 120a6e
    return operator+=(TFilePath(s));
jabarrera 52918b
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath &operator+=(const std::wstring &s);
Shinya Kitaoka 120a6e
  TFilePath operator+(const std::wstring &s) const {
Shinya Kitaoka 120a6e
    TFilePath res(*this);
Shinya Kitaoka 120a6e
    return res += s;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isAncestorOf(const TFilePath &) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath operator-(
Shinya Kitaoka 120a6e
      const TFilePath &fp) const;  // TFilePath("/a/b/c.txt")-TFilePath("/a/")
Shinya Kitaoka 120a6e
                                   // == TFilePath("b/c.txt");
Shinya Kitaoka 120a6e
  // se fp.isAncestorOf(this) == false ritorna this
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool match(const TFilePath &fp)
Shinya Kitaoka 120a6e
      const;  // sono uguali a meno del numero di digits del frame
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // '/a/b/c.txt' => head='a' tail='b/c.txt'
Shinya Kitaoka 120a6e
  void split(std::wstring &head, TFilePath &tail) const;
shun-iwasawa ef0f8b
shun-iwasawa ef0f8b
  TFilePathInfo analyzePath() const;
shun-iwasawa fc0d80
shun-iwasawa fc0d80
  QChar getSepChar() const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class TMalformedFrameException final : public TException {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TMalformedFrameException(const TFilePath &fp,
Shinya Kitaoka 120a6e
                           const std::wstring &msg = std::wstring())
Shinya Kitaoka 120a6e
      : TException(fp.getWideName() + L":" + msg) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  TMalformedFrameException();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
DVAPI std::ostream &operator<<(std::ostream &out, const TFilePath &path);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
typedef std::list<tfilepath> TFilePathSet;</tfilepath>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // T_FILEPATH_INCLUDED