// Save model to new filename void imodvSaveModelAs() { /* DNM: added rename of existing file and improved error checks */ ImodvApp *a = Imodv; char *filename; FILE *fout; int len, error; char *nfname1; QString qname; struct stat buf; a->mainWin->releaseKeyboard(); qname = imodPlugGetSaveName(NULL, "Select file to save model into:"); if (qname.isEmpty()) return; filename = strdup(LATIN1(qname)); /* DNM 8/4/01: store the current view when saving, if appropriate */ imodvAutoStoreView(a); len = strlen(filename)+1; nfname1 = (char *)malloc(len + 1); sprintf(nfname1, "%s~", filename); if (!stat(filename, &buf)) { remove(nfname1); rename(filename, nfname1); } fout = fopen(LATIN1(QDir::toNativeSeparators(QString(filename))), "wb"); if (fout){ error = writeOpenedModelFile(a, fout); if (!error) { if (a->imod->fileName) free(a->imod->fileName); a->imod->fileName = (char *)malloc(len); if (a->imod->fileName) memcpy(a->imod->fileName, filename, len); if ((strlen(filename)+1) < IMOD_STRSIZE) memcpy(a->imod->name, filename, strlen(filename)+1); else a->imod->name[0] = 0x00; } } else { error = 1; } if (error) { dia_err("Error writing model; attempting to restore backup file"); if (!stat(nfname1, &buf)) remove(filename); rename(nfname1, filename); } free(nfname1); free(filename); }
// The file menu dispatch function void imodvFileMenu(int item) { QString qname, format; switch (item) { case VFILE_MENU_LOAD: if (imodvLoadModel() < 0) dia_err("Error reading model file. No model loaded."); break; case VFILE_MENU_SAVE: imodvFileSave(); break; case VFILE_MENU_SAVEAS: imodvSaveModelAs(); break; case VFILE_MENU_SNAPRGB: case VFILE_MENU_SNAPTIFF: Imodv->mainWin->releaseKeyboard(); format = (item == VFILE_MENU_SNAPRGB) ? ImodPrefs->snapFormat() : QString("TIFF"); qname = imodPlugGetSaveName (NULL, QString("File to save ") + format + " snapshot into:"); if (qname.isEmpty()) break; imodv_auto_snapshot(qname, item == VFILE_MENU_SNAPRGB ? SnapShot_RGB : SnapShot_TIF); break; case VFILE_MENU_ZEROSNAP: imodvResetSnap(); break; case VFILE_MENU_SNAPDIR: Imodv->mainWin->releaseKeyboard(); b3dSetSnapDirectory(); break; case VFILE_MENU_MOVIE: mvMovieDialog(Imodv, 1); break; case VFILE_MENU_SEQUENCE: mvMovieSequenceDialog(Imodv, 1); break; case VFILE_MENU_QUIT: Imodv->mainWin->close(); break; } }
/* Takes fprintf-type arguments and gives an error message box if out is NULL or if under Windows; otherwise prints to file */ void imodError(FILE *out, const char *format, ...) { char errorMess[512]; va_list args; va_start(args, format); vsprintf(errorMess, format, args); #ifdef _WIN32 out = NULL; #endif if (!out || (ClipHandler && ClipHandler->disconnectedFromStderr())) dia_err(errorMess); else fprintf(out, errorMess); }
// Then wait until the thread exits or give error int ImodClipboard::waitForDisconnect() { #if defined(_WIN32) && defined(QT_THREAD_SUPPORT) int timeout = 5000; if (mUseStdin && sStdThread->isRunning()) { if (sStdThread->wait(timeout)) return 0; dia_err("3dmod is stuck listening for input and is unable to terminate" " cleanly\nYou need to kill it in Task Manager or with Ctrl C"); sStdThread->terminate(); } return 1; #else return 0; #endif }
// Save to the existing filename void imodvFileSave() { /* DNM: added rename of existing file to backup. Also eliminated use of Imodv pointer in favor of a->, and the double save (!?!), and added error checks */ int len, error; char *nfname1; FILE *fout = NULL; ImodvApp *a = Imodv; char *filename = a->imod->fileName; struct stat buf; /* DNM 8/4/01: store the current view when saving, if appropriate */ imodvAutoStoreView(a); len = strlen(filename)+1; nfname1 = (char *)malloc(len + 1); sprintf(nfname1, "%s~", filename); /* DNM 10/20/03: remove backup and rename only if file already exists */ if (!stat(filename, &buf)) { remove(nfname1); rename(filename, nfname1); } if (a->imod->fileName) fout = fopen(LATIN1(QDir::toNativeSeparators(QString(a->imod->fileName))), "wb"); if (fout){ error = writeOpenedModelFile(a, fout); } else error = 1; if (error) { dia_err("File not saved, bad filename or error;" " attempting to restore backup file."); /* If the backup actually exists, remove regular file first */ if (!stat(nfname1, &buf)) remove(filename); rename (nfname1, filename); } free(nfname1); }
/* * Load the sequence from a file */ void MovieSequenceForm::loadClicked() { int numSeg, iseg, err, se, cl, numObj; char *buffer; int *intArray = NULL; MovieSegment *segp; MovieTerminus *term; QString key; if (mModified) { iseg = dia_choice("Save current movie sequence before loading a new one?", "Yes", "No", "Cancel"); if (iseg == 3) return; if (iseg == 1 && saveSequence() < 0) return; } key = utilOpenFileName(this, "Select movie sequence file to load", 0, NULL); if (key.isEmpty()) return; if (AdocRead(LATIN1(key)) < 0) { dia_err("Error reading the movie sequence file as an autodoc"); AdocDone(); return; } mSegments->clear(); numSeg = AdocGetNumberOfSections(MSA_SEGMENT); if (numSeg <= 0) { dia_err(numSeg ? "Error getting number of segments from autodoc" : "No segments were found in the file"); loadTable(); return; } mSegments->resize(numSeg); for (iseg = 0; iseg < numSeg; iseg++) { err = 1; segp = &(mSegments->at(iseg)); // General segment items if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_FRAMES, &segp->numFrames)) break; err++; if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_VIEW, &segp->viewNum)) break; err++; if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_FULL_AXIS, &segp->fullAxis)) break; err++; if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_NUM_CLIPS, &segp->numClips)) break; err++; if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_CLIP_FLAGS, &segp->clipFlags)) break; err++; if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_IMG_AXIS, &segp->imgAxisFlags)) break; // Segment image drawing state if (segp->imgAxisFlags) { if (AdocGetThreeIntegers(MSA_SEGMENT, iseg, MSA_IMG_SIZE, &segp->imgXsize, &segp->imgYsize, &segp->imgZsize)) break; if (AdocGetTwoIntegers(MSA_SEGMENT, iseg, MSA_IMG_LEVELS, &segp->imgBlackLevel, &segp->imgWhiteLevel)) break; if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_IMG_FALSE, &segp->imgFalseColor)) break; } // Segment clip normals for (cl = 0; cl < segp->numClips; cl++) { key.sprintf("%s%d", MSA_CLIP_NORM, cl + 1); if (AdocGetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), &segp->clipNormal[cl].x, &segp->clipNormal[cl].y, &segp->clipNormal[cl].z)) break; } if (cl < segp->numClips) break; err++; if (AdocGetString(MSA_SEGMENT, iseg, MSA_LABEL, &buffer) == 0) { segp->label = QString(buffer); free(buffer); } err++; // The object states if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_NUM_ONOFF, &numObj) || !numObj) break; err++; segp->objStates.resize(numObj); if (AdocGetString(MSA_SEGMENT, iseg, MSA_OBJ_ONOFF, &buffer)) break; err++; if (strlen(buffer) < 2 * numObj - 1) { free(buffer); break; } for (cl = 0; cl < numObj; cl++) segp->objStates[cl] = buffer[cl * 2] == '0' ? 0 : 1; free(buffer); err++; // Objects with changed transparency if (AdocGetInteger(MSA_SEGMENT, iseg, MSA_NUMOBJ_DELTRANS, &numObj)) break; err++; if (numObj > 0) { intArray = B3DMALLOC(int, numObj); if (!intArray) break; if (AdocGetIntegerArray(MSA_SEGMENT, iseg, MSA_OBJ_DELTRANS, intArray, &numObj, numObj)) break; segp->transChangeObjs.resize(numObj); for (cl = 0; cl < numObj; cl++) segp->transChangeObjs[cl] = intArray[cl]; } err++; // Now start and end data term = &segp->start; for (se = 0; se < 2; se++) { key.sprintf("%s%s", MSA_ROTATION, se ? "End" : "Start"); if (AdocGetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), &term->rotation.x, &term->rotation.y, &term->rotation.z)) break; err++; key.sprintf("%s%s", MSA_TRANSLATE, se ? "End" : "Start"); if (AdocGetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), &term->translate.x, &term->translate.y, &term->translate.z)) break; err++; key.sprintf("%s%s", MSA_ZOOM, se ? "End" : "Start"); if (AdocGetFloat(MSA_SEGMENT, iseg, LATIN1(key), &term->zoomRad)) break; // Terminus image drawing if (segp->imgAxisFlags) { key.sprintf("%s%s", MSA_IMG_CEN, se ? "End" : "Start"); if (AdocGetThreeIntegers(MSA_SEGMENT, iseg, LATIN1(key), &term->imgXcenter, &term->imgYcenter, &term->imgZcenter)) break; key.sprintf("%s%s", MSA_IMG_SLICES, se ? "End" : "Start"); if (AdocGetInteger(MSA_SEGMENT, iseg, LATIN1(key), &term->imgSlices)) break; key.sprintf("%s%s", MSA_IMG_TRANSP, se ? "End" : "Start"); if (AdocGetInteger(MSA_SEGMENT, iseg, LATIN1(key), &term->imgTransparency)) break; } // Terminus clip points for (cl = 0; cl < segp->numClips; cl++) { key.sprintf("%s%s%d", MSA_CLIP_POINT, se ? "End" : "Start", cl + 1); if (AdocGetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), &term->clipPoint[cl].x, &term->clipPoint[cl].y, &term->clipPoint[cl].z)) break; } if (cl < segp->numClips) break; err++; // Terminus transparencies if (numObj > 0) { key.sprintf("%s%s", MSA_OBJ_TRANSP, se ? "End" : "Start"); if (AdocGetIntegerArray(MSA_SEGMENT, iseg, LATIN1(key), intArray, &numObj, numObj)) break; for (cl = 0; cl < numObj; cl++) term->objTrans[cl] = (unsigned char)intArray[cl]; } term= &segp->end; } if (se < 2) break; err = 0; }
/* * Save sequence with return code of -1 for error, 1 for cancel or failure to back up */ int MovieSequenceForm::saveSequence() { QString key, value, oneVal; int iseg, err, se, cl; char buffer[2 * MAX_OBJ_ONOFF]; MovieSegment *segp; MovieTerminus *term; if (AdocNew() < 0) { dia_err("Failed to create a new autodoc structure"); AdocDone(); return -1; } for (iseg = 0; iseg < mSegments->size(); iseg++) { err = 1; segp = &(mSegments->at(iseg)); key.sprintf("%d", iseg + 1); if (AdocAddSection(MSA_SEGMENT, LATIN1(key)) < 0) break; err = 2; // General segment items if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_FRAMES, segp->numFrames)) break; if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_VIEW, segp->viewNum)) break; if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_FULL_AXIS, segp->fullAxis)) break; if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_NUM_CLIPS, segp->numClips)) break; if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_CLIP_FLAGS, segp->clipFlags)) break; if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_IMG_AXIS, segp->imgAxisFlags)) break; // Segment image drawing state if (segp->imgAxisFlags) { if (AdocSetThreeIntegers(MSA_SEGMENT, iseg, MSA_IMG_SIZE, segp->imgXsize, segp->imgYsize, segp->imgZsize)) break; if (AdocSetTwoIntegers(MSA_SEGMENT, iseg, MSA_IMG_LEVELS, segp->imgBlackLevel, segp->imgWhiteLevel)) break; if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_IMG_FALSE, segp->imgFalseColor)) break; } // Segment clip normals for (cl = 0; cl < segp->numClips; cl++) { key.sprintf("%s%d", MSA_CLIP_NORM, cl + 1); if (AdocSetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), segp->clipNormal[cl].x, segp->clipNormal[cl].y, segp->clipNormal[cl].z)) break; } if (cl < segp->numClips) break; if (!segp->label.isEmpty() && AdocSetKeyValue(MSA_SEGMENT, iseg, MSA_LABEL, LATIN1(segp->label))) break; // The object states if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_NUM_ONOFF, segp->objStates.size())) break; for (cl = 0; cl < segp->objStates.size(); cl++) { buffer[2 * cl] = segp->objStates[cl] ? '1' : '0'; buffer[2 * cl + 1] = ' '; } buffer[2 * cl - 1] = 0x00; if (AdocSetKeyValue(MSA_SEGMENT, iseg, MSA_OBJ_ONOFF, buffer)) break; // Objects with trans changing if (AdocSetInteger(MSA_SEGMENT, iseg, MSA_NUMOBJ_DELTRANS, segp->transChangeObjs.size())) break; if (segp->transChangeObjs.size()) { value = ""; for (cl = 0; cl < segp->transChangeObjs.size(); cl++) { oneVal.sprintf(" %d", segp->transChangeObjs[cl]); value += oneVal; } if (AdocSetKeyValue(MSA_SEGMENT, iseg, MSA_OBJ_DELTRANS, LATIN1(value))) break; } // Now put out start and end data term = &segp->start; for (se = 0; se < 2; se++) { key.sprintf("%s%s", MSA_ROTATION, se ? "End" : "Start"); if (AdocSetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), term->rotation.x, term->rotation.y, term->rotation.z)) break; key.sprintf("%s%s", MSA_TRANSLATE, se ? "End" : "Start"); if (AdocSetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), term->translate.x, term->translate.y, term->translate.z)) break; key.sprintf("%s%s", MSA_ZOOM, se ? "End" : "Start"); if (AdocSetFloat(MSA_SEGMENT, iseg, LATIN1(key), term->zoomRad)) break; // Terminus image drawing if (segp->imgAxisFlags) { key.sprintf("%s%s", MSA_IMG_CEN, se ? "End" : "Start"); if (AdocSetThreeIntegers(MSA_SEGMENT, iseg, LATIN1(key), term->imgXcenter, term->imgYcenter, term->imgZcenter)) break; key.sprintf("%s%s", MSA_IMG_SLICES, se ? "End" : "Start"); if (AdocSetInteger(MSA_SEGMENT, iseg, LATIN1(key), term->imgSlices)) break; key.sprintf("%s%s", MSA_IMG_TRANSP, se ? "End" : "Start"); if (AdocSetInteger(MSA_SEGMENT, iseg, LATIN1(key), term->imgTransparency)) break; } // Terminus clip points for (cl = 0; cl < segp->numClips; cl++) { key.sprintf("%s%s%d", MSA_CLIP_POINT, se ? "End" : "Start", cl + 1); if (AdocSetThreeFloats(MSA_SEGMENT, iseg, LATIN1(key), term->clipPoint[cl].x, term->clipPoint[cl].y, term->clipPoint[cl].z)) break; } if (cl < segp->numClips) break; // Terminal transparency values if (segp->transChangeObjs.size()) { value = ""; for (cl = 0; cl < segp->transChangeObjs.size(); cl++) { oneVal.sprintf(" %d", (int)term->objTrans[cl]); value += oneVal; } key.sprintf("%s%s", MSA_OBJ_TRANSP, se ? "End" : "Start"); if (AdocSetKeyValue(MSA_SEGMENT, iseg, LATIN1(key), LATIN1(value))) break; } term= &segp->end; } if (se < 2) break; err = 0; } if (err) { dia_err(err == 1 ? "Failed to add a section to autodoc" : "Failed to add a key-value pair to autodoc"); AdocDone(); return -1; } key = imodPlugGetSaveName(this, "Select file to save movie sequence into:"); if (key.isEmpty()) { AdocDone(); return 1; } err = AdocWrite(LATIN1(key)); AdocDone(); if (err) dia_err(err == 1 ? "Failed to back up existing copy of file" : "Error writing the movie sequence to file"); mModified = err < 0; return err; }