Files
textmate/Frameworks/document/src/document.h
2016-07-11 12:27:05 +02:00

236 lines
6.8 KiB
Objective-C

#ifndef DOCUMENT_H_MIJOONQT
#define DOCUMENT_H_MIJOONQT
#include <buffer/buffer.h>
#include <undo/undo.h>
#include <plist/uuid.h>
#include <plist/date.h>
#include <text/types.h>
#include <authorization/authorization.h>
#include <file/bytes.h>
#include <file/open.h>
#include <file/save.h>
#include <file/encoding.h>
#include <scope/scope.h>
#include <regexp/glob.h>
#include <oak/debug.h>
#include <objc/objc.h>
#ifdef __OBJC__
@class OakDocument;
@class OakDocumentObserver;
#else
typedef struct objc_object OakDocument;
typedef struct objc_object OakDocumentObserver;
#endif
namespace document
{
PUBLIC extern std::string const kBookmarkIdentifier;
struct document_t;
typedef std::shared_ptr<document_t> document_ptr;
typedef std::weak_ptr<document_t> document_weak_ptr;
struct inode_t
{
inode_t () { }
inode_t (dev_t device, ino_t inode, std::string const& path);
inode_t (std::string const& path);
operator bool () const { return valid; }
bool operator== (inode_t const& rhs) const { return valid == rhs.valid && inode == rhs.inode && device == rhs.device; }
bool operator!= (inode_t const& rhs) const { return valid != rhs.valid || inode != rhs.inode || device != rhs.device; }
bool operator< (inode_t const& rhs) const;
dev_t device = 0;
ino_t inode = 0;
bool valid = false;
};
struct PUBLIC document_t : std::enable_shared_from_this<document_t>
{
WATCH_LEAKS(document_t);
document_t (OakDocument* document);
~document_t ();
bool operator== (document_t const& rhs) const { return this == &rhs || identifier() == rhs.identifier(); }
bool operator!= (document_t const& rhs) const { return this != &rhs && identifier() != rhs.identifier(); }
OakDocument* document () { observer(); return _document; }
// Only in document_t
bool sticky () const { return _sticky; }
void set_sticky (bool flag) { _sticky = flag; }
void sync_open (CFStringRef runLoopMode = kCFRunLoopDefaultMode);
bool sync_save (CFStringRef runLoopMode = kCFRunLoopDefaultMode);
void show ();
void hide ();
oak::date_t lru () const;
// ===================
// = Simple Wrappers =
// ===================
oak::uuid_t identifier () const;
std::string path () const;
std::string virtual_path () const;
std::string logical_path () const { return virtual_path() == NULL_STR ? path() : virtual_path(); }
std::string custom_name () const;
std::string backup_path () const;
std::string display_name () const;
encoding::type disk_encoding () const;
std::string file_type () const;
ssize_t revision () const;
std::string content () const;
bool is_open () const;
bool is_modified () const;
bool is_on_disk () const;
text::indent_t indent () const;
bool recent_tracking () const;
std::string selection () const;
std::string folded () const;
ng::index_t visible_index () const;
void set_path (std::string const& newPath);
void set_authorization (osx::authorization_t const& auth);
void set_virtual_path (std::string const& virtualPath);
void set_custom_name (std::string const& newCustomName);
void set_file_type (std::string const& newFileType);
void set_revision (ssize_t rev);
void set_content (std::string const& str);
void set_disk_revision (ssize_t rev);
void set_disk_encoding (encoding::type const& encoding);
void set_indent (text::indent_t const& indent);
void set_recent_tracking (bool flag);
void set_selection (std::string const& sel);
void set_folded (std::string const& folded);
void set_visible_index (ng::index_t index);
ng::buffer_t& buffer ();
ng::undo_manager_t& undo_manager ();
// ===========
// = Methods =
// ===========
std::map<std::string, std::string> document_variables () const;
bool backup ();
void detach_backup ();
void enumerate_bytes_using_block (void(^block)(char const* bytes, size_t len, bool* stop));
bool replace (std::multimap<std::pair<size_t, size_t>, std::string> const& replacements, uint32_t crc32);
void close ();
// ===================
void add_mark (text::pos_t const& pos, std::string const& mark, std::string const& value = std::string());
void remove_mark (text::pos_t const& pos, std::string const& mark);
void remove_all_marks (std::string const& typeToClear = NULL_STR);
// ===================
// = Callback system =
// ===================
struct callback_t
{
enum event_t
{
did_save,
did_change_open_status,
did_change_modified_status,
did_change_on_disk_status,
did_change_path,
did_change_file_type,
did_change_indent_settings,
did_change_marks,
did_change_content,
};
virtual ~callback_t () { }
virtual void handle_document_event (document_ptr document, event_t event) = 0;
virtual void document_will_delete (document_t* document) { }
};
void add_callback (callback_t* callback);
void remove_callback (callback_t* callback);
// ==========
// = Legacy =
// ==========
inode_t _inode;
private:
OakDocument* _document;
OakDocumentObserver* _observer;
bool _sticky = false;
OakDocumentObserver* observer ();
};
PUBLIC document_ptr create (std::string const& path = NULL_STR);
PUBLIC document_ptr find (oak::uuid_t const& uuid);
PUBLIC document_ptr from_content (std::string const& content, std::string fileType = NULL_STR);
PUBLIC void remove_marks (std::string const& typeToClear = NULL_STR);
// ====================
// = Document scanner =
// ====================
struct PUBLIC scanner_t
{
WATCH_LEAKS(scanner_t);
scanner_t (std::string const& path, path::glob_list_t const& glob);
~scanner_t ();
void set_follow_directory_links (bool flag) { follow_directory_links = flag; }
void set_follow_file_links (bool flag) { follow_file_links = flag; }
void set_include_untitled (bool flag) { include_untitled = flag; }
void set_depth_first (bool flag) { depth_first = flag; }
void start ();
void stop () { should_stop_flag = true; }
bool is_running () const { return is_running_flag; }
void wait () const { pthread_join(thread, NULL); }
static std::vector<document_ptr> open_documents ();
std::vector<document_ptr> accept_documents ();
std::string get_current_path () const;
private:
std::string path;
path::glob_list_t glob;
bool follow_directory_links = false;
bool follow_file_links = true;
bool include_untitled = false;
bool depth_first = false;
pthread_t thread;
mutable pthread_mutex_t mutex;
volatile bool is_running_flag = false;
volatile bool should_stop_flag = false;
void thread_main ();
void scan_dir (std::string const& dir);
std::string current_path;
std::vector<document_ptr> documents;
std::set< std::pair<dev_t, ino_t> > seen_paths;
};
typedef std::shared_ptr<scanner_t> scanner_ptr;
} /* document */
#endif /* end of include guard: DOCUMENT_H_MIJOONQT */