1 // Aseprite
2 // Copyright (c) 2001-2018  David Capello
3 //
4 // This program is distributed under the terms of
5 // the End-User License Agreement for Aseprite.
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include "app/docs.h"
12 
13 #include "app/doc.h"
14 #include "base/fs.h"
15 #include "base/mutex.h"
16 #include "base/unique_ptr.h"
17 
18 #include <algorithm>
19 
20 namespace app {
21 
Docs(Context * ctx)22 Docs::Docs(Context* ctx)
23   : m_ctx(ctx)
24 {
25   ASSERT(ctx != NULL);
26 }
27 
~Docs()28 Docs::~Docs()
29 {
30   deleteAll();
31 }
32 
add(int width,int height,ColorMode mode,int ncolors)33 Doc* Docs::add(int width, int height, ColorMode mode, int ncolors)
34 {
35   // Ask to observers to create the document (maybe a doc::Document or
36   // a derived class).
37   CreateDocArgs args;
38   notify_observers(&DocsObserver::onCreateDocument, &args);
39   if (!args.document())
40     args.setDocument(new Doc(nullptr));
41 
42   base::UniquePtr<Doc> doc(args.document());
43   doc->sprites().add(width, height, mode, ncolors);
44   doc->setFilename("Sprite");
45   doc->setContext(m_ctx); // Change the document context to add the doc in this collection
46 
47   return doc.release();
48 }
49 
add(Doc * doc)50 Doc* Docs::add(Doc* doc)
51 {
52   ASSERT(doc != NULL);
53   ASSERT(doc->id() != doc::NullId);
54 
55   if (doc->context() != m_ctx) {
56     doc->setContext(m_ctx);
57     ASSERT(std::find(begin(), end(), doc) != end());
58     return doc;
59   }
60 
61   m_docs.insert(begin(), doc);
62 
63   notify_observers(&DocsObserver::onAddDocument, doc);
64   return doc;
65 }
66 
remove(Doc * doc)67 void Docs::remove(Doc* doc)
68 {
69   iterator it = std::find(begin(), end(), doc);
70   if (it == end())              // Already removed.
71     return;
72 
73   m_docs.erase(it);
74 
75   notify_observers(&DocsObserver::onRemoveDocument, doc);
76 
77   doc->setContext(NULL);
78 }
79 
move(Doc * doc,int index)80 void Docs::move(Doc* doc, int index)
81 {
82   iterator it = std::find(begin(), end(), doc);
83   ASSERT(it != end());
84   if (it != end())
85     m_docs.erase(it);
86 
87   m_docs.insert(begin()+index, doc);
88 }
89 
getById(ObjectId id) const90 Doc* Docs::getById(ObjectId id) const
91 {
92   for (const auto& doc : *this) {
93     if (doc->id() == id)
94       return doc;
95   }
96   return NULL;
97 }
98 
getByName(const std::string & name) const99 Doc* Docs::getByName(const std::string& name) const
100 {
101   for (const auto& doc : *this) {
102     if (doc->name() == name)
103       return doc;
104   }
105   return NULL;
106 }
107 
getByFileName(const std::string & filename) const108 Doc* Docs::getByFileName(const std::string& filename) const
109 {
110   std::string fn = base::normalize_path(filename);
111   for (const auto& doc : *this) {
112     if (doc->filename() == fn)
113       return doc;
114   }
115   return NULL;
116 }
117 
deleteAll()118 void Docs::deleteAll()
119 {
120   while (!empty()) {
121     ASSERT(m_ctx == back()->context());
122     delete back();
123   }
124 }
125 
126 } // namespace app
127