static int handle_set_key_cmd(SOCKET sock, struct sync_device *data) { uint32_t track, row; union { float f; uint32_t i; } v; struct track_key key; unsigned char type; if (xrecv(sock, (char *)&track, sizeof(track), 0) || xrecv(sock, (char *)&row, sizeof(row), 0) || xrecv(sock, (char *)&v.i, sizeof(v.i), 0) || xrecv(sock, (char *)&type, 1, 0)) return -1; track = ntohl(track); v.i = ntohl(v.i); key.row = ntohl(row); key.value = v.f; assert(type < KEY_TYPE_COUNT); assert(track < data->num_tracks); key.type = (enum key_type)type; return sync_set_key(data->tracks[track], &key); }
static void execInsertKey(void* userData) { struct InsertKeyData* data = (struct InsertKeyData*)userData; struct sync_track* t = s_syncTracks[data->track]; sync_set_key(t, &data->key); RemoteConnection_sendSetKeyCommand(t->name, &data->key); }
static void execUpdateKey(void* userData) { struct UpdateKeyData* data = (struct UpdateKeyData*)userData; struct sync_track* t = s_syncTracks[data->track]; int idx = sync_find_key(t, data->key.row); data->oldKey = t->keys[idx]; sync_set_key(t, &data->key); RemoteConnection_sendSetKeyCommand(t->name, &data->key); }
static void undoDeleteKey(void* userData) { struct DeleteKeyData* data = (struct DeleteKeyData*)userData; struct sync_track* t = s_syncTracks[data->track]; if (data->noDelete) return; sync_set_key(t, &data->oldKey); RemoteConnection_sendSetKeyCommand(t->name, &data->oldKey); }
static void parseXml(mxml_node_t* rootNode, TrackData* trackData) { struct track_key k; int g, i, foldedGroupCount = 0, is_key, track_index = 0; mxml_node_t* node = rootNode; free(trackData->bookmarks); trackData->bookmarks = NULL; trackData->bookmarkCount = 0; trackData->highlightRowStep = 8; // Traverse the tracks node data while (1) { node = mxmlWalkNext(node, rootNode, MXML_DESCEND); if (!node) break; switch (mxmlGetType(node)) { case MXML_ELEMENT: { const char* element_name = mxmlGetElement(node); if (!strcmp("bookmark", element_name)) { const char* row = mxmlElementGetAttr(node, "row"); if (row) TrackData_toggleBookmark(trackData, atoi(row)); } if (!strcmp("group", element_name)) { s_foldedGroupNames[foldedGroupCount++] = strdup(mxmlElementGetAttr(node, "name")); } if (!strcmp("tracks", element_name)) { const char* start_row = mxmlElementGetAttr(node, "startRow"); const char* end_row = mxmlElementGetAttr(node, "endRow"); const char* hlrow_step = mxmlElementGetAttr(node, "highlightRowStep"); if (start_row) trackData->startRow = atoi(start_row); if (end_row) trackData->endRow = atoi(end_row); if (hlrow_step) trackData->highlightRowStep = atoi(hlrow_step); } if (!strcmp("track", element_name)) { int i; struct sync_track* track; Track* t; // TODO: Create the new track/channel here const char* track_name = mxmlElementGetAttr(node, "name"); const char* color_text = mxmlElementGetAttr(node, "color"); const char* folded_text = mxmlElementGetAttr(node, "folded"); track_index = TrackData_createGetTrack(trackData, track_name); t = &trackData->tracks[track_index]; track = trackData->syncData.tracks[track_index]; if (!color_text && t->color == 0) { t->color = TrackData_getNextColor(trackData); } else { if (color_text) t->color = strtoul(color_text, 0, 16); } if (folded_text) { if (folded_text[0] == '1') t->folded = true; } // If we already have this track loaded we delete all the existing keys for (i = 0; i < track->num_keys; ++i) { int row = track->keys[i].row; RemoteConnection_sendDeleteKeyCommand(track->name, row); } free(track->keys); track->keys = 0; track->num_keys = 0; } else if (!strcmp("key", element_name)) { struct sync_track* track = trackData->syncData.tracks[track_index]; const char* row = mxmlElementGetAttr(node, "row"); const char* value = mxmlElementGetAttr(node, "value"); const char* interpolation = mxmlElementGetAttr(node, "interpolation"); k.row = atoi(row); k.value = (float)(atof(value)); k.type = (atoi(interpolation)); is_key = is_key_frame(track, k.row); assert(!is_key); sync_set_key(track, &k); RemoteConnection_sendSetKeyCommand(track->name, &k); } } default: break; } } TrackData_linkGroups(trackData); // Apply fold status on the groups for (i = 0; i < foldedGroupCount; ++i) { for (g = 0; g < trackData->groupCount; ++g) { Group* group = &trackData->groups[g]; const char* groupName = group->name; const char* foldedName = s_foldedGroupNames[i]; // groups with 1 track is handled as non-grouped if (group->trackCount == 1) continue; if (!strcmp(foldedName, groupName)) { trackData->groups[g].folded = true; break; } } free(s_foldedGroupNames[i]); } trackData->tracks[0].selected = true; }
SyncDocument *SyncDocument::load(const QString &fileName) { SyncDocument *ret = new SyncDocument; ret->fileName = fileName; QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(NULL, "Error", file.errorString()); return NULL; } QDomDocument doc; QString err; if (!doc.setContent(&file, &err)) { file.close(); QMessageBox::critical(NULL, "Error", err); return NULL; } file.close(); QDomNamedNodeMap attribs = doc.documentElement().attributes(); QDomNode rowsParam = attribs.namedItem("rows"); if (!rowsParam.isNull()) { QString rowsString = rowsParam.nodeValue(); ret->setRows(rowsString.toInt()); } QDomNodeList trackNodes = doc.documentElement().elementsByTagName("track"); for (int i = 0; i < int(trackNodes.length()); ++i) { QDomNode trackNode = trackNodes.item(i); QDomNamedNodeMap attribs = trackNode.attributes(); QString name = attribs.namedItem("name").nodeValue(); // look up track-name, create it if it doesn't exist int trackIndex = sync_find_track(ret, name.toUtf8()); if (0 > trackIndex) trackIndex = int(ret->createTrack(name.toUtf8().constData())); QDomNodeList rowNodes = trackNode.childNodes(); for (int i = 0; i < int(rowNodes.length()); ++i) { QDomNode keyNode = rowNodes.item(i); QString baseName = keyNode.nodeName(); if (baseName == "key") { QDomNamedNodeMap rowAttribs = keyNode.attributes(); QString rowString = rowAttribs.namedItem("row").nodeValue(); QString valueString = rowAttribs.namedItem("value").nodeValue(); QString interpolationString = rowAttribs.namedItem("interpolation").nodeValue(); track_key k; k.row = rowString.toInt(); k.value = valueString.toFloat(); k.type = key_type(interpolationString.toInt()); Q_ASSERT(!is_key_frame(ret->tracks[trackIndex], k.row)); if (sync_set_key(ret->tracks[trackIndex], &k)) qFatal("failed to insert key"); } } } // YUCK: gathers from entire document QDomNodeList bookmarkNodes = doc.documentElement().elementsByTagName("bookmark"); for (int i = 0; i < int(bookmarkNodes.length()); ++i) { QDomNode bookmarkNode = bookmarkNodes.item(i); QDomNamedNodeMap bookmarkAttribs = bookmarkNode.attributes(); QString str = bookmarkAttribs.namedItem("row").nodeValue(); int row = str.toInt(); ret->toggleRowBookmark(row); } return ret; }
static void toggleMute(void* userData) { struct MuteData* data = (struct MuteData*)userData; // if we have mute data we should toggle back the track to it's old form if (data->track->muteBackup) { int i; sync_del_key(data->syncTrack, 0); RemoteConnection_sendDeleteKeyCommand(data->syncTrack->name, 0); for (i = 0; i < data->track->muteKeyCount; ++i) { struct track_key* key = &data->track->muteBackup[i]; sync_set_key(data->syncTrack, key); RemoteConnection_sendSetKeyCommand(data->syncTrack->name, key); } data->track->disabled = false; free(data->track->muteBackup); data->track->muteBackup = 0; data->track->muteKeyCount = 0; } else { struct track_key defKey; int i; size_t keysSize = sizeof(struct track_key) * data->syncTrack->num_keys; float currentValue = (float)sync_get_val(data->syncTrack, data->row); data->track->disabled = true; // No muteBackup, this means that we want to mute the channel data->track->muteBackup = malloc(keysSize); data->track->muteKeyCount = data->syncTrack->num_keys; memcpy(data->track->muteBackup, data->syncTrack->keys, keysSize); for (i = 0; i < data->syncTrack->num_keys; ++i) { int row = data->track->muteBackup[i].row; sync_del_key(data->syncTrack, row); RemoteConnection_sendDeleteKeyCommand(data->syncTrack->name, row); } defKey.row = 0; defKey.value = currentValue; defKey.type = KEY_STEP; // insert key with the current value sync_set_key(data->syncTrack, &defKey); RemoteConnection_sendSetKeyCommand(data->syncTrack->name, &defKey); } }