editor: replace document when loading
Simplify the book-keeping a bit by simply creating a new document when loading. Copy the ClientSocket to the new document to keep client-state.
This commit is contained in:
parent
9132474bdb
commit
3178f22c2a
@ -59,7 +59,6 @@ HWND hwnd = NULL;
|
|||||||
TrackView *trackView = NULL;
|
TrackView *trackView = NULL;
|
||||||
HWND trackViewWin = NULL;
|
HWND trackViewWin = NULL;
|
||||||
HWND statusBarWin = NULL;
|
HWND statusBarWin = NULL;
|
||||||
SyncDocument document;
|
|
||||||
HKEY regConfigKey = NULL;
|
HKEY regConfigKey = NULL;
|
||||||
RecentFiles mruFileList(NULL);
|
RecentFiles mruFileList(NULL);
|
||||||
|
|
||||||
@ -190,38 +189,64 @@ HMENU findSubMenuContaining(HMENU menu, UINT id)
|
|||||||
return (HMENU)0;
|
return (HMENU)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fileNew()
|
void setDocument(SyncDocument *newDoc)
|
||||||
{
|
{
|
||||||
// document.purgeUnusedTracks();
|
SyncDocument *oldDoc = trackView->getDocument();
|
||||||
SyncDocument::MultiCommand *multiCmd = new SyncDocument::MultiCommand();
|
|
||||||
for (size_t i = 0; i < document.num_tracks; ++i) {
|
if (oldDoc && oldDoc->clientSocket.connected()) {
|
||||||
sync_track *t = document.tracks[i];
|
// delete old key-frames
|
||||||
for (size_t j = 0; j < t->num_keys; ++j)
|
for (size_t i = 0; i < oldDoc->num_tracks; ++i) {
|
||||||
multiCmd->addCommand(new SyncDocument::DeleteCommand(i, t->keys[j].row));
|
sync_track *t = oldDoc->tracks[i];
|
||||||
|
for (size_t j = 0; j < t->num_keys; ++j)
|
||||||
|
oldDoc->clientSocket.sendDeleteKeyCommand(t->name, t->keys[j].row);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newDoc) {
|
||||||
|
// add back missing client-tracks
|
||||||
|
std::map<const std::string, size_t>::const_iterator it;
|
||||||
|
for (it = oldDoc->clientSocket.clientTracks.begin(); it != oldDoc->clientSocket.clientTracks.end(); ++it) {
|
||||||
|
int trackIndex = sync_find_track(newDoc, it->first.c_str());
|
||||||
|
if (0 > trackIndex)
|
||||||
|
trackIndex = int(newDoc->createTrack(it->first.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy socket and update client
|
||||||
|
newDoc->clientSocket = oldDoc->clientSocket;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < newDoc->num_tracks; ++i) {
|
||||||
|
sync_track *t = newDoc->tracks[i];
|
||||||
|
for (size_t j = 0; j < t->num_keys; ++j)
|
||||||
|
newDoc->clientSocket.sendSetKeyCommand(t->name, t->keys[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
document.exec(multiCmd);
|
|
||||||
|
|
||||||
setWindowFileName(L"Untitled");
|
trackView->setDocument(newDoc);
|
||||||
document.fileName.clear();
|
SendMessage(hwnd, WM_CURRVALDIRTY, 0, 0);
|
||||||
|
InvalidateRect(trackViewWin, NULL, FALSE);
|
||||||
|
|
||||||
document.clearUndoStack();
|
if (oldDoc)
|
||||||
document.clearRedoStack();
|
delete oldDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fileNew()
|
||||||
|
{
|
||||||
|
setDocument(new SyncDocument);
|
||||||
|
setWindowFileName(L"Untitled");
|
||||||
|
}
|
||||||
|
|
||||||
void loadDocument(const std::wstring &_fileName)
|
void loadDocument(const std::wstring &_fileName)
|
||||||
{
|
{
|
||||||
if (document.load(_fileName)) {
|
SyncDocument *newDoc = SyncDocument::load(_fileName);
|
||||||
setWindowFileName(_fileName.c_str());
|
if (newDoc) {
|
||||||
|
// update MRU list
|
||||||
mruFileList.insert(_fileName);
|
mruFileList.insert(_fileName);
|
||||||
mruFileList.update();
|
mruFileList.update();
|
||||||
DrawMenuBar(hwnd);
|
DrawMenuBar(hwnd);
|
||||||
|
|
||||||
trackView->setDocument(&document);
|
// set new document
|
||||||
|
setDocument(newDoc);
|
||||||
SendMessage(hwnd, WM_CURRVALDIRTY, 0, 0);
|
setWindowFileName(_fileName.c_str());
|
||||||
InvalidateRect(trackViewWin, NULL, FALSE);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error("failed to open file");
|
error("failed to open file");
|
||||||
@ -261,10 +286,11 @@ bool fileSaveAs()
|
|||||||
ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
|
ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
|
||||||
|
|
||||||
if (GetSaveFileNameW(&ofn)) {
|
if (GetSaveFileNameW(&ofn)) {
|
||||||
if (document.save(temp)) {
|
SyncDocument *doc = trackView->getDocument();
|
||||||
document.clientSocket.sendSaveCommand();
|
if (doc->save(temp)) {
|
||||||
|
doc->clientSocket.sendSaveCommand();
|
||||||
setWindowFileName(temp);
|
setWindowFileName(temp);
|
||||||
document.fileName = temp;
|
doc->fileName = temp;
|
||||||
|
|
||||||
mruFileList.insert(temp);
|
mruFileList.insert(temp);
|
||||||
mruFileList.update();
|
mruFileList.update();
|
||||||
@ -278,11 +304,12 @@ bool fileSaveAs()
|
|||||||
|
|
||||||
bool fileSave()
|
bool fileSave()
|
||||||
{
|
{
|
||||||
if (document.fileName.empty())
|
SyncDocument *doc = trackView->getDocument();
|
||||||
|
if (doc->fileName.empty())
|
||||||
return fileSaveAs();
|
return fileSaveAs();
|
||||||
|
|
||||||
if (!document.save(document.fileName)) {
|
if (!doc->save(doc->fileName)) {
|
||||||
document.clientSocket.sendSaveCommand();
|
doc->clientSocket.sendSaveCommand();
|
||||||
error("Failed to save file");
|
error("Failed to save file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -291,8 +318,8 @@ bool fileSave()
|
|||||||
|
|
||||||
void attemptQuit()
|
void attemptQuit()
|
||||||
{
|
{
|
||||||
if (document.modified())
|
SyncDocument *doc = trackView->getDocument();
|
||||||
{
|
if (doc->modified()) {
|
||||||
UINT res = MessageBox(hwnd, "Save before exit?", mainWindowTitle, MB_YESNOCANCEL | MB_ICONQUESTION);
|
UINT res = MessageBox(hwnd, "Save before exit?", mainWindowTitle, MB_YESNOCANCEL | MB_ICONQUESTION);
|
||||||
if ((IDYES == res && fileSave()) || (IDNO == res))
|
if ((IDYES == res && fileSave()) || (IDNO == res))
|
||||||
DestroyWindow(hwnd);
|
DestroyWindow(hwnd);
|
||||||
@ -325,6 +352,7 @@ static HWND createStatusBar(HINSTANCE hInstance, HWND hpwnd)
|
|||||||
|
|
||||||
static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
SyncDocument *doc = trackView ? trackView->getDocument() : NULL;
|
||||||
switch(msg)
|
switch(msg)
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
@ -415,7 +443,7 @@ static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_FILE_REMOTEEXPORT:
|
case ID_FILE_REMOTEEXPORT:
|
||||||
document.clientSocket.sendSaveCommand();
|
doc->clientSocket.sendSaveCommand();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_RECENTFILES_FILE1:
|
case ID_RECENTFILES_FILE1:
|
||||||
@ -482,8 +510,8 @@ static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA
|
|||||||
case WM_CURRVALDIRTY:
|
case WM_CURRVALDIRTY:
|
||||||
{
|
{
|
||||||
char temp[256];
|
char temp[256];
|
||||||
if (document.num_tracks > 0) {
|
if (doc->num_tracks > 0) {
|
||||||
const sync_track *t = document.tracks[document.getTrackIndexFromPos(trackView->getEditTrack())];
|
const sync_track *t = doc->tracks[doc->getTrackIndexFromPos(trackView->getEditTrack())];
|
||||||
int row = trackView->getEditRow();
|
int row = trackView->getEditRow();
|
||||||
int idx = key_idx_floor(t, row);
|
int idx = key_idx_floor(t, row);
|
||||||
snprintf(temp, 256, "%f", sync_get_val(t, row));
|
snprintf(temp, 256, "%f", sync_get_val(t, row));
|
||||||
@ -557,6 +585,7 @@ SOCKET clientConnect(SOCKET serverSocket, sockaddr_in *host)
|
|||||||
size_t clientIndex;
|
size_t clientIndex;
|
||||||
void processCommand(ClientSocket &sock)
|
void processCommand(ClientSocket &sock)
|
||||||
{
|
{
|
||||||
|
SyncDocument *doc = trackView->getDocument();
|
||||||
int strLen, serverIndex, newRow;
|
int strLen, serverIndex, newRow;
|
||||||
std::string trackName;
|
std::string trackName;
|
||||||
const sync_track *t;
|
const sync_track *t;
|
||||||
@ -575,19 +604,19 @@ void processCommand(ClientSocket &sock)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// find track
|
// find track
|
||||||
serverIndex = sync_find_track(&document,
|
serverIndex = sync_find_track(doc,
|
||||||
trackName.c_str());
|
trackName.c_str());
|
||||||
if (0 > serverIndex)
|
if (0 > serverIndex)
|
||||||
serverIndex =
|
serverIndex =
|
||||||
int(document.createTrack(trackName));
|
int(doc->createTrack(trackName));
|
||||||
|
|
||||||
// setup remap
|
// setup remap
|
||||||
document.clientSocket.clientTracks[trackName] = clientIndex++;
|
doc->clientSocket.clientTracks[trackName] = clientIndex++;
|
||||||
|
|
||||||
// send key-frames
|
// send key-frames
|
||||||
t = document.tracks[serverIndex];
|
t = doc->tracks[serverIndex];
|
||||||
for (int i = 0; i < (int)t->num_keys; ++i)
|
for (int i = 0; i < (int)t->num_keys; ++i)
|
||||||
document.clientSocket.sendSetKeyCommand(trackName,
|
doc->clientSocket.sendSetKeyCommand(trackName,
|
||||||
t->keys[i]);
|
t->keys[i]);
|
||||||
|
|
||||||
InvalidateRect(trackViewWin, NULL, FALSE);
|
InvalidateRect(trackViewWin, NULL, FALSE);
|
||||||
@ -641,7 +670,6 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
|
|||||||
die("Window Registration Failed!");
|
die("Window Registration Failed!");
|
||||||
|
|
||||||
trackView = new TrackView();
|
trackView = new TrackView();
|
||||||
trackView->setDocument(&document);
|
|
||||||
|
|
||||||
hwnd = CreateWindowExW(
|
hwnd = CreateWindowExW(
|
||||||
0,
|
0,
|
||||||
@ -666,10 +694,9 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
|
|||||||
bool done = false;
|
bool done = false;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
bool guiConnected = false;
|
bool guiConnected = false;
|
||||||
while (!done)
|
while (!done) {
|
||||||
{
|
SyncDocument *doc = trackView->getDocument();
|
||||||
if (!document.clientSocket.connected())
|
if (!doc->clientSocket.connected()) {
|
||||||
{
|
|
||||||
SOCKET clientSocket = INVALID_SOCKET;
|
SOCKET clientSocket = INVALID_SOCKET;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
@ -690,26 +717,26 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
|
|||||||
char temp[256];
|
char temp[256];
|
||||||
snprintf(temp, 256, "Connected to %s", inet_ntoa(client.sin_addr));
|
snprintf(temp, 256, "Connected to %s", inet_ntoa(client.sin_addr));
|
||||||
SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)temp);
|
SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)temp);
|
||||||
document.clientSocket = ClientSocket(clientSocket);
|
doc->clientSocket = ClientSocket(clientSocket);
|
||||||
clientIndex = 0;
|
clientIndex = 0;
|
||||||
document.clientSocket.sendPauseCommand(true);
|
doc->clientSocket.sendPauseCommand(true);
|
||||||
document.clientSocket.sendSetRowCommand(trackView->getEditRow());
|
doc->clientSocket.sendSetRowCommand(trackView->getEditRow());
|
||||||
guiConnected = true;
|
guiConnected = true;
|
||||||
}
|
}
|
||||||
else SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Not Connected.");
|
else SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Not Connected.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.clientSocket.connected()) {
|
if (doc->clientSocket.connected()) {
|
||||||
ClientSocket &clientSocket = document.clientSocket;
|
ClientSocket &clientSocket = doc->clientSocket;
|
||||||
|
|
||||||
// look for new commands
|
// look for new commands
|
||||||
while (clientSocket.pollRead())
|
while (clientSocket.pollRead())
|
||||||
processCommand(clientSocket);
|
processCommand(clientSocket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!document.clientSocket.connected() && guiConnected) {
|
if (!doc->clientSocket.connected() && guiConnected) {
|
||||||
document.clientSocket.clientPaused = true;
|
doc->clientSocket.clientPaused = true;
|
||||||
InvalidateRect(trackViewWin, NULL, FALSE);
|
InvalidateRect(trackViewWin, NULL, FALSE);
|
||||||
SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Not Connected.");
|
SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Not Connected.");
|
||||||
guiConnected = false;
|
guiConnected = false;
|
||||||
|
|||||||
@ -10,21 +10,22 @@ SyncDocument::~SyncDocument()
|
|||||||
|
|
||||||
#import <msxml3.dll> named_guids
|
#import <msxml3.dll> named_guids
|
||||||
|
|
||||||
bool SyncDocument::load(const std::wstring &fileName)
|
SyncDocument *SyncDocument::load(const std::wstring &fileName)
|
||||||
{
|
{
|
||||||
|
SyncDocument *ret = new SyncDocument;
|
||||||
|
ret->fileName = fileName;
|
||||||
|
|
||||||
MSXML2::IXMLDOMDocumentPtr doc(MSXML2::CLSID_DOMDocument);
|
MSXML2::IXMLDOMDocumentPtr doc(MSXML2::CLSID_DOMDocument);
|
||||||
try {
|
try {
|
||||||
SyncDocument::MultiCommand *multiCmd = new SyncDocument::MultiCommand();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_tracks; ++i) {
|
|
||||||
sync_track *t = tracks[i];
|
|
||||||
for (size_t j = 0; j < t->num_keys; ++j)
|
|
||||||
multiCmd->addCommand(new SyncDocument::DeleteCommand(i, t->keys[j].row));
|
|
||||||
}
|
|
||||||
|
|
||||||
doc->load(fileName.c_str());
|
doc->load(fileName.c_str());
|
||||||
MSXML2::IXMLDOMNamedNodeMapPtr attribs = doc->documentElement->Getattributes();
|
MSXML2::IXMLDOMNamedNodeMapPtr attribs = doc->documentElement->Getattributes();
|
||||||
|
|
||||||
|
MSXML2::IXMLDOMNodePtr rowsParam = attribs->getNamedItem("rows");
|
||||||
|
if (rowsParam) {
|
||||||
|
std::string rowsString = rowsParam->Gettext();
|
||||||
|
ret->setRows(atoi(rowsString.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
MSXML2::IXMLDOMNodeListPtr trackNodes = doc->documentElement->selectNodes("track");
|
MSXML2::IXMLDOMNodeListPtr trackNodes = doc->documentElement->selectNodes("track");
|
||||||
for (int i = 0; i < trackNodes->Getlength(); ++i)
|
for (int i = 0; i < trackNodes->Getlength(); ++i)
|
||||||
{
|
{
|
||||||
@ -34,8 +35,8 @@ bool SyncDocument::load(const std::wstring &fileName)
|
|||||||
std::string name = attribs->getNamedItem("name")->Gettext();
|
std::string name = attribs->getNamedItem("name")->Gettext();
|
||||||
|
|
||||||
// look up track-name, create it if it doesn't exist
|
// look up track-name, create it if it doesn't exist
|
||||||
int trackIndex = sync_find_track(this, name.c_str());
|
int trackIndex = sync_find_track(ret, name.c_str());
|
||||||
if (0 > trackIndex) trackIndex = int(createTrack(name));
|
if (0 > trackIndex) trackIndex = int(ret->createTrack(name));
|
||||||
|
|
||||||
MSXML2::IXMLDOMNodeListPtr rowNodes = trackNode->GetchildNodes();
|
MSXML2::IXMLDOMNodeListPtr rowNodes = trackNode->GetchildNodes();
|
||||||
for (int i = 0; i < rowNodes->Getlength(); ++i)
|
for (int i = 0; i < rowNodes->Getlength(); ++i)
|
||||||
@ -53,34 +54,23 @@ bool SyncDocument::load(const std::wstring &fileName)
|
|||||||
k.row = atoi(rowString.c_str());
|
k.row = atoi(rowString.c_str());
|
||||||
k.value = float(atof(valueString.c_str()));
|
k.value = float(atof(valueString.c_str()));
|
||||||
k.type = key_type(atoi(interpolationString.c_str()));
|
k.type = key_type(atoi(interpolationString.c_str()));
|
||||||
multiCmd->addCommand(new InsertCommand(int(trackIndex), k));
|
|
||||||
|
assert(!is_key_frame(ret->tracks[trackIndex], key.row));
|
||||||
|
if (sync_set_key(ret->tracks[trackIndex], &k))
|
||||||
|
throw std::bad_alloc("sync_set_key");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MSXML2::IXMLDOMNodePtr rowsParam = attribs->getNamedItem("rows");
|
|
||||||
if (rowsParam) {
|
|
||||||
std::string rowsString = rowsParam->Gettext();
|
|
||||||
this->setRows(atoi(rowsString.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->fileName = fileName;
|
|
||||||
clearUndoStack();
|
|
||||||
clearRedoStack();
|
|
||||||
|
|
||||||
this->exec(multiCmd);
|
|
||||||
savePointDelta = 0;
|
|
||||||
savePointUnreachable = false;
|
|
||||||
}
|
}
|
||||||
catch(_com_error &e)
|
catch(_com_error &e)
|
||||||
{
|
{
|
||||||
char temp[256];
|
char temp[256];
|
||||||
_snprintf(temp, 256, "Error loading: %s\n", (const char*)_bstr_t(e.Description()));
|
_snprintf(temp, 256, "Error loading: %s\n", (const char*)_bstr_t(e.Description()));
|
||||||
MessageBox(NULL, temp, NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
|
MessageBox(NULL, temp, NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SyncDocument::save(const std::wstring &fileName)
|
bool SyncDocument::save(const std::wstring &fileName)
|
||||||
|
|||||||
@ -257,7 +257,7 @@ public:
|
|||||||
std::swap(trackOrder[t1], trackOrder[t2]);
|
std::swap(trackOrder[t1], trackOrder[t2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load(const std::wstring &fileName);
|
static SyncDocument *load(const std::wstring &fileName);
|
||||||
bool save(const std::wstring &fileName);
|
bool save(const std::wstring &fileName);
|
||||||
|
|
||||||
bool modified()
|
bool modified()
|
||||||
|
|||||||
@ -34,7 +34,8 @@ static int getMaxCharacterWidthFromString(HDC hdc, const char *chars)
|
|||||||
return getMaxCharacterWidth(hdc, chars, strlen(chars));
|
return getMaxCharacterWidth(hdc, chars, strlen(chars));
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackView::TrackView()
|
TrackView::TrackView() :
|
||||||
|
document(NULL)
|
||||||
{
|
{
|
||||||
scrollPosX = 0;
|
scrollPosX = 0;
|
||||||
scrollPosY = 0;
|
scrollPosY = 0;
|
||||||
@ -82,6 +83,8 @@ TrackView::~TrackView()
|
|||||||
DeleteObject(editBrush);
|
DeleteObject(editBrush);
|
||||||
DeleteObject(rowPen);
|
DeleteObject(rowPen);
|
||||||
DeleteObject(rowSelectPen);
|
DeleteObject(rowSelectPen);
|
||||||
|
if (document)
|
||||||
|
delete document;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackView::setFont(HFONT font)
|
void TrackView::setFont(HFONT font)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user