Просмотр исходного кода

Added Data class, UTF8 support for String, save functionality for text editor in IDE

Ivan Safrin 15 лет назад
Родитель
Сommit
347e2cb643

+ 8 - 0
Core/Build/Mac OS X/PolyCore.xcodeproj/project.pbxproj

@@ -9,6 +9,8 @@
 /* Begin PBXBuildFile section */
 /* Begin PBXBuildFile section */
 		6D8656A912AF5FCD008A486E /* PolyString.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D8656A812AF5FCD008A486E /* PolyString.h */; };
 		6D8656A912AF5FCD008A486E /* PolyString.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D8656A812AF5FCD008A486E /* PolyString.h */; };
 		6D8656AB12AF5FD5008A486E /* PolyString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D8656AA12AF5FD5008A486E /* PolyString.cpp */; };
 		6D8656AB12AF5FD5008A486E /* PolyString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D8656AA12AF5FD5008A486E /* PolyString.cpp */; };
+		6D865AC212B07363008A486E /* PolyData.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D865AC112B07363008A486E /* PolyData.h */; };
+		6D865AC412B0736C008A486E /* PolyData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D865AC312B0736C008A486E /* PolyData.cpp */; };
 		6DFB016F12A73BC200C43A7D /* PolyModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DFB016E12A73BC200C43A7D /* PolyModule.h */; };
 		6DFB016F12A73BC200C43A7D /* PolyModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DFB016E12A73BC200C43A7D /* PolyModule.h */; };
 		6DFB017112A73BCF00C43A7D /* PolyModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6DFB017012A73BCF00C43A7D /* PolyModule.cpp */; };
 		6DFB017112A73BCF00C43A7D /* PolyModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6DFB017012A73BCF00C43A7D /* PolyModule.cpp */; };
 		6DFBF3BD12A3184E00C43A7D /* OSBasics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DFBF30D12A3184E00C43A7D /* OSBasics.h */; };
 		6DFBF3BD12A3184E00C43A7D /* OSBasics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DFBF30D12A3184E00C43A7D /* OSBasics.h */; };
