2006-01-16 22:02:54 +01:00
|
|
|
// Copyright (c) 2005, Rodrigo Braz Monteiro
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software
|
|
|
|
// without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
2006-01-16 22:02:54 +01:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// $Id$
|
|
|
|
|
|
|
|
/// @file ass_file.h
|
|
|
|
/// @see ass_file.cpp
|
|
|
|
/// @ingroup subs_storage
|
|
|
|
///
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2009-09-11 04:36:34 +02:00
|
|
|
#ifndef AGI_PRE
|
2006-01-16 22:02:54 +01:00
|
|
|
#include <fstream>
|
|
|
|
#include <list>
|
2007-06-19 06:14:25 +02:00
|
|
|
#include <vector>
|
2009-09-11 04:36:34 +02:00
|
|
|
|
2009-09-10 12:26:50 +02:00
|
|
|
#include <wx/arrstr.h>
|
2009-09-11 04:36:34 +02:00
|
|
|
#endif
|
|
|
|
|
2010-12-31 22:02:42 +01:00
|
|
|
#include <libaegisub/signal.h>
|
2010-12-07 20:09:28 +01:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
class FrameRate;
|
|
|
|
class AssDialogue;
|
|
|
|
class AssStyle;
|
2006-07-01 06:08:01 +02:00
|
|
|
class AssAttachment;
|
2006-01-16 22:02:54 +01:00
|
|
|
class AssDialogueBlock;
|
|
|
|
class AssDialogueBlockOverride;
|
|
|
|
class AssDialogueBlockPlain;
|
|
|
|
class AssEntry;
|
|
|
|
|
2010-05-19 02:44:44 +02:00
|
|
|
typedef std::list<AssEntry*>::iterator entryIter;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
/// @class AssFile
|
|
|
|
/// @brief DOCME
|
|
|
|
///
|
|
|
|
/// DOCME
|
2006-01-16 22:02:54 +01:00
|
|
|
class AssFile {
|
2010-07-09 09:31:34 +02:00
|
|
|
std::list<AssFile> UndoStack;
|
|
|
|
std::list<AssFile> RedoStack;
|
|
|
|
wxString undoDescription;
|
|
|
|
/// Revision counter for undo coalescing and modified state tracking
|
|
|
|
int commitId;
|
|
|
|
/// Last saved version of this file
|
|
|
|
int savedCommitId;
|
2011-09-29 20:17:27 +02:00
|
|
|
/// Last autosaved version of this file
|
|
|
|
int autosavedCommitId;
|
2010-06-16 08:20:14 +02:00
|
|
|
|
2011-01-16 08:16:40 +01:00
|
|
|
/// A set of changes has been committed to the file (AssFile::CommitType)
|
2010-12-07 20:09:28 +01:00
|
|
|
agi::signal::Signal<int> AnnounceCommit;
|
2011-01-16 08:16:40 +01:00
|
|
|
/// A new file has been opened (filename)
|
2011-01-16 08:16:33 +01:00
|
|
|
agi::signal::Signal<wxString> FileOpen;
|
2011-01-16 08:16:40 +01:00
|
|
|
/// The file is about to be saved
|
|
|
|
/// This signal is intended for adding metadata such as video filename,
|
|
|
|
/// frame number, etc. Ideally this would all be done immediately rather
|
|
|
|
/// than waiting for a save, but that causes (more) issues with undo
|
2011-01-16 08:16:33 +01:00
|
|
|
agi::signal::Signal<> FileSave;
|
2010-12-07 20:09:28 +01:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
public:
|
2010-06-16 08:20:14 +02:00
|
|
|
/// The lines in the file
|
2006-01-16 22:02:54 +01:00
|
|
|
std::list<AssEntry*> Line;
|
2010-06-16 08:20:14 +02:00
|
|
|
/// The filename of this file, if any
|
2006-01-16 22:02:54 +01:00
|
|
|
wxString filename;
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Is the file loaded?
|
2006-01-16 22:02:54 +01:00
|
|
|
bool loaded;
|
|
|
|
|
|
|
|
AssFile();
|
2010-06-22 02:03:33 +02:00
|
|
|
AssFile(const AssFile &from);
|
|
|
|
AssFile& operator=(AssFile from);
|
2006-01-16 22:02:54 +01:00
|
|
|
~AssFile();
|
|
|
|
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Does the file have unsaved changes?
|
2010-07-09 09:31:34 +02:00
|
|
|
bool IsModified() const {return commitId != savedCommitId; };
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Clear the file
|
|
|
|
void Clear();
|
2010-07-09 09:31:34 +02:00
|
|
|
|
2010-06-16 08:20:14 +02:00
|
|
|
/// @brief Load default file
|
|
|
|
/// @param defline Add a blank line to the file
|
|
|
|
void LoadDefault(bool defline=true);
|
|
|
|
/// Add a style to the file
|
|
|
|
void InsertStyle(AssStyle *style);
|
|
|
|
/// Add an attachment to the file
|
|
|
|
void InsertAttachment(AssAttachment *attach);
|
|
|
|
/// Attach a file to the ass file
|
|
|
|
void InsertAttachment(wxString filename);
|
|
|
|
/// Get the names of all of the styles available
|
|
|
|
wxArrayString GetStyles();
|
|
|
|
/// @brief Get a style by name
|
|
|
|
/// @param name Style name
|
|
|
|
/// @return Pointer to style or NULL
|
|
|
|
AssStyle *GetStyle(wxString name);
|
|
|
|
|
2010-07-09 09:31:34 +02:00
|
|
|
void swap(AssFile &) throw();
|
2010-06-16 08:20:14 +02:00
|
|
|
|
|
|
|
/// @brief Load from a file
|
|
|
|
/// @param file File name
|
|
|
|
/// @param charset Character set of file or empty to autodetect
|
|
|
|
/// @param addToRecent Should the file be added to the MRU list?
|
|
|
|
void Load(const wxString &file,wxString charset="",bool addToRecent=true);
|
2011-09-29 20:17:27 +02:00
|
|
|
|
2010-06-16 08:20:14 +02:00
|
|
|
/// @brief Save to a file
|
|
|
|
/// @param file Path to save to
|
|
|
|
/// @param setfilename Should the filename be changed to the passed path?
|
|
|
|
/// @param addToRecent Should the file be added to the MRU list?
|
|
|
|
/// @param encoding Encoding to use, or empty to let the writer decide (which usually means "App/Save Charset")
|
2011-09-28 21:43:11 +02:00
|
|
|
void Save(wxString file,bool setfilename=false,bool addToRecent=true,const wxString encoding="");
|
2011-09-29 20:17:27 +02:00
|
|
|
|
|
|
|
/// @brief Autosave the file if there have been any chances since the last autosave
|
|
|
|
/// @return File name used or empty if no save was performed
|
|
|
|
wxString AutoSave();
|
|
|
|
|
2010-06-16 08:20:14 +02:00
|
|
|
/// @brief Save to a memory buffer. Used for subtitle providers which support it
|
|
|
|
/// @param[out] dst Destination vector
|
2012-01-08 02:33:19 +01:00
|
|
|
void SaveMemory(std::vector<char> &dst);
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Add file name to the MRU list
|
|
|
|
void AddToRecent(wxString file);
|
|
|
|
/// Can the file be saved in its current format?
|
|
|
|
bool CanSave();
|
|
|
|
/// @brief Get the list of wildcards supported
|
|
|
|
/// @param mode 0 = open, 1 = save, 2 = export
|
|
|
|
static wxString GetWildcardList(int mode);
|
|
|
|
|
|
|
|
/// @brief Get the script resolution
|
|
|
|
/// @param[out] w Width
|
|
|
|
/// @param[in] h Height
|
|
|
|
void GetResolution(int &w,int &h);
|
|
|
|
/// Get the value in a [Script Info] key as int.
|
|
|
|
int GetScriptInfoAsInt(const wxString key);
|
|
|
|
/// Get the value in a [Script Info] key as string.
|
2011-10-25 03:16:36 +02:00
|
|
|
wxString GetScriptInfo(wxString key);
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Set the value of a [Script Info] key. Adds it if it doesn't exist.
|
2011-08-27 09:28:04 +02:00
|
|
|
void SetScriptInfo(wxString const& key, wxString const& value);
|
2010-06-16 08:20:14 +02:00
|
|
|
// Add a ";" comment in the [Script Info] section
|
2012-01-08 02:34:30 +01:00
|
|
|
void AddComment(wxString comment);
|
2010-06-16 08:20:14 +02:00
|
|
|
/// @brief Add a line to the file
|
|
|
|
/// @param data Full text of ASS line
|
2012-01-08 02:34:30 +01:00
|
|
|
/// @param[in,out] version ASS version the line was parsed as
|
|
|
|
/// @param[in,out] attach Accumulator for attachment parsing
|
|
|
|
void AddLine(wxString data, int *version, AssAttachment **attach);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2010-12-07 20:09:28 +01:00
|
|
|
/// Type of changes made in a commit
|
|
|
|
enum CommitType {
|
|
|
|
/// Potentially the entire file has been changed; any saved information
|
2011-09-15 07:16:32 +02:00
|
|
|
/// should be discarded. Note that the active line and selected set
|
|
|
|
/// should not be touched in handlers for this, as they may not have
|
|
|
|
/// been updated yet
|
|
|
|
/// Note that it is intentional that this cannot be combined with
|
|
|
|
/// other commit types
|
|
|
|
COMMIT_NEW = 0,
|
|
|
|
/// The order of lines in the file has changed
|
|
|
|
COMMIT_ORDER = 0x1,
|
|
|
|
/// The script info section has changed in some way
|
|
|
|
COMMIT_SCRIPTINFO = 0x2,
|
|
|
|
/// The styles have changed in some way
|
|
|
|
COMMIT_STYLES = 0x4,
|
|
|
|
/// The attachments have changed in some way
|
|
|
|
COMMIT_ATTACHMENT = 0x8,
|
|
|
|
/// Dialogue lines have been added or removed
|
|
|
|
/// Note that if the active dialogue line was removed, the active line
|
|
|
|
/// should be updated BEFORE committing
|
|
|
|
COMMIT_DIAG_ADDREM = 0x10,
|
|
|
|
/// The metadata fields of existing dialogue lines have changed
|
|
|
|
COMMIT_DIAG_META = 0x20,
|
|
|
|
/// The start and/or end times of existing dialogue lines have changed
|
|
|
|
COMMIT_DIAG_TIME = 0x40,
|
|
|
|
/// The text of existing dialogue lines have changed
|
|
|
|
COMMIT_DIAG_TEXT = 0x80,
|
2011-12-28 22:27:06 +01:00
|
|
|
COMMIT_DIAG_FULL = COMMIT_DIAG_META | COMMIT_DIAG_TIME | COMMIT_DIAG_TEXT
|
2010-12-07 20:09:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
DEFINE_SIGNAL_ADDERS(AnnounceCommit, AddCommitListener)
|
2011-01-16 08:16:33 +01:00
|
|
|
DEFINE_SIGNAL_ADDERS(FileOpen, AddFileOpenListener)
|
|
|
|
DEFINE_SIGNAL_ADDERS(FileSave, AddFileSaveListener)
|
2010-12-07 20:09:28 +01:00
|
|
|
|
2010-07-09 09:31:34 +02:00
|
|
|
/// @brief Flag the file as modified and push a copy onto the undo stack
|
2011-09-28 21:44:24 +02:00
|
|
|
/// @param desc Undo description
|
|
|
|
/// @param type Type of changes made to the file in this commit
|
|
|
|
/// @param commitId Commit to amend rather than pushing a new commit
|
|
|
|
/// @param single_line Line which was changed, if only one line was
|
2010-07-09 09:31:34 +02:00
|
|
|
/// @return Unique identifier for the new undo group
|
2011-09-28 21:44:24 +02:00
|
|
|
int Commit(wxString desc, int type, int commitId = -1, AssEntry *single_line = 0);
|
2010-07-09 09:31:34 +02:00
|
|
|
/// @brief Undo the last set of changes to the file
|
|
|
|
void Undo();
|
|
|
|
/// @brief Redo the last undone changes
|
|
|
|
void Redo();
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Check if undo stack is empty
|
2010-07-09 09:31:34 +02:00
|
|
|
bool IsUndoStackEmpty() const { return UndoStack.size() <= 1; };
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Check if redo stack is empty
|
2010-07-09 09:31:34 +02:00
|
|
|
bool IsRedoStackEmpty() const { return RedoStack.empty(); };
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Get the description of the first undoable change
|
2010-07-09 09:31:34 +02:00
|
|
|
wxString GetUndoDescription() const;
|
2010-06-16 08:20:14 +02:00
|
|
|
/// Get the description of the first redoable change
|
2010-07-09 09:31:34 +02:00
|
|
|
wxString GetRedoDescription() const;
|
2010-06-16 08:20:14 +02:00
|
|
|
|
|
|
|
/// Current script file. It is "above" the stack.
|
|
|
|
static AssFile *top;
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2010-05-19 02:44:44 +02:00
|
|
|
/// Comparison function for use when sorting
|
|
|
|
typedef bool (*CompFunc)(const AssDialogue* lft, const AssDialogue* rgt);
|
|
|
|
|
|
|
|
/// @brief Compare based on start time
|
|
|
|
static bool CompStart(const AssDialogue* lft, const AssDialogue* rgt);
|
|
|
|
/// @brief Compare based on end time
|
|
|
|
static bool CompEnd(const AssDialogue* lft, const AssDialogue* rgt);
|
|
|
|
/// @brief Compare based on end time
|
|
|
|
static bool CompStyle(const AssDialogue* lft, const AssDialogue* rgt);
|
|
|
|
|
|
|
|
/// @brief Sort the dialogue lines in this file
|
|
|
|
/// @param comp Comparison function to use. Defaults to sorting by start time.
|
|
|
|
void Sort(CompFunc comp = CompStart);
|
|
|
|
/// @brief Sort the dialogue lines in the given list
|
|
|
|
/// @param comp Comparison function to use. Defaults to sorting by start time.
|
|
|
|
static void Sort(std::list<AssEntry*>& lst, CompFunc comp = CompStart);
|
|
|
|
/// @brief Sort the dialogue lines in the given list
|
|
|
|
/// @param comp Comparison function to use. Defaults to sorting by start time.
|
|
|
|
static void Sort(std::list<AssDialogue*>& lst, CompFunc comp = CompStart);
|
2006-01-16 22:02:54 +01:00
|
|
|
};
|