111 } |
111 } |
112 |
112 |
113 // ============================================================================= |
113 // ============================================================================= |
114 // ----------------------------------------------------------------------------- |
114 // ----------------------------------------------------------------------------- |
115 LDDocument::LDDocument() |
115 LDDocument::LDDocument() |
116 { setImplicit (true); |
116 { setBeingDeleted (false); |
|
117 setImplicit (true); |
117 setSavePosition (-1); |
118 setSavePosition (-1); |
118 setListItem (null); |
119 setListItem (null); |
119 setHistory (new History); |
120 setHistory (new History); |
120 m_History->setFile (this); |
121 m_History->setFile (this); |
121 } |
122 } |
122 |
123 |
123 // ============================================================================= |
124 // ============================================================================= |
124 // ----------------------------------------------------------------------------- |
125 // ----------------------------------------------------------------------------- |
125 LDDocument::~LDDocument() |
126 LDDocument::~LDDocument() |
126 { // Clear everything from the model |
127 { // Remove this file from the list of files. This MUST be done FIRST, otherwise |
|
128 // a ton of other functions will think this file is still valid when it is not! |
|
129 g_loadedFiles.removeOne (this); |
|
130 |
|
131 setBeingDeleted (true); |
|
132 m_History->setIgnoring (true); |
|
133 |
|
134 // Clear everything from the model |
127 for (LDObject* obj : getObjects()) |
135 for (LDObject* obj : getObjects()) |
128 obj->deleteSelf(); |
136 obj->deleteSelf(); |
129 |
137 |
130 // Clear the cache as well |
138 // Clear the cache as well |
131 for (LDObject* obj : getCache()) |
139 for (LDObject* obj : getCache()) |
132 obj->deleteSelf(); |
140 obj->deleteSelf(); |
133 |
141 |
134 delete m_History; |
142 delete m_History; |
135 |
|
136 // Remove this file from the list of files |
|
137 g_loadedFiles.removeOne (this); |
|
138 |
143 |
139 // If we just closed the current file, we need to set the current |
144 // If we just closed the current file, we need to set the current |
140 // file as something else. |
145 // file as something else. |
141 if (this == getCurrentDocument()) |
146 if (this == getCurrentDocument()) |
142 { bool found = false; |
147 { bool found = false; |
907 |
919 |
908 // ============================================================================= |
920 // ============================================================================= |
909 // ----------------------------------------------------------------------------- |
921 // ----------------------------------------------------------------------------- |
910 void LDDocument::forgetObject (LDObject* obj) |
922 void LDDocument::forgetObject (LDObject* obj) |
911 { int idx = obj->getIndex(); |
923 { int idx = obj->getIndex(); |
|
924 obj->unselect(); |
912 assert (m_Objects[idx] == obj); |
925 assert (m_Objects[idx] == obj); |
913 dlog ("id: %1, type: %2, code: %3", obj->getID(), obj->getType(), obj->raw()); |
926 |
914 getHistory()->add (new DelHistory (idx, obj)); |
927 if (!getHistory()->isIgnoring()) |
|
928 getHistory()->add (new DelHistory (idx, obj)); |
|
929 |
915 m_Objects.removeAt (idx); |
930 m_Objects.removeAt (idx); |
916 obj->setFile (null); |
931 obj->setFile (null); |
917 } |
932 } |
918 |
933 |
919 // ============================================================================= |
934 // ============================================================================= |
936 { str oldcode = getObject (idx)->raw(); |
951 { str oldcode = getObject (idx)->raw(); |
937 str newcode = obj->raw(); |
952 str newcode = obj->raw(); |
938 *m_History << new EditHistory (idx, oldcode, newcode); |
953 *m_History << new EditHistory (idx, oldcode, newcode); |
939 } |
954 } |
940 |
955 |
|
956 m_Objects[idx]->unselect(); |
|
957 m_Objects[idx]->setFile (null); |
941 obj->setFile (this); |
958 obj->setFile (this); |
942 m_Objects[idx] = obj; |
959 m_Objects[idx] = obj; |
943 } |
960 } |
944 |
961 |
945 // ============================================================================= |
962 // ============================================================================= |
946 // ----------------------------------------------------------------------------- |
963 // ----------------------------------------------------------------------------- |
947 static QList<LDDocument*> getFilesUsed (LDDocument* node) |
964 static void getFilesUsed (LDDocument* node, QList<LDDocument*>& filesUsed) |
948 { QList<LDDocument*> filesUsed; |
965 { filesUsed << node; |
949 |
966 |
950 for (LDObject* obj : node->getObjects()) |
967 for (LDObject* obj : node->getObjects()) |
951 { if (obj->getType() != LDObject::Subfile) |
968 { if (obj->getType() != LDObject::Subfile) |
952 continue; |
969 continue; |
953 |
970 |
954 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
971 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
955 filesUsed << ref->getFileInfo(); |
972 filesUsed << ref->getFileInfo(); |
956 filesUsed << getFilesUsed (ref->getFileInfo()); |
973 getFilesUsed (ref->getFileInfo(), filesUsed); |
957 } |
974 } |
958 |
|
959 return filesUsed; |
|
960 } |
975 } |
961 |
976 |
962 // ============================================================================= |
977 // ============================================================================= |
963 // Find out which files are unused and close them. |
978 // Find out which files are unused and close them. |
964 // ----------------------------------------------------------------------------- |
979 // ----------------------------------------------------------------------------- |
|
980 static bool g_closingUnusedFiles = false; |
|
981 |
965 void LDDocument::closeUnused() |
982 void LDDocument::closeUnused() |
966 { QList<LDDocument*> filesUsed = getFilesUsed (getCurrentDocument()); |
983 { // Don't go here more than once at a time, otherwise we risk double-deletions |
967 |
984 if (g_closingUnusedFiles) |
968 // Anything that's explicitly opened must not be closed |
985 return; |
|
986 |
|
987 QList<LDDocument*> filesUsed; |
|
988 g_closingUnusedFiles = true; |
|
989 |
|
990 // Anything that's explicitly opened must not be closed. |
|
991 // Also do not close anything used by anything explicit |
969 for (LDDocument* file : g_loadedFiles) |
992 for (LDDocument* file : g_loadedFiles) |
970 if (!file->isImplicit()) |
993 if (!file->isImplicit()) |
971 filesUsed << file; |
994 getFilesUsed (file, filesUsed); |
|
995 |
|
996 // Savor the logoed studs if we use them |
|
997 if (gl_logostuds && g_logoedStud && g_logoedStud2) |
|
998 { getFilesUsed (g_logoedStud, filesUsed); |
|
999 getFilesUsed (g_logoedStud2, filesUsed); |
|
1000 } |
972 |
1001 |
973 // Remove duplicated entries |
1002 // Remove duplicated entries |
974 removeDuplicates (filesUsed); |
1003 removeDuplicates (filesUsed); |
975 |
1004 |
976 // Close all open files that aren't in filesUsed |
1005 // Close all open files that aren't in filesUsed |
977 for (LDDocument* file : g_loadedFiles) |
1006 for (LDDocument* file : g_loadedFiles) |
978 { bool isused = false; |
1007 if (!filesUsed.contains (file)) |
979 |
|
980 for (LDDocument* usedFile : filesUsed) |
|
981 { if (file == usedFile) |
|
982 { isused = true; |
|
983 break; |
|
984 } |
|
985 } |
|
986 |
|
987 if (!isused) |
|
988 delete file; |
1008 delete file; |
989 } |
1009 |
990 |
1010 g_closingUnusedFiles = false; |
991 g_loadedFiles.clear(); |
|
992 g_loadedFiles << filesUsed; |
|
993 } |
1011 } |
994 |
1012 |
995 // ============================================================================= |
1013 // ============================================================================= |
996 // ----------------------------------------------------------------------------- |
1014 // ----------------------------------------------------------------------------- |
997 LDObject* LDDocument::getObject (int pos) const |
1015 LDObject* LDDocument::getObject (int pos) const |
1030 QList<LDObject*> LDDocument::inlineContents (LDSubfile::InlineFlags flags) |
1048 QList<LDObject*> LDDocument::inlineContents (LDSubfile::InlineFlags flags) |
1031 { // Possibly substitute with logoed studs: |
1049 { // Possibly substitute with logoed studs: |
1032 // stud.dat -> stud-logo.dat |
1050 // stud.dat -> stud-logo.dat |
1033 // stud2.dat -> stud-logo2.dat |
1051 // stud2.dat -> stud-logo2.dat |
1034 if (gl_logostuds && (flags & LDSubfile::RendererInline)) |
1052 if (gl_logostuds && (flags & LDSubfile::RendererInline)) |
1035 { if (getName() == "stud.dat" && g_logoedStud) |
1053 { // Ensure logoed studs are loaded first |
|
1054 loadLogoedStuds(); |
|
1055 |
|
1056 if (getName() == "stud.dat" && g_logoedStud) |
1036 return g_logoedStud->inlineContents (flags); |
1057 return g_logoedStud->inlineContents (flags); |
1037 elif (getName() == "stud2.dat" && g_logoedStud2) |
1058 elif (getName() == "stud2.dat" && g_logoedStud2) |
1038 return g_logoedStud2->inlineContents (flags); |
1059 return g_logoedStud2->inlineContents (flags); |
1039 } |
1060 } |
1040 |
1061 |
1140 // a new file over it. |
1160 // a new file over it. |
1141 // ----------------------------------------------------------------------------- |
1161 // ----------------------------------------------------------------------------- |
1142 void LDDocument::closeInitialFile() |
1162 void LDDocument::closeInitialFile() |
1143 { if ( |
1163 { if ( |
1144 countExplicitFiles() == 2 && |
1164 countExplicitFiles() == 2 && |
1145 g_loadedFiles[0]->getName() == "" && |
1165 g_loadedFiles[0]->getName().isEmpty() && |
|
1166 g_loadedFiles[1]->getName().isEmpty() == false && |
1146 !g_loadedFiles[0]->hasUnsavedChanges() |
1167 !g_loadedFiles[0]->hasUnsavedChanges() |
1147 ) |
1168 ) |
1148 delete g_loadedFiles[0]; |
1169 delete g_loadedFiles[0]; |
1149 } |
1170 } |
1150 |
1171 |
1151 // ============================================================================= |
1172 // ============================================================================= |
1152 // ----------------------------------------------------------------------------- |
1173 // ----------------------------------------------------------------------------- |
1153 void loadLogoedStuds() |
1174 void loadLogoedStuds() |
1154 { log ("Loading logoed studs...\n"); |
1175 { if (g_logoedStud && g_logoedStud2) |
|
1176 return; |
1155 |
1177 |
1156 delete g_logoedStud; |
1178 delete g_logoedStud; |
1157 delete g_logoedStud2; |
1179 delete g_logoedStud2; |
1158 |
1180 |
1159 g_logoedStud = openDocument ("stud-logo.dat", true); |
1181 g_logoedStud = openDocument ("stud-logo.dat", true); |
1160 g_logoedStud2 = openDocument ("stud2-logo.dat", true); |
1182 g_logoedStud2 = openDocument ("stud2-logo.dat", true); |
|
1183 |
|
1184 log (LDDocument::tr ("Logoed studs loaded.\n")); |
1161 } |
1185 } |
1162 |
1186 |
1163 // ============================================================================= |
1187 // ============================================================================= |
1164 // ----------------------------------------------------------------------------- |
1188 // ----------------------------------------------------------------------------- |
1165 void LDDocument::addToSelection (LDObject* obj) // [protected] |
1189 void LDDocument::addToSelection (LDObject* obj) // [protected] |