@@ -205,6 +207,8 @@
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
 		6D8656A812AF5FCD008A486E /* PolyString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyString.h; sourceTree = "<group>"; };
 		6D8656A812AF5FCD008A486E /* PolyString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyString.h; sourceTree = "<group>"; };
 		6D8656AA12AF5FD5008A486E /* PolyString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolyString.cpp; sourceTree = "<group>"; };
 		6D8656AA12AF5FD5008A486E /* PolyString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolyString.cpp; sourceTree = "<group>"; };
+		6D865AC112B07363008A486E /* PolyData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyData.h; sourceTree = "<group>"; };
+		6D865AC312B0736C008A486E /* PolyData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolyData.cpp; sourceTree = "<group>"; };
 		6DFB016E12A73BC200C43A7D /* PolyModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyModule.h; sourceTree = "<group>"; };
 		6DFB016E12A73BC200C43A7D /* PolyModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyModule.h; sourceTree = "<group>"; };
 		6DFB017012A73BCF00C43A7D /* PolyModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolyModule.cpp; sourceTree = "<group>"; };
 		6DFB017012A73BCF00C43A7D /* PolyModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolyModule.cpp; sourceTree = "<group>"; };
 		6DFBF30D12A3184E00C43A7D /* OSBasics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSBasics.h; sourceTree = "<group>"; };
 		6DFBF30D12A3184E00C43A7D /* OSBasics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSBasics.h; sourceTree = "<group>"; };
@@ -454,6 +458,7 @@
 		6DFBF30B12A3184E00C43A7D /* Include */ = {
 		6DFBF30B12A3184E00C43A7D /* Include */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				6D865AC112B07363008A486E /* PolyData.h */,
 				6D8656A812AF5FCD008A486E /* PolyString.h */,
 				6D8656A812AF5FCD008A486E /* PolyString.h */,
 				6DFBF30D12A3184E00C43A7D /* OSBasics.h */,
 				6DFBF30D12A3184E00C43A7D /* OSBasics.h */,
 				6DFBF30E12A3184E00C43A7D /* Poly_iPhone.h */,
 				6DFBF30E12A3184E00C43A7D /* Poly_iPhone.h */,
@@ -552,6 +557,7 @@
 		6DFBF36612A3184E00C43A7D /* Source */ = {
 		6DFBF36612A3184E00C43A7D /* Source */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				6D865AC312B0736C008A486E /* PolyData.cpp */,
 				6D8656AA12AF5FD5008A486E /* PolyString.cpp */,
 				6D8656AA12AF5FD5008A486E /* PolyString.cpp */,
 				6DFBF36712A3184E00C43A7D /* OSBasics.cpp */,
 				6DFBF36712A3184E00C43A7D /* OSBasics.cpp */,
 				6DFBF36812A3184E00C43A7D /* PolyAGLCore.cpp */,
 				6DFBF36812A3184E00C43A7D /* PolyAGLCore.cpp */,
@@ -778,6 +784,7 @@
 				6DFBF77A12A383AF00C43A7D /* physfs.h in Headers */,
 				6DFBF77A12A383AF00C43A7D /* physfs.h in Headers */,
 				6DFB016F12A73BC200C43A7D /* PolyModule.h in Headers */,
 				6DFB016F12A73BC200C43A7D /* PolyModule.h in Headers */,
 				6D8656A912AF5FCD008A486E /* PolyString.h in Headers */,
 				6D8656A912AF5FCD008A486E /* PolyString.h in Headers */,
+				6D865AC212B07363008A486E /* PolyData.h in Headers */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -928,6 +935,7 @@
 				6DFBF7B812A3846A00C43A7D /* unix.c in Sources */,
 				6DFBF7B812A3846A00C43A7D /* unix.c in Sources */,
 				6DFB017112A73BCF00C43A7D /* PolyModule.cpp in Sources */,
 				6DFB017112A73BCF00C43A7D /* PolyModule.cpp in Sources */,
 				6D8656AB12AF5FD5008A486E /* PolyString.cpp in Sources */,
 				6D8656AB12AF5FD5008A486E /* PolyString.cpp in Sources */,
+				6D865AC412B0736C008A486E /* PolyData.cpp in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};

+ 27 - 0
Core/Contents/Include/PolyData.h

@@ -0,0 +1,27 @@
+
+
+#include "PolyGlobals.h"
+#include "PolyString.h"
+#include "OSBasics.h"
+
+namespace _PolyExport Polycode {
+
+	class Data {
+		public:
+			Data();
+			~Data();
+		
+		void loadFromFile(String fileName);
+		String getAsString(int encoding);
+		void setFromString(String str, int encoding);
+		bool saveToFile(String fileName);
+		char *getData() { return data; }
+				
+		protected:
+
+			long dataSize;
+			char *data;
+		
+	};
+
+}

+ 16 - 1
Core/Contents/Include/PolyString.h

@@ -9,12 +9,19 @@ using std::vector;
 
 
 using namespace std;
 using namespace std;
 
 
+typedef std::string Str;
+typedef std::wstring WStr;
+
+void utf8toWStr(WStr& dest, const Str& src);
+void wstrToUtf8(Str& dest, const WStr& src);	
+
 namespace Polycode {
 namespace Polycode {
 
 
 	class _PolyExport String {
 	class _PolyExport String {
 		public:
 		public:
 			String();
 			String();
 			String(const wchar_t *str);
 			String(const wchar_t *str);
+			String(const wchar_t *str, size_t n);		
 			String(const char *str);
 			String(const char *str);
 			String(string str);
 			String(string str);
 			String(wstring str);
 			String(wstring str);
@@ -57,10 +64,18 @@ namespace Polycode {
 		
 		
 			const wchar_t *data(){ return contents.data(); }
 			const wchar_t *data(){ return contents.data(); }
 
 
+			const char *getDataWithEncoding(int encoding);
+			void setDataWithEncoding(char *data, int encoding);	
+			size_t getDataSizeWithEncoding(int encoding);
+		
 			wstring contents;	
 			wstring contents;	
 			string s_contents;
 			string s_contents;
+		
+			static const int ENCODING_UTF8 = 0; 
+			
+		
 		private:
 		private:
-
+		
 	};
 	};
 
 
 	static inline String operator+ (const char *str, const String &rstr) { return String(String(str).contents + rstr.contents); }
 	static inline String operator+ (const char *str, const String &rstr) { return String(String(str).contents + rstr.contents); }

+ 1 - 0
Core/Contents/Include/Polycode.h

@@ -10,6 +10,7 @@
 #pragma once
 #pragma once
 
 
 #include "PolyString.h"
 #include "PolyString.h"
+#include "PolyData.h"
 #include "PolyLogger.h"
 #include "PolyLogger.h"
 #include "PolyConfig.h"
 #include "PolyConfig.h"
 #include "PolyEntity.h"
 #include "PolyEntity.h"

+ 66 - 0
Core/Contents/Source/PolyData.cpp

@@ -0,0 +1,66 @@
+
+#include "PolyData.h"
+
+
+using namespace Polycode;
+
+Data::Data() {
+	data = NULL;
+	dataSize = 0;
+}
+
+Data::~Data() {
+	if(data)
+		free(data);
+}
+
+void Data::setFromString(String str, int encoding) {
+	if(data)
+		free(data);
+
+	dataSize = str.getDataSizeWithEncoding(encoding);
+	data = (char*)malloc(dataSize);
+	memcpy(data, str.getDataWithEncoding(encoding), dataSize);
+}
+
+bool Data::saveToFile(String fileName) {
+	
+	OSFILE *file = OSBasics::open(fileName, "wb");
+	
+	if(!file) {
+		OSBasics::close(file);		
+		return false;
+	}
+	
+	OSBasics::write(data, sizeof(char), dataSize, file);	
+	OSBasics::close(file);	
+	
+	return true;
+}
+
+void Data::loadFromFile(String fileName) {
+	OSFILE *file = OSBasics::open(fileName, "rb");
+	
+	OSBasics::seek(file, 0L, SEEK_END);
+	dataSize = OSBasics::tell(file);
+	OSBasics::seek(file, 0L, SEEK_SET);
+	
+	if(data)
+		free(data);
+	
+	data = (char*)malloc(dataSize);
+	if(!data) {
+		OSBasics::close(file);		
+		return;
+	}
+	
+	OSBasics::read(data, sizeof(char), dataSize, file);	
+	OSBasics::close(file);
+		
+}
+
+String Data::getAsString(int encoding) {
+	String str;
+	str.setDataWithEncoding(data, encoding);
+	return str;
+}

+ 135 - 8
Core/Contents/Source/PolyString.cpp

@@ -16,6 +16,10 @@ String::String(const char *str) {
 	contents.assign(sstr.begin(), sstr.end());
 	contents.assign(sstr.begin(), sstr.end());
 }
 }
 
 
+String::String(const wchar_t *str, size_t n) {
+	contents = wstring(str, n);
+}
+
 String::String(string str) {
 String::String(string str) {
 	contents.assign(str.begin(), str.end());	
 	contents.assign(str.begin(), str.end());	
 }
 }
@@ -28,18 +32,69 @@ String::~String() {
 	
 	
 }
 }
 
 
+size_t String::getDataSizeWithEncoding(int encoding) {
+	switch(encoding) {
+		case ENCODING_UTF8: {
+			string dest;
+			wstrToUtf8(dest, contents);
+			return dest.size();
+		}
+		default:
+			return NULL;
+	}
+}
+
+const char *String::getDataWithEncoding(int encoding) {
+	switch(encoding) {
+		case ENCODING_UTF8: {
+			string dest;
+			wstrToUtf8(dest, contents);
+			return dest.data();
+		}
+		break;
+		default:
+			return NULL;
+	}
+}
+
+void String::setDataWithEncoding(char *data, int encoding) {
+	switch(encoding) {
+		case ENCODING_UTF8: {
+			string str = string(data);
+			utf8toWStr(contents, str);
+		}
+		default:
+			break;
+	}
+}
+
 
 
 vector<String> String::split(const String &delims) {
 vector<String> String::split(const String &delims) {
-	wstring::size_type lastPos = contents.find_first_not_of(delims.contents, 0);
-	wstring::size_type pos     = contents.find_first_of(delims.contents, lastPos);
 	
 	
 	vector<String> tokens;
 	vector<String> tokens;
+	bool trimEmpty = false;
 	
 	
-	while (wstring::npos != pos || wstring::npos != lastPos) {
-		tokens.push_back(String(contents.substr(lastPos, pos - lastPos)));
-		lastPos = contents.find_first_not_of(delims.contents, pos);
-		pos = contents.find_first_of(delims.contents, lastPos);
-    }
+		std::wstring::size_type pos, lastPos = 0;
+		while(true)
+		{
+			pos = contents.find_first_of(delims.contents, lastPos);
+			if(pos == std::wstring::npos)
+			{
+				pos = contents.length();
+				
+				if(pos != lastPos || !trimEmpty)
+					tokens.push_back(vector<String>::value_type(contents.data()+lastPos, (wstring::size_type)pos-lastPos ));
+				
+				break;
+			}
+			else
+			{
+				if(pos != lastPos || !trimEmpty)
+					tokens.push_back(vector<String>::value_type(contents.data()+lastPos, (wstring::size_type)pos-lastPos ));
+			}
+			
+			lastPos = pos + 1;
+		}	
 	
 	
 	return tokens;
 	return tokens;
 }
 }
@@ -85,4 +140,76 @@ const char *String::c_str() {
 
 
 const wchar_t *String::wc_str() {
 const wchar_t *String::wc_str() {
 	return contents.c_str();
 	return contents.c_str();
-}
+}
+
+
+void utf8toWStr(WStr& dest, const Str& src){
+	dest.clear();
+	wchar_t w = 0;
+	int bytes = 0;
+	wchar_t err = L'�';
+	for (size_t i = 0; i < src.size(); i++){
+		unsigned char c = (unsigned char)src[i];
+		if (c <= 0x7f){//first byte
+			if (bytes){
+				dest.push_back(err);
+				bytes = 0;
+			}
+			dest.push_back((wchar_t)c);
+		}
+		else if (c <= 0xbf){//second/third/etc byte
+			if (bytes){
+				w = ((w << 6)|(c & 0x3f));
+				bytes--;
+				if (bytes == 0)
+					dest.push_back(w);
+			}
+			else
+				dest.push_back(err);
+		}
+		else if (c <= 0xdf){//2byte sequence start
+			bytes = 1;
+			w = c & 0x1f;
+		}
+		else if (c <= 0xef){//3byte sequence start
+			bytes = 2;
+			w = c & 0x0f;
+		}
+		else if (c <= 0xf7){//3byte sequence start
+			bytes = 3;
+			w = c & 0x07;
+		}
+		else{
+			dest.push_back(err);
+			bytes = 0;
+		}
+	}
+	if (bytes)
+		dest.push_back(err);
+}
+
+void wstrToUtf8(Str& dest, const WStr& src){
+	dest.clear();
+	for (size_t i = 0; i < src.size(); i++){
+		wchar_t w = src[i];
+		if (w <= 0x7f)
+			dest.push_back((char)w);
+		else if (w <= 0x7ff){
+			dest.push_back(0xc0 | ((w >> 6)& 0x1f));
+			dest.push_back(0x80| (w & 0x3f));
+		}
+		else if (w <= 0xffff){
+			dest.push_back(0xe0 | ((w >> 12)& 0x0f));
+			dest.push_back(0x80| ((w >> 6) & 0x3f));
+			dest.push_back(0x80| (w & 0x3f));
+		}
+		else if (w <= 0x10ffff){
+			dest.push_back(0xf0 | ((w >> 18)& 0x07));
+			dest.push_back(0x80| ((w >> 12) & 0x3f));
+			dest.push_back(0x80| ((w >> 6) & 0x3f));
+			dest.push_back(0x80| (w & 0x3f));
+		}
+		else
+			dest.push_back('?');
+	}
+}

+ 16 - 9
IDE/Build/Mac OS X/English.lproj/MainMenu.xib

@@ -721,14 +721,6 @@
 					</object>
 					</object>
 					<int key="connectionID">245</int>
 					<int key="connectionID">245</int>
 				</object>
 				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBActionConnection" key="connection">
-						<string key="label">saveDocument:</string>
-						<reference key="source" ref="1014"/>
-						<reference key="destination" ref="1023925487"/>
-					</object>
-					<int key="connectionID">362</int>
-				</object>
 				<object class="IBConnectionRecord">
 				<object class="IBConnectionRecord">
 					<object class="IBActionConnection" key="connection">
 					<object class="IBActionConnection" key="connection">
 						<string key="label">saveDocumentAs:</string>
 						<string key="label">saveDocumentAs:</string>
@@ -849,6 +841,14 @@
 					</object>
 					</object>
 					<int key="connectionID">549</int>
 					<int key="connectionID">549</int>
 				</object>
 				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">saveFile:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="1023925487"/>
+					</object>
+					<int key="connectionID">550</int>
+				</object>
 			</object>
 			</object>
 			<object class="IBMutableOrderedSet" key="objectRecords">
 			<object class="IBMutableOrderedSet" key="objectRecords">
 				<object class="NSArray" key="orderedObjects">
 				<object class="NSArray" key="orderedObjects">
@@ -1604,7 +1604,7 @@
 				</object>
 				</object>
 			</object>
 			</object>
 			<nil key="sourceID"/>
 			<nil key="sourceID"/>
-			<int key="maxID">549</int>
+			<int key="maxID">550</int>
 		</object>
 		</object>
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
 			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1618,11 +1618,13 @@
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>newProject:</string>
 							<string>newProject:</string>
 							<string>openProject:</string>
 							<string>openProject:</string>
+							<string>saveFile:</string>
 						</object>
 						</object>
 						<object class="NSMutableArray" key="dict.values">
 						<object class="NSMutableArray" key="dict.values">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>id</string>
 							<string>id</string>
 							<string>id</string>
 							<string>id</string>
+							<string>id</string>
 						</object>
 						</object>
 					</object>
 					</object>
 					<object class="NSMutableDictionary" key="actionInfosByName">
 					<object class="NSMutableDictionary" key="actionInfosByName">
@@ -1631,6 +1633,7 @@
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>newProject:</string>
 							<string>newProject:</string>
 							<string>openProject:</string>
 							<string>openProject:</string>
+							<string>saveFile:</string>
 						</object>
 						</object>
 						<object class="NSMutableArray" key="dict.values">
 						<object class="NSMutableArray" key="dict.values">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1642,6 +1645,10 @@
 								<string key="name">openProject:</string>
 								<string key="name">openProject:</string>
 								<string key="candidateClassName">id</string>
 								<string key="candidateClassName">id</string>
 							</object>
 							</object>
+							<object class="IBActionInfo">
+								<string key="name">saveFile:</string>
+								<string key="candidateClassName">id</string>
+							</object>
 						</object>
 						</object>
 					</object>
 					</object>
 					<object class="NSMutableDictionary" key="outlets">
 					<object class="NSMutableDictionary" key="outlets">

+ 1 - 0
IDE/Build/Mac OS X/PolycodeAppDelegate.h

@@ -26,5 +26,6 @@
 
 
 -(void) newProject: (id) sender;
 -(void) newProject: (id) sender;
 -(void) openProject: (id) sender;
 -(void) openProject: (id) sender;
+-(void) saveFile: (id) sender;
 
 
 @end
 @end

+ 4 - 0
IDE/Build/Mac OS X/PolycodeAppDelegate.m

@@ -42,4 +42,8 @@
 	app->openProject();
 	app->openProject();
 }
 }
 
 
+-(void) saveFile: (id) sender {
+	app->saveFile();
+}
+
 @end
 @end

+ 2 - 0
IDE/Contents/Include/PolycodeEditor.h

@@ -13,6 +13,8 @@ public:
 	virtual bool openFile(String filePath){ this->filePath = filePath; }
 	virtual bool openFile(String filePath){ this->filePath = filePath; }
 	virtual void Resize(int x, int y) = 0;
 	virtual void Resize(int x, int y) = 0;
 	
 	
+	virtual void saveFile(){};
+	
 	String getFilePath() { return filePath; }
 	String getFilePath() { return filePath; }
 	
 	
 	bool isReadOnly() { return _isReadOnly; }
 	bool isReadOnly() { return _isReadOnly; }

+ 5 - 1
IDE/Contents/Include/PolycodeEditorManager.h

@@ -15,9 +15,13 @@ class PolycodeEditorManager {
 		PolycodeEditor *createEditorForExtension(String extension);
 		PolycodeEditor *createEditorForExtension(String extension);
 		void registerEditorFactory(PolycodeEditorFactory *editorFactory);
 		void registerEditorFactory(PolycodeEditorFactory *editorFactory);
 	
 	
+		void setCurrentEditor(PolycodeEditor *editor) { currentEditor = editor; }
+		PolycodeEditor *getCurrentEditor() { return currentEditor; }
 		
 		
-	
 protected:
 protected:
+	
+	PolycodeEditor *currentEditor;
+	
 	vector<PolycodeEditor*> openEditors;
 	vector<PolycodeEditor*> openEditors;
 	vector<PolycodeEditorFactory*> editorFactories;	
 	vector<PolycodeEditorFactory*> editorFactories;	
 };
 };

+ 1 - 0
IDE/Contents/Include/PolycodeIDEApp.h

@@ -34,6 +34,7 @@ public:
 	// menu commands
 	// menu commands
 	void newProject();
 	void newProject();
 	void openProject();
 	void openProject();
+	void saveFile();
 	
 	
 protected:	
 protected:	
 	PolycodeFrame *frame;
 	PolycodeFrame *frame;

+ 1 - 0
IDE/Contents/Include/PolycodeTextEditor.h

@@ -15,6 +15,7 @@ public:
 	
 	
 	bool openFile(String filePath);
 	bool openFile(String filePath);
 	void Resize(int x, int y);
 	void Resize(int x, int y);
+	void saveFile();	
 	
 	
 protected:
 protected:
 
 

+ 1 - 1
IDE/Contents/Source/PolycodeEditorManager.cpp

@@ -3,7 +3,7 @@
 
 
 
 
 PolycodeEditorManager::PolycodeEditorManager() {
 PolycodeEditorManager::PolycodeEditorManager() {
-	
+	currentEditor = NULL;
 }
 }
 
 
 PolycodeEditorManager::~PolycodeEditorManager() {
 PolycodeEditorManager::~PolycodeEditorManager() {

+ 10 - 0
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -72,6 +72,10 @@ void PolycodeIDEApp::openProject() {
 	}
 	}
 }
 }
 
 
+void PolycodeIDEApp::saveFile() {
+	editorManager->getCurrentEditor()->saveFile();
+}
+
 void PolycodeIDEApp::handleEvent(Event *event) {
 void PolycodeIDEApp::handleEvent(Event *event) {
 	if(event->getDispatcher() == core) {
 	if(event->getDispatcher() == core) {
 		switch(event->getEventCode()) {
 		switch(event->getEventCode()) {
@@ -98,9 +102,15 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 						frame->showEditor(editor);
 						frame->showEditor(editor);
 					} else {
 					} else {
 						delete editor;
 						delete editor;
+						editor = NULL;
 					}
 					}
 				}
 				}
 			}
 			}
+				
+				if(editor) {
+					editorManager->setCurrentEditor(editor);
+				}
+				
 			}
 			}
 		}
 		}
 	}	
 	}	

+ 12 - 1
IDE/Contents/Source/PolycodeTextEditor.cpp

@@ -12,14 +12,25 @@ PolycodeTextEditor::~PolycodeTextEditor() {
 
 
 bool PolycodeTextEditor::openFile(String filePath) {
 bool PolycodeTextEditor::openFile(String filePath) {
 	
 	
-	textInput = new UITextInput(true, 600, 550);
+	textInput = new UITextInput(true, 100, 100);
 	addChild(textInput);	
 	addChild(textInput);	
 	
 	
+	Data *data = new Data();
+	data->loadFromFile(filePath);	
+	textInput->insertText(data->getAsString(String::ENCODING_UTF8));
+	delete data;
 	
 	
 	PolycodeEditor::openFile(filePath);
 	PolycodeEditor::openFile(filePath);
 	return true;
 	return true;
 }
 }
 
 
+void PolycodeTextEditor::saveFile() {
+	Data *data = new Data();
+	data->setFromString(textInput->getText(), String::ENCODING_UTF8);
+	data->saveToFile(filePath);
+	delete data;
+}
+
 void PolycodeTextEditor::Resize(int x, int y) {
 void PolycodeTextEditor::Resize(int x, int y) {
 	textInput->Resize(x,y);
 	textInput->Resize(x,y);
 }
 }

+ 1 - 0
Modules/Contents/UI/Include/PolyUITextInput.h

@@ -35,6 +35,7 @@ namespace Polycode {
 			void onLoseFocus();
 			void onLoseFocus();
 		
 		
 			int insertLine(bool after);
 			int insertLine(bool after);
+		
 			
 			
 			void onKeyDown(TAUKey key, wchar_t charCode);
 			void onKeyDown(TAUKey key, wchar_t charCode);
 		
 		

+ 15 - 1
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -487,7 +487,21 @@ void UITextInput::selectAll() {
 }
 }
 
 
 void UITextInput::insertText(String text) {
 void UITextInput::insertText(String text) {
-	
+	vector<String> strings = text.split("\n");
+	int numLines = lines.size();
+	for(int i=0; i < strings.size(); i++) {
+		if(i < numLines) {
+			lines[i]->setText(strings[i]);
+		} else {
+			numLines++;	
+			ScreenLabel *newLine = new ScreenLabel(fontName, L"", fontSize, Label::ANTIALIAS_FULL);
+			newLine->setColor(0,0,0,1);
+			addChild(newLine);			
+			lines.push_back(newLine);
+			newLine->setText(strings[i]);
+		}
+	}
+	restructLines();	
 }
 }
 
 
 String UITextInput::getSelectionText() {
 String UITextInput::getSelectionText() {