#include "lc_global.h" #include #include "lc_application.h" #include "lc_library.h" #include "lc_profile.h" #include "project.h" #include "lc_mainwindow.h" #include "lc_qpreferencesdialog.h" #include "lc_partselectionwidget.h" #include "lc_shortcuts.h" #include "view.h" lcApplication* gApplication; void lcPreferences::LoadDefaults() { mFixedAxes = lcGetProfileInt(LC_PROFILE_FIXED_AXES); mMouseSensitivity = lcGetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY); mShadingMode = static_cast(lcGetProfileInt(LC_PROFILE_SHADING_MODE)); mDrawAxes = lcGetProfileInt(LC_PROFILE_DRAW_AXES); mAxesColor = lcGetProfileInt(LC_PROFILE_AXES_COLOR); mOverlayColor = lcGetProfileInt(LC_PROFILE_OVERLAY_COLOR); mDrawEdgeLines = lcGetProfileInt(LC_PROFILE_DRAW_EDGE_LINES); mLineWidth = lcGetProfileFloat(LC_PROFILE_LINE_WIDTH); mAllowLOD = lcGetProfileInt(LC_PROFILE_ALLOW_LOD); mFadeSteps = lcGetProfileInt(LC_PROFILE_FADE_STEPS); mFadeStepsColor = lcGetProfileInt(LC_PROFILE_FADE_STEPS_COLOR); mHighlightNewParts = lcGetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS); mHighlightNewPartsColor = lcGetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS_COLOR); mDrawGridStuds = lcGetProfileInt(LC_PROFILE_GRID_STUDS); mGridStudColor = lcGetProfileInt(LC_PROFILE_GRID_STUD_COLOR); mDrawGridLines = lcGetProfileInt(LC_PROFILE_GRID_LINES); mGridLineSpacing = lcGetProfileInt(LC_PROFILE_GRID_LINE_SPACING); mGridLineColor = lcGetProfileInt(LC_PROFILE_GRID_LINE_COLOR); mViewSphereEnabled = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_ENABLED); mViewSphereLocation = static_cast(lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_LOCATION)); mViewSphereSize = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_SIZE); mViewSphereColor = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_COLOR); mViewSphereTextColor = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_TEXT_COLOR); mViewSphereHighlightColor = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_HIGHLIGHT_COLOR); mAutoLoadMostRecent = lcGetProfileInt(LC_PROFILE_AUTOLOAD_MOSTRECENT); mRestoreTabLayout = lcGetProfileInt(LC_PROFILE_RESTORE_TAB_LAYOUT); } void lcPreferences::SaveDefaults() { lcSetProfileInt(LC_PROFILE_FIXED_AXES, mFixedAxes); lcSetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY, mMouseSensitivity); lcSetProfileInt(LC_PROFILE_SHADING_MODE, static_cast(mShadingMode)); lcSetProfileInt(LC_PROFILE_DRAW_AXES, mDrawAxes); lcSetProfileInt(LC_PROFILE_AXES_COLOR, mAxesColor); lcSetProfileInt(LC_PROFILE_OVERLAY_COLOR, mOverlayColor); lcSetProfileInt(LC_PROFILE_DRAW_EDGE_LINES, mDrawEdgeLines); lcSetProfileFloat(LC_PROFILE_LINE_WIDTH, mLineWidth); lcSetProfileInt(LC_PROFILE_ALLOW_LOD, mAllowLOD); lcSetProfileInt(LC_PROFILE_FADE_STEPS, mFadeSteps); lcSetProfileInt(LC_PROFILE_FADE_STEPS_COLOR, mFadeStepsColor); lcSetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS, mHighlightNewParts); lcSetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS_COLOR, mHighlightNewPartsColor); lcSetProfileInt(LC_PROFILE_GRID_STUDS, mDrawGridStuds); lcSetProfileInt(LC_PROFILE_GRID_STUD_COLOR, mGridStudColor); lcSetProfileInt(LC_PROFILE_GRID_LINES, mDrawGridLines); lcSetProfileInt(LC_PROFILE_GRID_LINE_SPACING, mGridLineSpacing); lcSetProfileInt(LC_PROFILE_GRID_LINE_COLOR, mGridLineColor); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_ENABLED, mViewSphereSize ? 1 : 0); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_LOCATION, (int)mViewSphereLocation); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_SIZE, mViewSphereSize); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_COLOR, mViewSphereColor); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_TEXT_COLOR, mViewSphereTextColor); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_HIGHLIGHT_COLOR, mViewSphereHighlightColor); lcSetProfileInt(LC_PROFILE_AUTOLOAD_MOSTRECENT, mAutoLoadMostRecent); lcSetProfileInt(LC_PROFILE_RESTORE_TAB_LAYOUT, mRestoreTabLayout); } lcApplication::lcApplication(int& Argc, char** Argv) : QApplication(Argc, Argv) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) setApplicationDisplayName("LeoCAD"); #endif setOrganizationDomain("leocad.org"); setOrganizationName("LeoCAD Software"); setApplicationName("LeoCAD"); setApplicationVersion(LC_VERSION_TEXT); gApplication = this; mProject = nullptr; mLibrary = nullptr; mPreferences.LoadDefaults(); } lcApplication::~lcApplication() { delete mProject; delete mLibrary; gApplication = nullptr; } void lcApplication::SaveTabLayout() const { if (!mProject || mProject->GetFileName().isEmpty()) return; QSettings Settings; QByteArray TabLayout = gMainWindow->GetTabLayout(); Settings.setValue(GetTabLayoutKey(), TabLayout); } QString lcApplication::GetTabLayoutKey() const { if (mProject) { QString FileName = mProject->GetFileName(); if (!FileName.isEmpty()) { FileName.replace('\\', '?'); FileName.replace('/', '?'); return QString("TabLayouts/%1").arg(FileName); } } return QString(); } void lcApplication::SetProject(Project* Project) { SaveTabLayout(); gMainWindow->RemoveAllModelTabs(); delete mProject; mProject = Project; Project->SetActiveModel(0); lcGetPiecesLibrary()->RemoveTemporaryPieces(); if (mProject && !mProject->GetFileName().isEmpty() && mPreferences.mRestoreTabLayout) { QSettings Settings; QByteArray TabLayout = Settings.value(GetTabLayoutKey()).toByteArray(); gMainWindow->RestoreTabLayout(TabLayout); } } void lcApplication::SetClipboard(const QByteArray& Clipboard) { mClipboard = Clipboard; gMainWindow->UpdatePaste(!mClipboard.isEmpty()); } void lcApplication::ExportClipboard(const QByteArray& Clipboard) { QMimeData* MimeData = new QMimeData(); MimeData->setData("application/vnd.leocad-clipboard", Clipboard); QApplication::clipboard()->setMimeData(MimeData); SetClipboard(Clipboard); } bool lcApplication::LoadPartsLibrary(const QList>& LibraryPaths, bool OnlyUsePaths, bool ShowProgress) { if (mLibrary == nullptr) mLibrary = new lcPiecesLibrary(); if (!OnlyUsePaths) { char* EnvPath = getenv("LEOCAD_LIB"); if (EnvPath && EnvPath[0]) return mLibrary->Load(EnvPath, ShowProgress); QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); if (!CustomPath.isEmpty()) return mLibrary->Load(CustomPath, ShowProgress); } for (const QPair& LibraryPathEntry : LibraryPaths) { if (mLibrary->Load(LibraryPathEntry.first, ShowProgress)) { if (LibraryPathEntry.second) mLibrary->SetOfficialPieces(); return true; } } return false; } bool lcApplication::Initialize(QList>& LibraryPaths, bool& ShowWindow) { bool OnlyUseLibraryPaths = false; bool SaveImage = false; bool SaveWavefront = false; bool Save3DS = false; bool SaveCOLLADA = false; bool SaveHTML = false; bool SetCameraAngles = false; bool Orthographic = false; bool ImageHighlight = mPreferences.mHighlightNewParts; int ImageWidth = lcGetProfileInt(LC_PROFILE_IMAGE_WIDTH); int ImageHeight = lcGetProfileInt(LC_PROFILE_IMAGE_HEIGHT); int StudLogo = lcGetProfileInt(LC_PROFILE_STUD_LOGO); int ImageStart = 0; int ImageEnd = 0; float CameraLatitude = 0.0f, CameraLongitude = 0.0f; QString ImageName; QString ModelName; QString CameraName; QString ViewpointName; QString ProjectName; QString SaveWavefrontName; QString Save3DSName; QString SaveCOLLADAName; QString SaveHTMLName; QStringList Arguments = arguments(); const int NumArguments = Arguments.size(); for (int ArgIdx = 1; ArgIdx < NumArguments; ArgIdx++) { const QString& Param = Arguments[ArgIdx]; if (Param.isEmpty()) continue; if (Param[0] != '-') { ProjectName = Param; continue; } auto ParseString = [&ArgIdx, &Arguments, NumArguments](QString& Value, bool Required) { if (ArgIdx < NumArguments - 1 && Arguments[ArgIdx + 1][0] != '-') { ArgIdx++; Value = Arguments[ArgIdx]; } else if (Required) printf("Not enough parameters for the '%s' argument.\n", Arguments[ArgIdx].toLatin1().constData()); }; auto ParseInteger = [&ArgIdx, &Arguments, NumArguments](int& Value) { if (ArgIdx < NumArguments - 1 && Arguments[ArgIdx + 1][0] != '-') { bool Ok = false; ArgIdx++; int NewValue = Arguments[ArgIdx].toInt(&Ok); if (Ok) Value = NewValue; else printf("Invalid value specified for the '%s' argument.\n", Arguments[ArgIdx - 1].toLatin1().constData()); } else printf("Not enough parameters for the '%s' argument.\n", Arguments[ArgIdx].toLatin1().constData()); }; auto ParseFloat = [&ArgIdx, &Arguments, NumArguments](float& Value) { if (ArgIdx < NumArguments - 1 && Arguments[ArgIdx + 1][0] != '-') { bool Ok = false; ArgIdx++; int NewValue = Arguments[ArgIdx].toFloat(&Ok); if (Ok) Value = NewValue; else printf("Invalid value specified for the '%s' argument.\n", Arguments[ArgIdx - 1].toLatin1().constData()); } else printf("Not enough parameters for the '%s' argument.\n", Arguments[ArgIdx].toLatin1().constData()); }; auto ParseVector2 = [&ArgIdx, &Arguments, NumArguments](float& Value1, float& Value2) { if (ArgIdx < NumArguments - 2 && Arguments[ArgIdx + 1][0] != '-' && Arguments[ArgIdx + 2][0] != '-') { bool Ok1 = false, Ok2 = false; ArgIdx++; float NewValue1 = Arguments[ArgIdx].toFloat(&Ok1); ArgIdx++; float NewValue2 = Arguments[ArgIdx].toFloat(&Ok2); if (Ok1 && Ok2) { Value1 = NewValue1; Value2 = NewValue2; return true; } else printf("Invalid value specified for the '%s' argument.\n", Arguments[ArgIdx - 2].toLatin1().constData()); } else printf("Not enough parameters for the '%s' argument.\n", Arguments[ArgIdx].toLatin1().constData()); return false; }; if (Param == QLatin1String("-l") || Param == QLatin1String("--libpath")) { QString LibPath; ParseString(LibPath, true); if (!LibPath.isEmpty()) { LibraryPaths.clear(); LibraryPaths += qMakePair(LibPath, false); OnlyUseLibraryPaths = true; } } else if (Param == QLatin1String("-i") || Param == QLatin1String("--image")) { SaveImage = true; ParseString(ImageName, false); } else if (Param == QLatin1String("-w") || Param == QLatin1String("--width")) ParseInteger(ImageWidth); else if (Param == QLatin1String("-h") || Param == QLatin1String("--height")) ParseInteger(ImageHeight); else if (Param == QLatin1String("-f") || Param == QLatin1String("--from")) ParseInteger(ImageStart); else if (Param == QLatin1String("-t") || Param == QLatin1String("--to")) ParseInteger(ImageEnd); else if (Param == QLatin1String("-s") || Param == QLatin1String("--submodel")) ParseString(ModelName, true); else if (Param == QLatin1String("-c") || Param == QLatin1String("--camera")) ParseString(CameraName, true); else if (Param == QLatin1String("--viewpoint")) ParseString(ViewpointName, true); else if (Param == QLatin1String("--camera-angles")) SetCameraAngles = ParseVector2(CameraLatitude, CameraLongitude); else if (Param == QLatin1String("--orthographic")) Orthographic = true; else if (Param == QLatin1String("--highlight")) ImageHighlight = true; else if (Param == QLatin1String("--shading")) { QString ShadingString; ParseString(ShadingString, true); if (ShadingString == QLatin1String("wireframe")) mPreferences.mShadingMode = lcShadingMode::Wireframe; else if (ShadingString == QLatin1String("flat")) mPreferences.mShadingMode = lcShadingMode::Flat; else if (ShadingString == QLatin1String("default")) mPreferences.mShadingMode = lcShadingMode::DefaultLights; else if (ShadingString == QLatin1String("full")) mPreferences.mShadingMode = lcShadingMode::Full; } else if (Param == QLatin1String("--line-width")) ParseFloat(mPreferences.mLineWidth); else if (Param == QLatin1String("-sl") || Param == QLatin1String("--stud-logo")) { ParseInteger(StudLogo); if (StudLogo != lcGetProfileInt(LC_PROFILE_STUD_LOGO)) { lcGetPiecesLibrary()->SetStudLogo(StudLogo, false); } } else if (Param == QLatin1String("-obj") || Param == QLatin1String("--export-wavefront")) { SaveWavefront = true; ParseString(SaveWavefrontName, false); } else if (Param == QLatin1String("-3ds") || Param == QLatin1String("--export-3ds")) { Save3DS = true; ParseString(Save3DSName, false); } else if (Param == QLatin1String("-dae") || Param == QLatin1String("--export-collada")) { SaveCOLLADA = true; ParseString(SaveCOLLADAName, false); } else if (Param == QLatin1String("-html") || Param == QLatin1String("--export-html")) { SaveHTML = true; ParseString(SaveHTMLName, false); } else if (Param == QLatin1String("-v") || Param == QLatin1String("--version")) { #ifdef LC_CONTINUOUS_BUILD printf("LeoCAD Continuous Build " QT_STRINGIFY(LC_CONTINUOUS_BUILD) "\n"); #else printf("LeoCAD Version " LC_VERSION_TEXT "\n"); #endif printf("LeoCAD Version " LC_VERSION_TEXT "\n"); printf("Compiled " __DATE__ "\n"); ShowWindow = false; return true; } else if (Param == QLatin1String("-?") || Param == QLatin1String("--help")) { printf("Usage: leocad [options] [file]\n"); printf(" [options] can be:\n"); printf(" -l, --libpath : Set the Parts Library location to path.\n"); printf(" -i, --image : Save a picture in the format specified by ext.\n"); printf(" -w, --width : Set the picture width.\n"); printf(" -h, --height : Set the picture height.\n"); printf(" -f, --from