mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 00:37:51 -06:00
Fixed conflicts after merge with master
This commit is contained in:
commit
5693545d15
71 changed files with 3265 additions and 2634 deletions
|
@ -328,13 +328,21 @@ find_package(TBB REQUIRED)
|
||||||
# add_definitions(-DTBB_USE_CAPTURED_EXCEPTION=0)
|
# add_definitions(-DTBB_USE_CAPTURED_EXCEPTION=0)
|
||||||
|
|
||||||
find_package(CURL REQUIRED)
|
find_package(CURL REQUIRED)
|
||||||
include_directories(${CURL_INCLUDE_DIRS})
|
|
||||||
|
add_library(libcurl INTERFACE)
|
||||||
|
target_link_libraries(libcurl INTERFACE CURL::libcurl)
|
||||||
|
|
||||||
|
if (NOT WIN32)
|
||||||
|
# Required by libcurl
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
target_link_libraries(libcurl INTERFACE ZLIB::ZLIB)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (SLIC3R_STATIC)
|
if (SLIC3R_STATIC)
|
||||||
if (NOT APPLE)
|
if (NOT APPLE)
|
||||||
# libcurl is always linked dynamically to the system libcurl on OSX.
|
# libcurl is always linked dynamically to the system libcurl on OSX.
|
||||||
# On other systems, libcurl is linked statically if SLIC3R_STATIC is set.
|
# On other systems, libcurl is linked statically if SLIC3R_STATIC is set.
|
||||||
add_definitions(-DCURL_STATICLIB)
|
target_compile_definitions(libcurl INTERFACE CURL_STATICLIB)
|
||||||
endif()
|
endif()
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
# As of now, our build system produces a statically linked libcurl,
|
# As of now, our build system produces a statically linked libcurl,
|
||||||
|
@ -342,7 +350,8 @@ if (SLIC3R_STATIC)
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}")
|
message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}")
|
||||||
message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
|
message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
|
||||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
target_include_directories(libcurl INTERFACE ${OPENSSL_INCLUDE_DIR})
|
||||||
|
target_link_libraries(libcurl INTERFACE ${OPENSSL_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
11
resources/icons/lock_open_sys.svg
Normal file
11
resources/icons/lock_open_sys.svg
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="lock_x5F_open">
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M4,8V4c0,0,0-2,2-2
|
||||||
|
c1,0,3,0,4,0c2,0,2,2,2,2v1"/>
|
||||||
|
<path fill="#808080" d="M13,8H3C2.45,8,2,8.45,2,9v5c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V9C14,8.45,13.55,8,13,8z M10,12H8.91
|
||||||
|
c-0.21,0.58-0.76,1-1.41,1C6.67,13,6,12.33,6,11.5S6.67,10,7.5,10c0.65,0,1.2,0.42,1.41,1H10V12z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 753 B |
11
resources/icons/white/lock_open_sys.svg
Normal file
11
resources/icons/white/lock_open_sys.svg
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="lock_x5F_open">
|
||||||
|
<path fill="none" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M4,8V4c0,0,0-2,2-2
|
||||||
|
c1,0,3,0,4,0c2,0,2,2,2,2v1"/>
|
||||||
|
<path fill="#FFFFFF" d="M13,8H3C2.45,8,2,8.45,2,9v5c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V9C14,8.45,13.55,8,13,8z M10,12H8.91
|
||||||
|
c-0.21,0.58-0.76,1-1.41,1C6.67,13,6,12.33,6,11.5S6.67,10,7.5,10c0.65,0,1.2,0.42,1.41,1H10V12z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 753 B |
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -5,7 +5,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||||
"X-Generator: Poedit 2.2.1\n"
|
"X-Generator: Poedit 2.3\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
|
@ -1561,6 +1561,10 @@ msgstr "Kubická"
|
||||||
msgid "Current mode is %s"
|
msgid "Current mode is %s"
|
||||||
msgstr "Aktuální režim je %s"
|
msgstr "Aktuální režim je %s"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:959
|
||||||
|
msgid "Current preset is inherited from"
|
||||||
|
msgstr "Aktuální nastavení je zděděné od"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:957
|
#: src/slic3r/GUI/Tab.cpp:957
|
||||||
msgid "Current preset is inherited from the default preset."
|
msgid "Current preset is inherited from the default preset."
|
||||||
msgstr "Aktuální nastavení je zděděno z výchozího nastavení."
|
msgstr "Aktuální nastavení je zděděno z výchozího nastavení."
|
||||||
|
@ -2136,6 +2140,18 @@ msgstr "Upravit značku - Pravé tlačítko myši"
|
||||||
msgid "Editing"
|
msgid "Editing"
|
||||||
msgstr "Editace"
|
msgstr "Editace"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:547
|
||||||
|
msgid "Ejec&t SD card / Flash drive"
|
||||||
|
msgstr "Vysunou&t SD kartu / Flash disk"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/KBShortcutsDialog.cpp:126
|
||||||
|
msgid "Eject SD card / Flash drive"
|
||||||
|
msgstr "Vysunout SD kartu / Flash disk"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:547
|
||||||
|
msgid "Eject SD card / Flash drive after the G-code was exported to it."
|
||||||
|
msgstr "Vysunout SD kartu / Flash disk po vyexportování G-codu."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:118
|
#: src/libslic3r/PrintConfig.cpp:118
|
||||||
msgid "Elephant foot compensation"
|
msgid "Elephant foot compensation"
|
||||||
msgstr "Kompenzace rozplácnutí první vrstvy"
|
msgstr "Kompenzace rozplácnutí první vrstvy"
|
||||||
|
@ -2426,6 +2442,10 @@ msgstr "Exportovat stávající plochu jako AMF"
|
||||||
msgid "Export current plate as G-code"
|
msgid "Export current plate as G-code"
|
||||||
msgstr "Exportovat stávající plochu do G-code"
|
msgstr "Exportovat stávající plochu do G-code"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:521
|
||||||
|
msgid "Export current plate as G-code to SD card / Flash drive"
|
||||||
|
msgstr "Exportovat aktuální podložku jako G-code na SD kartu / Flash disk"
|
||||||
|
|
||||||
#: src/slic3r/GUI/MainFrame.cpp:486
|
#: src/slic3r/GUI/MainFrame.cpp:486
|
||||||
msgid "Export current plate as STL"
|
msgid "Export current plate as STL"
|
||||||
msgstr "Exportovat stávající plochu jako STL"
|
msgstr "Exportovat stávající plochu jako STL"
|
||||||
|
@ -2447,6 +2467,10 @@ msgstr "Exportovat úplné zdrojové cesty modelů a dílů do souborů 3mf a am
|
||||||
msgid "Export G-code"
|
msgid "Export G-code"
|
||||||
msgstr "Exportovat G-code"
|
msgstr "Exportovat G-code"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:521
|
||||||
|
msgid "Export G-code to SD card / Flash drive"
|
||||||
|
msgstr "Exportovat G-code na SD kartu / Flash disk"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:3320
|
#: src/libslic3r/PrintConfig.cpp:3320
|
||||||
msgid "Export OBJ"
|
msgid "Export OBJ"
|
||||||
msgstr "Exportovat OBJ"
|
msgstr "Exportovat OBJ"
|
||||||
|
@ -2956,6 +2980,15 @@ msgstr ""
|
||||||
"na levé straně: indikuje nesystémové (jiné než výchozí) přednastavení,\n"
|
"na levé straně: indikuje nesystémové (jiné než výchozí) přednastavení,\n"
|
||||||
"na pravé straně: indikuje, že nastavení nebylo změněno."
|
"na pravé straně: indikuje, že nastavení nebylo změněno."
|
||||||
|
|
||||||
|
#. TRN Description for "WHITE BULLET"
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:3267
|
||||||
|
msgid ""
|
||||||
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
|
msgstr ""
|
||||||
|
"na levé straně: indikuje nesystémové (jiné než výchozí) přednastavení,\n"
|
||||||
|
"na pravé straně: indikuje, že nastavení nebylo změněno."
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
||||||
msgid ""
|
msgid ""
|
||||||
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
|
@ -3589,7 +3622,9 @@ msgstr "indikuje, že nastavení jsou stejná jako systémové (výchozí) hodno
|
||||||
msgid ""
|
msgid ""
|
||||||
"indicates that the settings were changed and are not equal to the last saved preset for the current option group.\n"
|
"indicates that the settings were changed and are not equal to the last saved preset for the current option group.\n"
|
||||||
"Click the BACK ARROW icon to reset all settings for the current option group to the last saved preset."
|
"Click the BACK ARROW icon to reset all settings for the current option group to the last saved preset."
|
||||||
msgstr "indikuje, že došlo ke změně nastavení, které není shodné s naposledy uloženým přednastavením pro aktuální skupinu nastavení. Klikněte na ikonu ŠIPKY ZPĚT pro reset všech nastavení pro aktuální skupinu nastavení na naposledy uložené přednastavení."
|
msgstr ""
|
||||||
|
"indikuje, že došlo ke změně nastavení, které není shodné s naposledy uloženým přednastavením pro aktuální skupinu nastavení.\n"
|
||||||
|
"Klikněte na ikonu ŠIPKY ZPĚT pro reset všech nastavení pro aktuální skupinu nastavení na naposledy uložené přednastavení."
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:211
|
#: src/slic3r/GUI/ConfigManipulation.cpp:211
|
||||||
#: src/slic3r/GUI/GUI_ObjectList.cpp:35 src/slic3r/GUI/GUI_ObjectList.cpp:96
|
#: src/slic3r/GUI/GUI_ObjectList.cpp:35 src/slic3r/GUI/GUI_ObjectList.cpp:96
|
||||||
|
@ -4118,6 +4153,10 @@ msgstr "Maximum"
|
||||||
msgid "Max bridge length"
|
msgid "Max bridge length"
|
||||||
msgstr "Maximální délka mostu"
|
msgstr "Maximální délka mostu"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2658
|
||||||
|
msgid "Max bridges on a pillar"
|
||||||
|
msgstr "Max počet mostů na sloupu"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2822
|
#: src/libslic3r/PrintConfig.cpp:2822
|
||||||
msgid "Max merge distance"
|
msgid "Max merge distance"
|
||||||
msgstr "Maximální vzdálenost pro sloučení"
|
msgstr "Maximální vzdálenost pro sloučení"
|
||||||
|
@ -4286,6 +4325,10 @@ msgstr "Maximální ryv Y"
|
||||||
msgid "Maximum jerk Z"
|
msgid "Maximum jerk Z"
|
||||||
msgstr "Maximální ryv Z"
|
msgstr "Maximální ryv Z"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2660
|
||||||
|
msgid "Maximum number of bridges that can be placed on a pillar. Bridges hold support point pinheads and connect to pillars as small branches."
|
||||||
|
msgstr "Maximální počet mostů, které mohou být umístěny na podpěrný sloup. Mosty drží hroty podpěr a připojují se ke sloupům jako malé větve."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:598
|
#: src/libslic3r/PrintConfig.cpp:598
|
||||||
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
||||||
msgstr "Maximální povolený objem průtoku pro tento filament. Omezuje maximální rychlost průtoku pro tisk až na minimální rychlost průtoku pro tisk a filament. Zadejte nulu pro nastavení bez omezení."
|
msgstr "Maximální povolený objem průtoku pro tento filament. Omezuje maximální rychlost průtoku pro tisk až na minimální rychlost průtoku pro tisk a filament. Zadejte nulu pro nastavení bez omezení."
|
||||||
|
@ -4957,6 +5000,11 @@ msgstr "současného Objektu"
|
||||||
msgid "Offset"
|
msgid "Offset"
|
||||||
msgstr "Odsazení"
|
msgstr "Odsazení"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1755
|
||||||
|
#, c-format
|
||||||
|
msgid "On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."
|
||||||
|
msgstr "V tomto systému používá %s certifikáty HTTPS ze systému Certificate Store nebo Keychain."
|
||||||
|
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
||||||
msgid "One layer mode"
|
msgid "One layer mode"
|
||||||
msgstr "Zobrazení po jedné vrstvě"
|
msgstr "Zobrazení po jedné vrstvě"
|
||||||
|
@ -6430,6 +6478,16 @@ msgstr ""
|
||||||
"NE, pokud chcete, aby se všechny změny nástroje přepnout na změny barev,\n"
|
"NE, pokud chcete, aby se všechny změny nástroje přepnout na změny barev,\n"
|
||||||
"nebo ZRUŠIT pro ponechání beze změny."
|
"nebo ZRUŠIT pro ponechání beze změny."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/DoubleSlider.cpp:1917
|
||||||
|
msgid ""
|
||||||
|
"Select YES if you want to delete all saved tool changes, \n"
|
||||||
|
"NO if you want all tool changes switch to color changes, \n"
|
||||||
|
"or CANCEL to leave it unchanged."
|
||||||
|
msgstr ""
|
||||||
|
"Vyberte ANO, pokud chcete odstranit všechny uložené změny nástroje,\n"
|
||||||
|
"NE, pokud chcete, aby se všechny změny nástroje přepnout na změny barev,\n"
|
||||||
|
"nebo ZRUŠIT pro ponechání beze změny."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Selection.cpp:146
|
#: src/slic3r/GUI/Selection.cpp:146
|
||||||
msgid "Selection-Add"
|
msgid "Selection-Add"
|
||||||
msgstr "Výběř - Přidání"
|
msgstr "Výběř - Přidání"
|
||||||
|
@ -7737,6 +7795,14 @@ msgstr "Vybraný objekt nemůže být rozdělen, protože obsahuje více než je
|
||||||
msgid "The selected object couldn't be split because it contains only one part."
|
msgid "The selected object couldn't be split because it contains only one part."
|
||||||
msgstr "Vybraný objekt nemůže být rozdělen, protože obsahuje pouze jednu část."
|
msgstr "Vybraný objekt nemůže být rozdělen, protože obsahuje pouze jednu část."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:432
|
||||||
|
msgid ""
|
||||||
|
"The selected project is no longer available.\n"
|
||||||
|
"Do you want to remove it from the recent projects list ?"
|
||||||
|
msgstr ""
|
||||||
|
"Vybraný projekt již není k dispozici.\n"
|
||||||
|
"Chcete ho odstranit ze seznamu posledních projektů?"
|
||||||
|
|
||||||
#: src/slic3r/GUI/MainFrame.cpp:422
|
#: src/slic3r/GUI/MainFrame.cpp:422
|
||||||
msgid "The selected project is no more available"
|
msgid "The selected project is no more available"
|
||||||
msgstr "Vybraný projekt již není dostupný"
|
msgstr "Vybraný projekt již není dostupný"
|
||||||
|
@ -8087,6 +8153,10 @@ msgstr "Nejmenší tisknutelná výška vrstvy pro tento extruder. Omezuje rozli
|
||||||
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
msgstr "To je obvykle způsobeno zanedbatelně malým množstvím extrudovaného materiálu nebo chybným modelem. Zkuste model opravit nebo změnit jeho orientaci na podložce."
|
msgstr "To je obvykle způsobeno zanedbatelně malým množstvím extrudovaného materiálu nebo chybným modelem. Zkuste model opravit nebo změnit jeho orientaci na podložce."
|
||||||
|
|
||||||
|
#: src/libslic3r/GCode.cpp:639
|
||||||
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
|
msgstr "To je obvykle způsobeno zanedbatelně malým množstvím extrudovaného materiálu nebo chybným modelem. Zkuste model opravit nebo změnit jeho orientaci na podložce."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2215
|
#: src/libslic3r/PrintConfig.cpp:2215
|
||||||
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
||||||
msgstr "Tato matice popisuje objemy (v kubických milimetrech) nutné k vyčištění nového filamentu na čistící věži pro danou dvojici nástrojů."
|
msgstr "Tato matice popisuje objemy (v kubických milimetrech) nutné k vyčištění nového filamentu na čistící věži pro danou dvojici nástrojů."
|
||||||
|
@ -8228,6 +8298,10 @@ msgstr "Na objekty"
|
||||||
msgid "To parts"
|
msgid "To parts"
|
||||||
msgstr "Na části"
|
msgstr "Na části"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1756
|
||||||
|
msgid "To use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
||||||
|
msgstr "Chcete-li použít vlastní soubor CA, importujte soubor CA do Certificate Store / Keychain."
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Toggle %c axis mirroring"
|
msgid "Toggle %c axis mirroring"
|
||||||
|
|
Binary file not shown.
|
@ -5,7 +5,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 2.2.1\n"
|
"X-Generator: Poedit 2.3\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
|
@ -1557,6 +1557,10 @@ msgstr "Kubisch"
|
||||||
msgid "Current mode is %s"
|
msgid "Current mode is %s"
|
||||||
msgstr "Aktueller Modus ist %s"
|
msgstr "Aktueller Modus ist %s"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:959
|
||||||
|
msgid "Current preset is inherited from"
|
||||||
|
msgstr "Aktuelle Voreinstellung ist abgeleitet von"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:957
|
#: src/slic3r/GUI/Tab.cpp:957
|
||||||
msgid "Current preset is inherited from the default preset."
|
msgid "Current preset is inherited from the default preset."
|
||||||
msgstr "Aktuelle Voreinstellung ist abgeleitet von der Standardvoreinstellung."
|
msgstr "Aktuelle Voreinstellung ist abgeleitet von der Standardvoreinstellung."
|
||||||
|
@ -2952,6 +2956,15 @@ msgstr ""
|
||||||
"Beim linken Knopf: zeigt eine Nicht-System- (oder Nicht-Standard-) Einstellung an.\n"
|
"Beim linken Knopf: zeigt eine Nicht-System- (oder Nicht-Standard-) Einstellung an.\n"
|
||||||
"Beim rechten Knopf: zeigt an, dass die Einstellung nicht geändert wurde."
|
"Beim rechten Knopf: zeigt an, dass die Einstellung nicht geändert wurde."
|
||||||
|
|
||||||
|
#. TRN Description for "WHITE BULLET"
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:3267
|
||||||
|
msgid ""
|
||||||
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
|
msgstr ""
|
||||||
|
"Beim linken Knopf: zeigt eine Nicht-System- (oder Nicht-Standard-) Einstellung an.\n"
|
||||||
|
"Beim rechten Knopf: zeigt an, dass die Einstellung nicht geändert wurde."
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
||||||
msgid ""
|
msgid ""
|
||||||
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
|
@ -4112,6 +4125,10 @@ msgstr "Max"
|
||||||
msgid "Max bridge length"
|
msgid "Max bridge length"
|
||||||
msgstr "Max Überbrückungslänge"
|
msgstr "Max Überbrückungslänge"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2658
|
||||||
|
msgid "Max bridges on a pillar"
|
||||||
|
msgstr "Max Brücken auf einem Pfeiler"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2822
|
#: src/libslic3r/PrintConfig.cpp:2822
|
||||||
msgid "Max merge distance"
|
msgid "Max merge distance"
|
||||||
msgstr "Maximaler Zusammenfügeabstand"
|
msgstr "Maximaler Zusammenfügeabstand"
|
||||||
|
@ -4280,6 +4297,10 @@ msgstr "Maximaler Ruck Y"
|
||||||
msgid "Maximum jerk Z"
|
msgid "Maximum jerk Z"
|
||||||
msgstr "Maximaler Ruck Z"
|
msgstr "Maximaler Ruck Z"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2660
|
||||||
|
msgid "Maximum number of bridges that can be placed on a pillar. Bridges hold support point pinheads and connect to pillars as small branches."
|
||||||
|
msgstr "Maximale Anzahl von Brücken, die auf einen Pfeiler gesetzt werden können. Brücken halten Stützpunkt-Nadelköpfe und verbinden sich als kleine Äste mit den Pfeilern."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:598
|
#: src/libslic3r/PrintConfig.cpp:598
|
||||||
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
||||||
msgstr "Maximale volumetrische Geschwindigkeit, die für dieses Filament zulässig ist. Begrenzt die maximale volumetrische Geschwindigkeit eines Drucks auf das Minimum von Druck- und Filament-Volumengeschwindigkeit. Wird auf null gesetzt, wenn es keine Begrenzung gibt."
|
msgstr "Maximale volumetrische Geschwindigkeit, die für dieses Filament zulässig ist. Begrenzt die maximale volumetrische Geschwindigkeit eines Drucks auf das Minimum von Druck- und Filament-Volumengeschwindigkeit. Wird auf null gesetzt, wenn es keine Begrenzung gibt."
|
||||||
|
@ -4951,6 +4972,11 @@ msgstr "des aktuellen Objekts"
|
||||||
msgid "Offset"
|
msgid "Offset"
|
||||||
msgstr "Offset"
|
msgstr "Offset"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1755
|
||||||
|
#, c-format
|
||||||
|
msgid "On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."
|
||||||
|
msgstr "Auf diesem System verwendet %s HTTPS-Zertifikate aus dem System Zertifikatsspeicher oder Schlüsselbund."
|
||||||
|
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
||||||
msgid "One layer mode"
|
msgid "One layer mode"
|
||||||
msgstr "Eine Schicht Modus"
|
msgstr "Eine Schicht Modus"
|
||||||
|
@ -6421,6 +6447,16 @@ msgstr ""
|
||||||
"NEIN, wenn Sie möchten, dass alle Werkzeugänderungen auf Farbwechsel umgestellt werden, \n"
|
"NEIN, wenn Sie möchten, dass alle Werkzeugänderungen auf Farbwechsel umgestellt werden, \n"
|
||||||
"oder ABBRECHEN, um sie unverändert zu lassen."
|
"oder ABBRECHEN, um sie unverändert zu lassen."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/DoubleSlider.cpp:1917
|
||||||
|
msgid ""
|
||||||
|
"Select YES if you want to delete all saved tool changes, \n"
|
||||||
|
"NO if you want all tool changes switch to color changes, \n"
|
||||||
|
"or CANCEL to leave it unchanged."
|
||||||
|
msgstr ""
|
||||||
|
"Wählen Sie JA, wenn Sie alle gespeicherten Werkzeugänderungen löschen möchten, \n"
|
||||||
|
"NEIN, wenn Sie möchten, dass alle Werkzeugänderungen auf Farbwechsel umgestellt werden, \n"
|
||||||
|
"oder ABBRECHEN, um sie unverändert zu lassen."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Selection.cpp:146
|
#: src/slic3r/GUI/Selection.cpp:146
|
||||||
msgid "Selection-Add"
|
msgid "Selection-Add"
|
||||||
msgstr "Auswahl hinzufügen"
|
msgstr "Auswahl hinzufügen"
|
||||||
|
@ -7733,6 +7769,14 @@ msgstr "Das ausgewählte Objekt konnte nicht getrennt werden, weil es aus mehr a
|
||||||
msgid "The selected object couldn't be split because it contains only one part."
|
msgid "The selected object couldn't be split because it contains only one part."
|
||||||
msgstr "Das ausgewählte Objekt konnte nicht getrennt werden, da es nur aus einem Teil besteht."
|
msgstr "Das ausgewählte Objekt konnte nicht getrennt werden, da es nur aus einem Teil besteht."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:432
|
||||||
|
msgid ""
|
||||||
|
"The selected project is no longer available.\n"
|
||||||
|
"Do you want to remove it from the recent projects list ?"
|
||||||
|
msgstr ""
|
||||||
|
"Das ausgewählte Projekt ist nicht mehr verfügbar.\n"
|
||||||
|
"Wollen Sie es aus der Liste der letzten Projekte entfernen ?"
|
||||||
|
|
||||||
#: src/slic3r/GUI/MainFrame.cpp:422
|
#: src/slic3r/GUI/MainFrame.cpp:422
|
||||||
msgid "The selected project is no more available"
|
msgid "The selected project is no more available"
|
||||||
msgstr "Das ausgewählte Projekt ist nicht mehr verfügbar"
|
msgstr "Das ausgewählte Projekt ist nicht mehr verfügbar"
|
||||||
|
@ -8077,6 +8121,10 @@ msgstr "Dies ist die niedrigste druckbare Schichthöhe für diesen Extruder und
|
||||||
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
msgstr "Dies wird in der Regel durch vernachlässigbar kleine Extrusionen oder durch ein fehlerhaftes Modell verursacht. Versuchen Sie, das Modell zu reparieren oder seine Ausrichtung auf dem Druckbett zu ändern."
|
msgstr "Dies wird in der Regel durch vernachlässigbar kleine Extrusionen oder durch ein fehlerhaftes Modell verursacht. Versuchen Sie, das Modell zu reparieren oder seine Ausrichtung auf dem Druckbett zu ändern."
|
||||||
|
|
||||||
|
#: src/libslic3r/GCode.cpp:639
|
||||||
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
|
msgstr "Dies wird in der Regel durch vernachlässigbar kleine Extrusionen oder durch ein fehlerhaftes Modell verursacht. Versuchen Sie, das Modell zu reparieren oder seine Ausrichtung auf dem Druckbett zu ändern."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2215
|
#: src/libslic3r/PrintConfig.cpp:2215
|
||||||
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
||||||
msgstr "Diese Matrix beschreibt die Volumina (in Kubikmillimetern), die benötigt werden, um das neue Filament auf dem Reinigungsturm für ein bestimmtes Werkzeugpaar zu reinigen."
|
msgstr "Diese Matrix beschreibt die Volumina (in Kubikmillimetern), die benötigt werden, um das neue Filament auf dem Reinigungsturm für ein bestimmtes Werkzeugpaar zu reinigen."
|
||||||
|
@ -8218,6 +8266,10 @@ msgstr "Zu Objekten"
|
||||||
msgid "To parts"
|
msgid "To parts"
|
||||||
msgstr "Zu Teilen"
|
msgstr "Zu Teilen"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1756
|
||||||
|
msgid "To use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
||||||
|
msgstr "Um eine benutzerdefinierte CA-Datei zu verwenden, importieren Sie bitte Ihre CA-Datei in den Zertifikatsspeicher / Schlüsselbund."
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Toggle %c axis mirroring"
|
msgid "Toggle %c axis mirroring"
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -5,7 +5,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
"X-Generator: Poedit 1.8.7.1\n"
|
"X-Generator: Poedit 2.3\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
|
@ -1561,6 +1561,10 @@ msgstr "Cubique"
|
||||||
msgid "Current mode is %s"
|
msgid "Current mode is %s"
|
||||||
msgstr "Le mode actuel est %s"
|
msgstr "Le mode actuel est %s"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:959
|
||||||
|
msgid "Current preset is inherited from"
|
||||||
|
msgstr "Le préréglage actuel est hérité de"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:957
|
#: src/slic3r/GUI/Tab.cpp:957
|
||||||
msgid "Current preset is inherited from the default preset."
|
msgid "Current preset is inherited from the default preset."
|
||||||
msgstr "Le préréglage actuel est hérité du préréglage par défaut."
|
msgstr "Le préréglage actuel est hérité du préréglage par défaut."
|
||||||
|
@ -2956,6 +2960,15 @@ msgstr ""
|
||||||
"pour le bouton gauche : indique un préréglage non-système (ou non par défaut),\n"
|
"pour le bouton gauche : indique un préréglage non-système (ou non par défaut),\n"
|
||||||
"pour le bouton droit : indique que le réglage n'a pas été modifié."
|
"pour le bouton droit : indique que le réglage n'a pas été modifié."
|
||||||
|
|
||||||
|
#. TRN Description for "WHITE BULLET"
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:3267
|
||||||
|
msgid ""
|
||||||
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
|
msgstr ""
|
||||||
|
"pour le bouton gauche : indique un préréglage non-système (ou non par défaut),\n"
|
||||||
|
"pour le bouton droit : indique que le réglage n'a pas été modifié."
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
||||||
msgid ""
|
msgid ""
|
||||||
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
|
@ -3578,7 +3591,6 @@ msgid ""
|
||||||
"Click the UNLOCKED LOCK icon to reset all settings for current option group to the system (or default) values."
|
"Click the UNLOCKED LOCK icon to reset all settings for current option group to the system (or default) values."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"indique que certains paramètres ont été modifiés et ne sont pas égaux aux valeurs du système (ou par défaut) pour le groupe d'options actuel.\n"
|
"indique que certains paramètres ont été modifiés et ne sont pas égaux aux valeurs du système (ou par défaut) pour le groupe d'options actuel.\n"
|
||||||
"\n"
|
|
||||||
"Cliquez sur l'icône CADENAS OUVERT pour régler tous les paramètres pour le groupe d'options actuel sur les valeurs du système (ou par défaut)."
|
"Cliquez sur l'icône CADENAS OUVERT pour régler tous les paramètres pour le groupe d'options actuel sur les valeurs du système (ou par défaut)."
|
||||||
|
|
||||||
#. TRN Description for "LOCKED LOCK"
|
#. TRN Description for "LOCKED LOCK"
|
||||||
|
@ -4055,15 +4067,15 @@ msgstr "Verrouiller les supports sous de nouveaux îlots"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:3252
|
#: src/slic3r/GUI/Tab.cpp:3252
|
||||||
msgid "LOCKED LOCK"
|
msgid "LOCKED LOCK"
|
||||||
msgstr "VERROU VERROUILLE"
|
msgstr "CADENAS FERMÉ"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:3280
|
#: src/slic3r/GUI/Tab.cpp:3280
|
||||||
msgid "LOCKED LOCK icon indicates that the settings are the same as the system (or default) values for the current option group"
|
msgid "LOCKED LOCK icon indicates that the settings are the same as the system (or default) values for the current option group"
|
||||||
msgstr "L'icône VERROU VERROUILLE indique que les réglages sont les mêmes que les valeurs système (ou par défaut) pour le groupe d'options actuel"
|
msgstr "L'icône CADENAS FERMÉ indique que les réglages sont les mêmes que les valeurs système (ou par défaut) pour le groupe d'options actuel"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:3296
|
#: src/slic3r/GUI/Tab.cpp:3296
|
||||||
msgid "LOCKED LOCK icon indicates that the value is the same as the system (or default) value."
|
msgid "LOCKED LOCK icon indicates that the value is the same as the system (or default) value."
|
||||||
msgstr "L'icône VERROU VERROUILLÉ indique que la valeur est la même que la valeur système (ou par défaut)."
|
msgstr "L'icône CADENAS FERMÉ indique que la valeur est la même que la valeur système (ou par défaut)."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:3508
|
#: src/libslic3r/PrintConfig.cpp:3508
|
||||||
msgid "Logging level"
|
msgid "Logging level"
|
||||||
|
@ -4122,6 +4134,10 @@ msgstr "Maximum"
|
||||||
msgid "Max bridge length"
|
msgid "Max bridge length"
|
||||||
msgstr "Longueur maximum de pont"
|
msgstr "Longueur maximum de pont"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2658
|
||||||
|
msgid "Max bridges on a pillar"
|
||||||
|
msgstr "Nombre de ponts maximum par pilier"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2822
|
#: src/libslic3r/PrintConfig.cpp:2822
|
||||||
msgid "Max merge distance"
|
msgid "Max merge distance"
|
||||||
msgstr "Distance maximum de fusion"
|
msgstr "Distance maximum de fusion"
|
||||||
|
@ -4290,6 +4306,10 @@ msgstr "Mouvement brusque maximum Y"
|
||||||
msgid "Maximum jerk Z"
|
msgid "Maximum jerk Z"
|
||||||
msgstr "Mouvement brusque maximum Z"
|
msgstr "Mouvement brusque maximum Z"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2660
|
||||||
|
msgid "Maximum number of bridges that can be placed on a pillar. Bridges hold support point pinheads and connect to pillars as small branches."
|
||||||
|
msgstr "Le nombre de ponts maximum pouvant être placés sur un pilier. Les ponts soutiennent les têtes des points de support et sont connectés aux piliers comme de petites branches."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:598
|
#: src/libslic3r/PrintConfig.cpp:598
|
||||||
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
||||||
msgstr "Vitesse volumétrique maximale autorisée pour ce filament. Limite la vitesse volumétrique d'une impression au minimum des vitesses volumétriques d'impression et de filament. Mettez à zéro pour enlever la limite."
|
msgstr "Vitesse volumétrique maximale autorisée pour ce filament. Limite la vitesse volumétrique d'une impression au minimum des vitesses volumétriques d'impression et de filament. Mettez à zéro pour enlever la limite."
|
||||||
|
@ -4961,6 +4981,11 @@ msgstr "d'un Objet en cours"
|
||||||
msgid "Offset"
|
msgid "Offset"
|
||||||
msgstr "Décalage"
|
msgstr "Décalage"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1755
|
||||||
|
#, c-format
|
||||||
|
msgid "On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."
|
||||||
|
msgstr "Dans ce système, %s utilise des certificats HTTPS issus du système Magasin de Certificats ou Trousseau."
|
||||||
|
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
||||||
msgid "One layer mode"
|
msgid "One layer mode"
|
||||||
msgstr "Mode couche unique"
|
msgstr "Mode couche unique"
|
||||||
|
@ -6437,6 +6462,16 @@ msgstr ""
|
||||||
"NON si vous souhaitez que tous les changements d'outil soient remplacés par des modifications de couleur, \n"
|
"NON si vous souhaitez que tous les changements d'outil soient remplacés par des modifications de couleur, \n"
|
||||||
"ou ANNULER pour ne pas les modifier."
|
"ou ANNULER pour ne pas les modifier."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/DoubleSlider.cpp:1917
|
||||||
|
msgid ""
|
||||||
|
"Select YES if you want to delete all saved tool changes, \n"
|
||||||
|
"NO if you want all tool changes switch to color changes, \n"
|
||||||
|
"or CANCEL to leave it unchanged."
|
||||||
|
msgstr ""
|
||||||
|
"Sélectionnez OUI si vous souhaitez supprimer tous les changements d'outil enregistrées, \n"
|
||||||
|
"NON si vous souhaitez que tous les changements d'outil soient remplacés par des modifications de couleur, \n"
|
||||||
|
"ou ANNULER pour ne pas les modifier."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Selection.cpp:146
|
#: src/slic3r/GUI/Selection.cpp:146
|
||||||
msgid "Selection-Add"
|
msgid "Selection-Add"
|
||||||
msgstr "Sélection-Ajouter"
|
msgstr "Sélection-Ajouter"
|
||||||
|
@ -7745,6 +7780,14 @@ msgstr "L'objet sélectionné ne peut être scindé car il contient plus d'un vo
|
||||||
msgid "The selected object couldn't be split because it contains only one part."
|
msgid "The selected object couldn't be split because it contains only one part."
|
||||||
msgstr "L'objet sélectionné n'a pu être scindé car il ne contient qu'une seule pièce."
|
msgstr "L'objet sélectionné n'a pu être scindé car il ne contient qu'une seule pièce."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:432
|
||||||
|
msgid ""
|
||||||
|
"The selected project is no longer available.\n"
|
||||||
|
"Do you want to remove it from the recent projects list ?"
|
||||||
|
msgstr ""
|
||||||
|
"Le projet sélectionné n'est plus disponible.\n"
|
||||||
|
"Voulez-vous le retirer de la liste des projets récents ?"
|
||||||
|
|
||||||
#: src/slic3r/GUI/MainFrame.cpp:422
|
#: src/slic3r/GUI/MainFrame.cpp:422
|
||||||
msgid "The selected project is no more available"
|
msgid "The selected project is no more available"
|
||||||
msgstr "Le projet sélectionné n'est plus disponible"
|
msgstr "Le projet sélectionné n'est plus disponible"
|
||||||
|
@ -8092,6 +8135,10 @@ msgstr "Cette valeur est la hauteur de couche imprimable minimum pour cet extrud
|
||||||
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
msgstr "Ceci est généralement provoqué par de petites extrusions négligeables ou par un modèle défectueux. Essayez de réparer le modèle ou de changer son orientation sur le lit."
|
msgstr "Ceci est généralement provoqué par de petites extrusions négligeables ou par un modèle défectueux. Essayez de réparer le modèle ou de changer son orientation sur le lit."
|
||||||
|
|
||||||
|
#: src/libslic3r/GCode.cpp:639
|
||||||
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
|
msgstr "Ceci est généralement provoqué par de petites extrusions négligeables ou par un modèle défectueux. Essayez de réparer le modèle ou de changer son orientation sur le lit."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2215
|
#: src/libslic3r/PrintConfig.cpp:2215
|
||||||
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
||||||
msgstr "Cette matrice décrit les volumes (en millimètres cube) nécessaires pour purger le nouveau filament dans la tour de nettoyage pour une paire d'outils donnée."
|
msgstr "Cette matrice décrit les volumes (en millimètres cube) nécessaires pour purger le nouveau filament dans la tour de nettoyage pour une paire d'outils donnée."
|
||||||
|
@ -8233,6 +8280,10 @@ msgstr "Vers les objets"
|
||||||
msgid "To parts"
|
msgid "To parts"
|
||||||
msgstr "Vers les parties"
|
msgstr "Vers les parties"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1756
|
||||||
|
msgid "To use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
||||||
|
msgstr "Pour utiliser un fichier CA personnalisé, veuillez importer votre fichier CA dans le Magasin de Certificats / Trousseau."
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Toggle %c axis mirroring"
|
msgid "Toggle %c axis mirroring"
|
||||||
|
|
Binary file not shown.
|
@ -5,7 +5,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 1.8.7.1\n"
|
"X-Generator: Poedit 2.3\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
|
@ -1561,6 +1561,10 @@ msgstr "Cubico"
|
||||||
msgid "Current mode is %s"
|
msgid "Current mode is %s"
|
||||||
msgstr "La modalità corrente è %s"
|
msgstr "La modalità corrente è %s"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:959
|
||||||
|
msgid "Current preset is inherited from"
|
||||||
|
msgstr "Il preset corrente è ereditato da"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:957
|
#: src/slic3r/GUI/Tab.cpp:957
|
||||||
msgid "Current preset is inherited from the default preset."
|
msgid "Current preset is inherited from the default preset."
|
||||||
msgstr "Il preset attuale è stato ereditato dal preset predefinito."
|
msgstr "Il preset attuale è stato ereditato dal preset predefinito."
|
||||||
|
@ -2956,6 +2960,15 @@ msgstr ""
|
||||||
"per il tasto sinistro: indica un preset non di sistema (o non-predefinito),\n"
|
"per il tasto sinistro: indica un preset non di sistema (o non-predefinito),\n"
|
||||||
"per il tasto destro: indica che le impostazioni non sono state modificate."
|
"per il tasto destro: indica che le impostazioni non sono state modificate."
|
||||||
|
|
||||||
|
#. TRN Description for "WHITE BULLET"
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:3267
|
||||||
|
msgid ""
|
||||||
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
|
msgstr ""
|
||||||
|
"per il tasto sinistro: indica un preset non di sistema (o non-predefinito),\n"
|
||||||
|
"per il tasto destro: indica che le impostazioni non sono state modificate."
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
||||||
msgid ""
|
msgid ""
|
||||||
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
|
@ -4115,6 +4128,10 @@ msgstr "Massimo"
|
||||||
msgid "Max bridge length"
|
msgid "Max bridge length"
|
||||||
msgstr "Lunghezza massima Bridge"
|
msgstr "Lunghezza massima Bridge"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2658
|
||||||
|
msgid "Max bridges on a pillar"
|
||||||
|
msgstr "Ponteggi massimi su un pilastro"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2822
|
#: src/libslic3r/PrintConfig.cpp:2822
|
||||||
msgid "Max merge distance"
|
msgid "Max merge distance"
|
||||||
msgstr "Massima distanza di unione"
|
msgstr "Massima distanza di unione"
|
||||||
|
@ -4283,6 +4300,10 @@ msgstr "Jerk massimo Y"
|
||||||
msgid "Maximum jerk Z"
|
msgid "Maximum jerk Z"
|
||||||
msgstr "Jerk massimo Z"
|
msgstr "Jerk massimo Z"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2660
|
||||||
|
msgid "Maximum number of bridges that can be placed on a pillar. Bridges hold support point pinheads and connect to pillars as small branches."
|
||||||
|
msgstr "Numero massimo di ponteggi che può essere posizionato su un pilastro. I ponteggi mantengono le capocchie dei punti di supporto e si collegano ai pilastri come piccoli rami."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:598
|
#: src/libslic3r/PrintConfig.cpp:598
|
||||||
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
||||||
msgstr "Massima velocità volumetrica consentita per questo filamento. Limita la velocità volumetrica massima di una stampa alla velocità volumetrica minima del filamento e di stampa. Imposta a zero per non avere limite."
|
msgstr "Massima velocità volumetrica consentita per questo filamento. Limita la velocità volumetrica massima di una stampa alla velocità volumetrica minima del filamento e di stampa. Imposta a zero per non avere limite."
|
||||||
|
@ -4953,6 +4974,11 @@ msgstr "di un Oggetto corrente"
|
||||||
msgid "Offset"
|
msgid "Offset"
|
||||||
msgstr "Offset"
|
msgstr "Offset"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1755
|
||||||
|
#, c-format
|
||||||
|
msgid "On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."
|
||||||
|
msgstr "Su questo sistema, %s utilizza certificati HTTPS provenienti dal sistema Certificate Store o da Keychain."
|
||||||
|
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
||||||
msgid "One layer mode"
|
msgid "One layer mode"
|
||||||
msgstr "Modalità Un Layer"
|
msgstr "Modalità Un Layer"
|
||||||
|
@ -6425,6 +6451,16 @@ msgstr ""
|
||||||
"NO se vuoi che tutti i cambi attrezzo passino a cambi colore,\n"
|
"NO se vuoi che tutti i cambi attrezzo passino a cambi colore,\n"
|
||||||
"o ANNULLA per lasciarlo invariato."
|
"o ANNULLA per lasciarlo invariato."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/DoubleSlider.cpp:1917
|
||||||
|
msgid ""
|
||||||
|
"Select YES if you want to delete all saved tool changes, \n"
|
||||||
|
"NO if you want all tool changes switch to color changes, \n"
|
||||||
|
"or CANCEL to leave it unchanged."
|
||||||
|
msgstr ""
|
||||||
|
"Seleziona SI se vuoi cancellare tutti i cambi attrezzo salvati,\n"
|
||||||
|
"NO se vuoi che tutti i cambi attrezzo passino a cambi colore,\n"
|
||||||
|
"o ANNULLA per lasciarlo invariato."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Selection.cpp:146
|
#: src/slic3r/GUI/Selection.cpp:146
|
||||||
msgid "Selection-Add"
|
msgid "Selection-Add"
|
||||||
msgstr "Selezione-Aggiungi"
|
msgstr "Selezione-Aggiungi"
|
||||||
|
@ -7736,6 +7772,14 @@ msgstr "L'oggetto selezionato non può essere diviso perché contiene più di un
|
||||||
msgid "The selected object couldn't be split because it contains only one part."
|
msgid "The selected object couldn't be split because it contains only one part."
|
||||||
msgstr "L'oggetto selezionato non può essere diviso perché contiene solo una parte."
|
msgstr "L'oggetto selezionato non può essere diviso perché contiene solo una parte."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:432
|
||||||
|
msgid ""
|
||||||
|
"The selected project is no longer available.\n"
|
||||||
|
"Do you want to remove it from the recent projects list ?"
|
||||||
|
msgstr ""
|
||||||
|
"Il progetto selezionato non è più disponibile.\n"
|
||||||
|
"Vuoi rimuoverlo dall'elenco dei progetti recenti?"
|
||||||
|
|
||||||
#: src/slic3r/GUI/MainFrame.cpp:422
|
#: src/slic3r/GUI/MainFrame.cpp:422
|
||||||
msgid "The selected project is no more available"
|
msgid "The selected project is no more available"
|
||||||
msgstr "Il progetto selezionato non è più disponibile"
|
msgstr "Il progetto selezionato non è più disponibile"
|
||||||
|
@ -8080,6 +8124,10 @@ msgstr "Questa è l'altezza minima stampabile per questo estrusore e limita la r
|
||||||
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
msgstr "Questo solitamente è causato da estrusioni molto piccole o da un modello difettoso. Provare a riparare il modello o cambiare il suo orientamento sul piano."
|
msgstr "Questo solitamente è causato da estrusioni molto piccole o da un modello difettoso. Provare a riparare il modello o cambiare il suo orientamento sul piano."
|
||||||
|
|
||||||
|
#: src/libslic3r/GCode.cpp:639
|
||||||
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
|
msgstr "Questo solitamente è causato da estrusioni molto piccole o da un modello difettoso. Provare a riparare il modello o cambiare il suo orientamento sul piano."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2215
|
#: src/libslic3r/PrintConfig.cpp:2215
|
||||||
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
||||||
msgstr "Questa matrice descrive il volume (in millimetri cubici) necessario per spurgare il filamento nella torre di spurgo per una qualunque coppia di attrezzi."
|
msgstr "Questa matrice descrive il volume (in millimetri cubici) necessario per spurgare il filamento nella torre di spurgo per una qualunque coppia di attrezzi."
|
||||||
|
@ -8221,6 +8269,10 @@ msgstr "In oggetti"
|
||||||
msgid "To parts"
|
msgid "To parts"
|
||||||
msgstr "In parti"
|
msgstr "In parti"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1756
|
||||||
|
msgid "To use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
||||||
|
msgstr "Per utilizzare un file CA personalizzato, importa il tuo file CA sul Certificate Store / Keychain."
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Toggle %c axis mirroring"
|
msgid "Toggle %c axis mirroring"
|
||||||
|
|
Binary file not shown.
|
@ -5,7 +5,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
"X-Generator: Poedit 2.2.1\n"
|
"X-Generator: Poedit 2.3\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
|
@ -1553,6 +1553,10 @@ msgstr "立方"
|
||||||
msgid "Current mode is %s"
|
msgid "Current mode is %s"
|
||||||
msgstr "現在のモードは%sです"
|
msgstr "現在のモードは%sです"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:959
|
||||||
|
msgid "Current preset is inherited from"
|
||||||
|
msgstr "現在のプリセット継承元"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:957
|
#: src/slic3r/GUI/Tab.cpp:957
|
||||||
msgid "Current preset is inherited from the default preset."
|
msgid "Current preset is inherited from the default preset."
|
||||||
msgstr "現在の設定はデフォルト設定から継承されます。"
|
msgstr "現在の設定はデフォルト設定から継承されます。"
|
||||||
|
@ -2941,6 +2945,15 @@ msgid ""
|
||||||
"for the right button: \tindicates that the settings hasn't been modified."
|
"for the right button: \tindicates that the settings hasn't been modified."
|
||||||
msgstr "左ボタンの場合:システム(デフォルト)プリセットでないことを示し、右側ボタンの場合:設定が変更されていないことを示します。"
|
msgstr "左ボタンの場合:システム(デフォルト)プリセットでないことを示し、右側ボタンの場合:設定が変更されていないことを示します。"
|
||||||
|
|
||||||
|
#. TRN Description for "WHITE BULLET"
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:3267
|
||||||
|
msgid ""
|
||||||
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
|
msgstr ""
|
||||||
|
"左ボタンの場合:システム(デフォルト)プリセットでないことを示し、\n"
|
||||||
|
"右側ボタンの場合:設定が変更されていないことを示します。"
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
||||||
msgid ""
|
msgid ""
|
||||||
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
|
@ -3571,7 +3584,9 @@ msgstr "設定が現在の設定グループのシステム(デフォルト)
|
||||||
msgid ""
|
msgid ""
|
||||||
"indicates that the settings were changed and are not equal to the last saved preset for the current option group.\n"
|
"indicates that the settings were changed and are not equal to the last saved preset for the current option group.\n"
|
||||||
"Click the BACK ARROW icon to reset all settings for the current option group to the last saved preset."
|
"Click the BACK ARROW icon to reset all settings for the current option group to the last saved preset."
|
||||||
msgstr "設定が変更され、現在のオプショングループに最後に保存されたプリセットと等しくないことを示します。戻る矢印アイコンをクリックして、現在のオプショングループのすべての設定を最後に保存されたプリセットに戻します。"
|
msgstr ""
|
||||||
|
"設定が変更され、現在のオプショングループに最後に保存されたプリセットと等しくないことを示します。\n"
|
||||||
|
"戻る矢印アイコンをクリックして、現在のオプショングループのすべての設定を最後に保存されたプリセットに戻します。"
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:211
|
#: src/slic3r/GUI/ConfigManipulation.cpp:211
|
||||||
#: src/slic3r/GUI/GUI_ObjectList.cpp:35 src/slic3r/GUI/GUI_ObjectList.cpp:96
|
#: src/slic3r/GUI/GUI_ObjectList.cpp:35 src/slic3r/GUI/GUI_ObjectList.cpp:96
|
||||||
|
@ -4100,6 +4115,10 @@ msgstr "最大"
|
||||||
msgid "Max bridge length"
|
msgid "Max bridge length"
|
||||||
msgstr "最長ブリッジ長さ"
|
msgstr "最長ブリッジ長さ"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2658
|
||||||
|
msgid "Max bridges on a pillar"
|
||||||
|
msgstr "柱の上の最大ブリッジ数"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2822
|
#: src/libslic3r/PrintConfig.cpp:2822
|
||||||
msgid "Max merge distance"
|
msgid "Max merge distance"
|
||||||
msgstr "最大結合距離"
|
msgstr "最大結合距離"
|
||||||
|
@ -4268,6 +4287,10 @@ msgstr "Yの最大ジャーク"
|
||||||
msgid "Maximum jerk Z"
|
msgid "Maximum jerk Z"
|
||||||
msgstr "Zの最大ジャーク"
|
msgstr "Zの最大ジャーク"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2660
|
||||||
|
msgid "Maximum number of bridges that can be placed on a pillar. Bridges hold support point pinheads and connect to pillars as small branches."
|
||||||
|
msgstr "柱の上に置くことができるブリッジの最大数。 ブリッジはサポートポイントのピンヘッドを保持し、小さな枝として柱に接続します。"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:598
|
#: src/libslic3r/PrintConfig.cpp:598
|
||||||
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
||||||
msgstr "このフィラメントに許容される最大体積押出し速度。プリントの最大体積押出し速度を、プリントとフィラメントの体積押出し速度の最小値にに制限します。 制限なしに設定するにはゼロを入力します。"
|
msgstr "このフィラメントに許容される最大体積押出し速度。プリントの最大体積押出し速度を、プリントとフィラメントの体積押出し速度の最小値にに制限します。 制限なしに設定するにはゼロを入力します。"
|
||||||
|
@ -4922,6 +4945,11 @@ msgstr "現在のオブジェクトの"
|
||||||
msgid "Offset"
|
msgid "Offset"
|
||||||
msgstr "オフセット"
|
msgstr "オフセット"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1755
|
||||||
|
#, c-format
|
||||||
|
msgid "On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."
|
||||||
|
msgstr "このシステムでは、%sはシステムの証明書ストアまたはキーチェーンからのHTTPS証明書を使用します。"
|
||||||
|
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
||||||
msgid "One layer mode"
|
msgid "One layer mode"
|
||||||
msgstr "1レイヤーモード"
|
msgstr "1レイヤーモード"
|
||||||
|
@ -6391,6 +6419,16 @@ msgstr ""
|
||||||
"すべてのツールの変更を色の変更に切り替えたい場合は「いいえ」、\n"
|
"すべてのツールの変更を色の変更に切り替えたい場合は「いいえ」、\n"
|
||||||
"または「キャンセル」で変更せずにそのままにします"
|
"または「キャンセル」で変更せずにそのままにします"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/DoubleSlider.cpp:1917
|
||||||
|
msgid ""
|
||||||
|
"Select YES if you want to delete all saved tool changes, \n"
|
||||||
|
"NO if you want all tool changes switch to color changes, \n"
|
||||||
|
"or CANCEL to leave it unchanged."
|
||||||
|
msgstr ""
|
||||||
|
"保存したツールの変更をすべて削除する場合は、「はい」を選択します。\n"
|
||||||
|
"すべてのツールの変更を色の変更に切り替えたい場合は「いいえ」、\n"
|
||||||
|
"または「キャンセル」で変更せずにそのままにします"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Selection.cpp:146
|
#: src/slic3r/GUI/Selection.cpp:146
|
||||||
msgid "Selection-Add"
|
msgid "Selection-Add"
|
||||||
msgstr "選択-追加"
|
msgstr "選択-追加"
|
||||||
|
@ -7696,6 +7734,14 @@ msgstr "選択したオブジェクトには複数のボリューム/マテリ
|
||||||
msgid "The selected object couldn't be split because it contains only one part."
|
msgid "The selected object couldn't be split because it contains only one part."
|
||||||
msgstr "選択したオブジェクトには、1つのパーツしか含まれていないため、分割できませんでした。"
|
msgstr "選択したオブジェクトには、1つのパーツしか含まれていないため、分割できませんでした。"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:432
|
||||||
|
msgid ""
|
||||||
|
"The selected project is no longer available.\n"
|
||||||
|
"Do you want to remove it from the recent projects list ?"
|
||||||
|
msgstr ""
|
||||||
|
"選択したプロジェクトは使用できなくなりました。\n"
|
||||||
|
"最近のプロジェクトリストから削除しますか?"
|
||||||
|
|
||||||
#: src/slic3r/GUI/MainFrame.cpp:422
|
#: src/slic3r/GUI/MainFrame.cpp:422
|
||||||
msgid "The selected project is no more available"
|
msgid "The selected project is no more available"
|
||||||
msgstr "選択したプロジェクトはもう利用できません"
|
msgstr "選択したプロジェクトはもう利用できません"
|
||||||
|
@ -8040,6 +8086,10 @@ msgstr "このエクストルーダーの最小プリント可能なレイヤー
|
||||||
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
msgstr "これは通常、無視できるほど少量の押出量またはモデルの欠陥が原因です。 ベッド上のモデルの修復または向きを再配置してみてください。"
|
msgstr "これは通常、無視できるほど少量の押出量またはモデルの欠陥が原因です。 ベッド上のモデルの修復または向きを再配置してみてください。"
|
||||||
|
|
||||||
|
#: src/libslic3r/GCode.cpp:639
|
||||||
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
|
msgstr "これは通常、無視できるほど少量の押出量またはモデルの欠陥が原因です。 ベッド上のモデルの修復または向きを再配置してみてください。"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2215
|
#: src/libslic3r/PrintConfig.cpp:2215
|
||||||
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
||||||
msgstr "この行列は、任意のツールチェンジ間においてワイプタワーの新しいフィラメントをパージするために必要な体積(立方ミリメートル)を示しています。"
|
msgstr "この行列は、任意のツールチェンジ間においてワイプタワーの新しいフィラメントをパージするために必要な体積(立方ミリメートル)を示しています。"
|
||||||
|
@ -8180,6 +8230,10 @@ msgstr "オブジェクト"
|
||||||
msgid "To parts"
|
msgid "To parts"
|
||||||
msgstr "パーツへ"
|
msgstr "パーツへ"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1756
|
||||||
|
msgid "To use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
||||||
|
msgstr "カスタムCAファイルを使用するには、CAファイルを証明書ストア/キーチェーンにインポートしてください。"
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Toggle %c axis mirroring"
|
msgid "Toggle %c axis mirroring"
|
||||||
|
|
Binary file not shown.
|
@ -1208,12 +1208,12 @@ msgstr "다중 압출기 인쇄를 위해 마지막 색상 변경 데이터가
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:1889
|
#: src/slic3r/GUI/DoubleSlider.cpp:1889
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select YES if you want to delete all saved tool changes,\n"
|
"Select YES if you want to delete all saved tool changes,\n"
|
||||||
"\tNO if you want all tool changes switch to color changes, \n"
|
"NO if you want all tool changes switch to color changes,\n"
|
||||||
"\tor CANCEL for do nothing"
|
"or CANCEL for do nothing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"저장된 도구 변경 내용을 모두 삭제하려면 YES를 선택합니다.\n"
|
"저장된 도구 변경 내용을 모두 삭제하려면 YES를 선택합니다.\n"
|
||||||
"\t아니오 모든 도구 변경 이 색상 변경으로 전환하려면 \n"
|
"아니오 모든 도구 변경 이 색상 변경으로 전환하려면\n"
|
||||||
"\t또는 아무것도 하지 않는 취소"
|
"또는 아무것도 하지 않는 취소"
|
||||||
|
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:1892
|
#: src/slic3r/GUI/DoubleSlider.cpp:1892
|
||||||
msgid "Do you want to delete all saved tool changes?"
|
msgid "Do you want to delete all saved tool changes?"
|
||||||
|
@ -5411,16 +5411,18 @@ msgstr "CA 인증서 파일 열기"
|
||||||
#: src/slic3r/GUI/Tab.cpp:1741
|
#: src/slic3r/GUI/Tab.cpp:1741
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"HTTPS CA File:\n"
|
"On this system, %s uses HTTPS certificates from the system Certificate "
|
||||||
" \tOn this system, %s uses HTTPS certificates from the system Certificate "
|
|
||||||
"Store or Keychain.\n"
|
"Store or Keychain.\n"
|
||||||
" \tTo use a custom CA file, please import your CA file into Certificate "
|
msgstr ""
|
||||||
|
"이 시스템에서 %s는 시스템 인증서 저장소나 키체인의 HTTPS 인증서를 사용 "
|
||||||
|
"합니다.\n"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1741
|
||||||
|
msgid ""
|
||||||
|
"To use a custom CA file, please import your CA file into Certificate "
|
||||||
"Store / Keychain."
|
"Store / Keychain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"HTTPS CA 파일:\n"
|
"사용자 지정 CA 파일을 사용 하려면 CA 파일을 인증서 저장소/키체인에 가져"
|
||||||
" \t이 시스템에서 %s는 시스템 인증서 저장소나 키체인의 HTTPS 인증서를 사용 "
|
|
||||||
"합니다.\n"
|
|
||||||
" \t사용자 지정 CA 파일을 사용 하려면 CA 파일을 인증서 저장소/키체인에 가져"
|
|
||||||
"오십시오."
|
"오십시오."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1781 src/slic3r/GUI/Tab.cpp:2025
|
#: src/slic3r/GUI/Tab.cpp:1781 src/slic3r/GUI/Tab.cpp:2025
|
||||||
|
@ -5717,8 +5719,8 @@ msgstr "흰색 글머리 기호"
|
||||||
#. TRN Description for "WHITE BULLET"
|
#. TRN Description for "WHITE BULLET"
|
||||||
#: src/slic3r/GUI/Tab.cpp:3235
|
#: src/slic3r/GUI/Tab.cpp:3235
|
||||||
msgid ""
|
msgid ""
|
||||||
"for the left button: \tindicates a non-system (or non-default) preset,\n"
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
"for the right button: \tindicates that the settings hasn't been modified."
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"왼쪽 단추의 경우: 비시스템(또는 기본이 아닌) 사전 설정을 나타냅니다.\n"
|
"왼쪽 단추의 경우: 비시스템(또는 기본이 아닌) 사전 설정을 나타냅니다.\n"
|
||||||
"오른쪽 버튼: 설정이 수정되지 않았음을 나타냅니다."
|
"오른쪽 버튼: 설정이 수정되지 않았음을 나타냅니다."
|
||||||
|
|
Binary file not shown.
|
@ -1224,8 +1224,8 @@ msgstr "Weet u zeker dat u wilt doorgaan?"
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:1915
|
#: src/slic3r/GUI/DoubleSlider.cpp:1915
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select YES if you want to delete all saved tool changes,\n"
|
"Select YES if you want to delete all saved tool changes,\n"
|
||||||
"\tNO if you want all tool changes switch to color changes, \n"
|
"NO if you want all tool changes switch to color changes,\n"
|
||||||
"\tor CANCEL to leave it unchanged"
|
"or CANCEL to leave it unchanged"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Selecteer JA als u alle opgeslagen toolwisselingen wilt verwijdere,\n"
|
"Selecteer JA als u alle opgeslagen toolwisselingen wilt verwijdere,\n"
|
||||||
"Selecteer NEE als u alle toolwisselingen wil omzetten in kleurwisselingen\n"
|
"Selecteer NEE als u alle toolwisselingen wil omzetten in kleurwisselingen\n"
|
||||||
|
@ -5264,11 +5264,9 @@ msgstr "Huidige preset is gebaseerd op de standaard preset."
|
||||||
#: src/slic3r/GUI/Tab.cpp:962
|
#: src/slic3r/GUI/Tab.cpp:962
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Current preset is inherited from:\n"
|
"Current preset is inherited from"
|
||||||
"\t%s"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Huidige preset is gebaseerd op:\n"
|
"Huidige preset is gebaseerd op"
|
||||||
"\t%s"
|
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:966
|
#: src/slic3r/GUI/Tab.cpp:966
|
||||||
msgid "It can't be deleted or modified."
|
msgid "It can't be deleted or modified."
|
||||||
|
@ -5544,16 +5542,18 @@ msgstr "Open een CA-certificaatbestand"
|
||||||
#: src/slic3r/GUI/Tab.cpp:1759
|
#: src/slic3r/GUI/Tab.cpp:1759
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"HTTPS CA File:\n"
|
"On this system, %s uses HTTPS certificates from the system Certificate "
|
||||||
" \tOn this system, %s uses HTTPS certificates from the system Certificate "
|
"Store or Keychain."
|
||||||
"Store or Keychain.\n"
|
msgstr ""
|
||||||
" \tTo use a custom CA file, please import your CA file into Certificate "
|
"%s gebruikt op dit systeem HTTPS-certificaten van de Certificate Store "
|
||||||
|
"of Keychain."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1759
|
||||||
|
msgid ""
|
||||||
|
"To use a custom CA file, please import your CA file into Certificate "
|
||||||
"Store / Keychain."
|
"Store / Keychain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"HTTPS-CA-bestand:\n"
|
"Om een aangepast CA-bestand te gebruiken moet uw CA-bestand in de "
|
||||||
" \t%s gebruikt op dit systeem HTTPS-certificaten van de Certificate Store "
|
|
||||||
"of Keychain.\n"
|
|
||||||
" \tOm een aangepast CA-bestand te gebruiken moet uw CA-bestand in de "
|
|
||||||
"Certificate Store of Keychain geïmporteerd worden."
|
"Certificate Store of Keychain geïmporteerd worden."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1799 src/slic3r/GUI/Tab.cpp:2043
|
#: src/slic3r/GUI/Tab.cpp:1799 src/slic3r/GUI/Tab.cpp:2043
|
||||||
|
@ -5855,11 +5855,11 @@ msgstr "Wit bolletje"
|
||||||
#. TRN Description for "WHITE BULLET"
|
#. TRN Description for "WHITE BULLET"
|
||||||
#: src/slic3r/GUI/Tab.cpp:3255
|
#: src/slic3r/GUI/Tab.cpp:3255
|
||||||
msgid ""
|
msgid ""
|
||||||
"for the left button: \tindicates a non-system (or non-default) preset,\n"
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
"for the right button: \tindicates that the settings hasn't been modified."
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"linker knop: \tgeeft een niet-systeempreset aan,\n"
|
"linker knop: geeft een niet-systeempreset aan,\n"
|
||||||
"rechter knop: \tgeeft aan dat de instelling niet veranderd is."
|
"rechter knop: geeft aan dat de instelling niet veranderd is."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:3258
|
#: src/slic3r/GUI/Tab.cpp:3258
|
||||||
msgid "BACK ARROW"
|
msgid "BACK ARROW"
|
||||||
|
|
Binary file not shown.
|
@ -5,7 +5,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || n%10 == 1 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 12 && n%100 <= 14)) ? 2 : 3);\n"
|
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || n%10 == 1 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 12 && n%100 <= 14)) ? 2 : 3);\n"
|
||||||
"X-Generator: Poedit 2.2.1\n"
|
"X-Generator: Poedit 2.3\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
|
@ -1032,7 +1032,7 @@ msgstr "Mosty objętościowe"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Plater.cpp:534 src/slic3r/GUI/Tab.cpp:1117
|
#: src/slic3r/GUI/Plater.cpp:534 src/slic3r/GUI/Tab.cpp:1117
|
||||||
msgid "Brim"
|
msgid "Brim"
|
||||||
msgstr "Brim (obramowanie)"
|
msgstr "Brim"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:244
|
#: src/libslic3r/PrintConfig.cpp:244
|
||||||
msgid "Brim width"
|
msgid "Brim width"
|
||||||
|
@ -1561,6 +1561,10 @@ msgstr "Sześcienny"
|
||||||
msgid "Current mode is %s"
|
msgid "Current mode is %s"
|
||||||
msgstr "Obecny tryb to %s"
|
msgstr "Obecny tryb to %s"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:959
|
||||||
|
msgid "Current preset is inherited from"
|
||||||
|
msgstr "Obecny zestaw ustawień jest dziedziczony z"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:957
|
#: src/slic3r/GUI/Tab.cpp:957
|
||||||
msgid "Current preset is inherited from the default preset."
|
msgid "Current preset is inherited from the default preset."
|
||||||
msgstr "Obecny zestaw ustawień jest dziedziczony z zestawu domyślnego."
|
msgstr "Obecny zestaw ustawień jest dziedziczony z zestawu domyślnego."
|
||||||
|
@ -2956,6 +2960,15 @@ msgstr ""
|
||||||
"dla lewego przycisku: wskazuje na niesystemowy (lub inny niż domyślny) zestaw ustawień,\n"
|
"dla lewego przycisku: wskazuje na niesystemowy (lub inny niż domyślny) zestaw ustawień,\n"
|
||||||
"dla prawego przycisku: wskazuje, że ustawienia nie zostały zmodyfikowane."
|
"dla prawego przycisku: wskazuje, że ustawienia nie zostały zmodyfikowane."
|
||||||
|
|
||||||
|
#. TRN Description for "WHITE BULLET"
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:3267
|
||||||
|
msgid ""
|
||||||
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
|
msgstr ""
|
||||||
|
"dla lewego przycisku: wskazuje na niesystemowy (lub inny niż domyślny) zestaw ustawień,\n"
|
||||||
|
"dla prawego przycisku: wskazuje, że ustawienia nie zostały zmodyfikowane."
|
||||||
|
|
||||||
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
#: src/slic3r/GUI/ConfigManipulation.cpp:136
|
||||||
msgid ""
|
msgid ""
|
||||||
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
"For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
|
@ -4116,6 +4129,10 @@ msgstr "Max"
|
||||||
msgid "Max bridge length"
|
msgid "Max bridge length"
|
||||||
msgstr "Maksymalna długość mostu"
|
msgstr "Maksymalna długość mostu"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2658
|
||||||
|
msgid "Max bridges on a pillar"
|
||||||
|
msgstr "Maks. liczba mostków na słupku"
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2822
|
#: src/libslic3r/PrintConfig.cpp:2822
|
||||||
msgid "Max merge distance"
|
msgid "Max merge distance"
|
||||||
msgstr "Maksymalny dystans łączenia"
|
msgstr "Maksymalny dystans łączenia"
|
||||||
|
@ -4284,6 +4301,10 @@ msgstr "Maksymalny jerk Y"
|
||||||
msgid "Maximum jerk Z"
|
msgid "Maximum jerk Z"
|
||||||
msgstr "Maksymalny jerk Z"
|
msgstr "Maksymalny jerk Z"
|
||||||
|
|
||||||
|
#: src/libslic3r/PrintConfig.cpp:2660
|
||||||
|
msgid "Maximum number of bridges that can be placed on a pillar. Bridges hold support point pinheads and connect to pillars as small branches."
|
||||||
|
msgstr "Maksymalna liczba mostków, która zostanie umieszczona na słupku podpory. Mostki wspierają łączniki podpór i łączą słupki podpór."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:598
|
#: src/libslic3r/PrintConfig.cpp:598
|
||||||
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
msgid "Maximum volumetric speed allowed for this filament. Limits the maximum volumetric speed of a print to the minimum of print and filament volumetric speed. Set to zero for no limit."
|
||||||
msgstr "Maksymalna prędkość objętościowa dla tego filamentu. Ogranicza maksymalną prędkość objętościową do minimum objętościowej prędkości druku i filamentu. Ustaw zero aby usunąć ograniczenie."
|
msgstr "Maksymalna prędkość objętościowa dla tego filamentu. Ogranicza maksymalną prędkość objętościową do minimum objętościowej prędkości druku i filamentu. Ustaw zero aby usunąć ograniczenie."
|
||||||
|
@ -4954,6 +4975,11 @@ msgstr "obecnego Modelu"
|
||||||
msgid "Offset"
|
msgid "Offset"
|
||||||
msgstr "Offset"
|
msgstr "Offset"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1755
|
||||||
|
#, c-format
|
||||||
|
msgid "On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."
|
||||||
|
msgstr "W tym systemie, %s używa certyfikatu HTTPS z magazynu systemowego (Certificate Store) lub Keychain."
|
||||||
|
|
||||||
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
#: src/slic3r/GUI/DoubleSlider.cpp:950
|
||||||
msgid "One layer mode"
|
msgid "One layer mode"
|
||||||
msgstr "Tryb jednej warstwy"
|
msgstr "Tryb jednej warstwy"
|
||||||
|
@ -6430,6 +6456,16 @@ msgstr ""
|
||||||
"NIE, jeśli chcesz przełączyć zmiany narzędzi na zmiany koloru lub\n"
|
"NIE, jeśli chcesz przełączyć zmiany narzędzi na zmiany koloru lub\n"
|
||||||
"ANULUJ, aby pozostawić bez zmian."
|
"ANULUJ, aby pozostawić bez zmian."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/DoubleSlider.cpp:1917
|
||||||
|
msgid ""
|
||||||
|
"Select YES if you want to delete all saved tool changes, \n"
|
||||||
|
"NO if you want all tool changes switch to color changes, \n"
|
||||||
|
"or CANCEL to leave it unchanged."
|
||||||
|
msgstr ""
|
||||||
|
"Wybierz TAK, jeśli chcesz usunąć wszystkie zapisane zmiany narzędzi,\n"
|
||||||
|
"NIE, jeśli chcesz przełączyć zmiany narzędzi na zmiany koloru lub\n"
|
||||||
|
"ANULUJ, aby pozostawić bez zmian."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Selection.cpp:146
|
#: src/slic3r/GUI/Selection.cpp:146
|
||||||
msgid "Selection-Add"
|
msgid "Selection-Add"
|
||||||
msgstr "Zaznaczenie-Dodaj"
|
msgstr "Zaznaczenie-Dodaj"
|
||||||
|
@ -7738,6 +7774,14 @@ msgstr "Wybrany model nie może być podzielony ponieważ składa się z więcej
|
||||||
msgid "The selected object couldn't be split because it contains only one part."
|
msgid "The selected object couldn't be split because it contains only one part."
|
||||||
msgstr "Wybrany model nie może być rozdzielony ponieważ zawiera tylko jedną część."
|
msgstr "Wybrany model nie może być rozdzielony ponieważ zawiera tylko jedną część."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/MainFrame.cpp:432
|
||||||
|
msgid ""
|
||||||
|
"The selected project is no longer available.\n"
|
||||||
|
"Do you want to remove it from the recent projects list ?"
|
||||||
|
msgstr ""
|
||||||
|
"Wybrany obiekt nie jest już dostępny.\n"
|
||||||
|
"Czy chcesz usunąć go z listy niedawno używanych projektów?"
|
||||||
|
|
||||||
#: src/slic3r/GUI/MainFrame.cpp:422
|
#: src/slic3r/GUI/MainFrame.cpp:422
|
||||||
msgid "The selected project is no more available"
|
msgid "The selected project is no more available"
|
||||||
msgstr "Wybrany projekt nie jest dostępny"
|
msgstr "Wybrany projekt nie jest dostępny"
|
||||||
|
@ -8083,6 +8127,10 @@ msgstr "To jest najniższa możliwa do wydrukowania wysokość warstwy dla tego
|
||||||
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
msgstr "Dzieje się to zazwyczaj z powodu zbyt małych odcinków ekstruzji (są one pomijane) lub uszkodzenia modelu. Spróbuj naprawić model lub zmienić jego orientację na stole."
|
msgstr "Dzieje się to zazwyczaj z powodu zbyt małych odcinków ekstruzji (są one pomijane) lub uszkodzenia modelu. Spróbuj naprawić model lub zmienić jego orientację na stole."
|
||||||
|
|
||||||
|
#: src/libslic3r/GCode.cpp:639
|
||||||
|
msgid "This is usually caused by negligibly small extrusions or by a faulty model. Try to repair the model or change its orientation on the bed."
|
||||||
|
msgstr "Dzieje się to zazwyczaj z powodu zbyt małych odcinków ekstruzji (są one pomijane) lub uszkodzenia modelu. Spróbuj naprawić model lub zmienić jego orientację na stole."
|
||||||
|
|
||||||
#: src/libslic3r/PrintConfig.cpp:2215
|
#: src/libslic3r/PrintConfig.cpp:2215
|
||||||
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
msgid "This matrix describes volumes (in cubic milimetres) required to purge the new filament on the wipe tower for any given pair of tools."
|
||||||
msgstr "Ta formuła określa objętość (w milimetrach sześciennych) wymaganą do wyczyszczenia filamentu na wieży czyszczącej dla danej pary narzędzi (filamentów)."
|
msgstr "Ta formuła określa objętość (w milimetrach sześciennych) wymaganą do wyczyszczenia filamentu na wieży czyszczącej dla danej pary narzędzi (filamentów)."
|
||||||
|
@ -8224,6 +8272,10 @@ msgstr "Do modeli"
|
||||||
msgid "To parts"
|
msgid "To parts"
|
||||||
msgstr "Na części"
|
msgstr "Na części"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1756
|
||||||
|
msgid "To use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
||||||
|
msgstr "Aby użyć własnego certyfikatu, zaimportuj plik do Certificate Store / Keychain."
|
||||||
|
|
||||||
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
#: src/slic3r/GUI/GUI_ObjectManipulation.cpp:263
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Toggle %c axis mirroring"
|
msgid "Toggle %c axis mirroring"
|
||||||
|
|
Binary file not shown.
|
@ -4196,11 +4196,9 @@ msgstr "Predefinição atual é herdada da predefinição padrão."
|
||||||
#: src/slic3r/GUI/Tab.cpp:950
|
#: src/slic3r/GUI/Tab.cpp:950
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Current preset is inherited from:\n"
|
"Current preset is inherited from"
|
||||||
"\t%s"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Predefinição atual é herdada de:\n"
|
"Predefinição atual é herdada de"
|
||||||
"\t%s"
|
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:954
|
#: src/slic3r/GUI/Tab.cpp:954
|
||||||
msgid "It can't be deleted or modified."
|
msgid "It can't be deleted or modified."
|
||||||
|
@ -4472,16 +4470,18 @@ msgstr "Abra o arquivo de certificado da CA"
|
||||||
#: src/slic3r/GUI/Tab.cpp:1962
|
#: src/slic3r/GUI/Tab.cpp:1962
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"HTTPS CA File:\n"
|
"On this system, %s uses HTTPS certificates from the system Certificate "
|
||||||
" \tOn this system, %s uses HTTPS certificates from the system Certificate "
|
"Store or Keychain."
|
||||||
"Store or Keychain.\n"
|
msgstr ""
|
||||||
" \tTo use a custom CA file, please import your CA file into Certificate "
|
"Neste sistema, %s usa certificados HTTPS do sistema Certificate Store "
|
||||||
|
"ou keychain."
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1962
|
||||||
|
msgid ""
|
||||||
|
"To use a custom CA file, please import your CA file into Certificate "
|
||||||
"Store / Keychain."
|
"Store / Keychain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Arquivo HTTPS CA:\n"
|
"Para usar um arquivo de CA personalizado, importe seu arquivo de CA "
|
||||||
" \tNeste sistema, %s usa certificados HTTPS do sistema Certificate Store "
|
|
||||||
"ou keychain.\n"
|
|
||||||
" \tPara usar um arquivo de CA personalizado, importe seu arquivo de CA "
|
|
||||||
"para o repositório de certificados/chaveiro."
|
"para o repositório de certificados/chaveiro."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:2002 src/slic3r/GUI/Tab.cpp:2243
|
#: src/slic3r/GUI/Tab.cpp:2002 src/slic3r/GUI/Tab.cpp:2243
|
||||||
|
@ -4778,12 +4778,12 @@ msgstr "PONTO BRANCO"
|
||||||
#. TRN Description for "WHITE BULLET"
|
#. TRN Description for "WHITE BULLET"
|
||||||
#: src/slic3r/GUI/Tab.cpp:3427
|
#: src/slic3r/GUI/Tab.cpp:3427
|
||||||
msgid ""
|
msgid ""
|
||||||
"for the left button: \tindicates a non-system (or non-default) preset,\n"
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
"for the right button: \tindicates that the settings hasn't been modified."
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"para o botão esquerdo: \t indica uma predefinição que não é do sistema (ou "
|
"para o botão esquerdo: indica uma predefinição que não é do sistema (ou "
|
||||||
"não-padrão),\n"
|
"não-padrão),\n"
|
||||||
"para o botão direito: \t indica que as config. não foram modificadas."
|
"para o botão direito: indica que as config. não foram modificadas."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:3430
|
#: src/slic3r/GUI/Tab.cpp:3430
|
||||||
msgid "BACK ARROW"
|
msgid "BACK ARROW"
|
||||||
|
|
Binary file not shown.
|
@ -3679,13 +3679,15 @@ msgstr "CA sertifika dosyasını aç"
|
||||||
#: src/slic3r/GUI/Tab.cpp:1810
|
#: src/slic3r/GUI/Tab.cpp:1810
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"HTTPS CA File:\n"
|
"On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."
|
||||||
" \tOn this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.\n"
|
|
||||||
" \tTo use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"HTTPS CA Dosyası:\n"
|
"Bu sistemde, %s , sistem Sertifika Deposu veya Anahtarlıktan HTTPS sertifikaları kullanır."
|
||||||
" \tBu sistemde, %s , sistem Sertifika Deposu veya Anahtarlıktan HTTPS sertifikaları kullanır.\n"
|
|
||||||
" \tÖzel bir CA dosyası kullanmak için, lütfen CA dosyanızı Sertifika Deposu/Anahtarlık içine aktarın."
|
#: src/slic3r/GUI/Tab.cpp:1810
|
||||||
|
msgid ""
|
||||||
|
"To use a custom CA file, please import your CA file into Certificate Store / Keychain."
|
||||||
|
msgstr ""
|
||||||
|
"Özel bir CA dosyası kullanmak için, lütfen CA dosyanızı Sertifika Deposu/Anahtarlık içine aktarın."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1850 src/slic3r/GUI/Tab.cpp:2051
|
#: src/slic3r/GUI/Tab.cpp:1850 src/slic3r/GUI/Tab.cpp:2051
|
||||||
msgid "Size and coordinates"
|
msgid "Size and coordinates"
|
||||||
|
@ -3948,11 +3950,11 @@ msgstr "BEYAZ NOKTA"
|
||||||
#. TRN Description for "WHITE BULLET"
|
#. TRN Description for "WHITE BULLET"
|
||||||
#: src/slic3r/GUI/Tab.cpp:3129
|
#: src/slic3r/GUI/Tab.cpp:3129
|
||||||
msgid ""
|
msgid ""
|
||||||
"for the left button: \tindicates a non-system preset,\n"
|
"for the left button: indicates a non-system preset,\n"
|
||||||
"for the right button: \tindicates that the settings hasn't been modified."
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"sol tuş için: \tsistem dışı bir ön ayarı gösterir,\n"
|
"sol tuş için: sistem dışı bir ön ayarı gösterir,\n"
|
||||||
"sağ tuş için: \tayarların değiştirilmediğini gösterir."
|
"sağ tuş için: ayarların değiştirilmediğini gösterir."
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:3103
|
#: src/slic3r/GUI/Tab.cpp:3103
|
||||||
msgid "BACK ARROW"
|
msgid "BACK ARROW"
|
||||||
|
|
Binary file not shown.
|
@ -4106,11 +4106,9 @@ msgstr "当前预设从默认预设继承。"
|
||||||
#: src/slic3r/GUI/Tab.cpp:947
|
#: src/slic3r/GUI/Tab.cpp:947
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Current preset is inherited from:\n"
|
"Current preset is inherited from"
|
||||||
"\t%s"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"当前预设继承自:\n"
|
"当前预设继承自"
|
||||||
"\t%s"
|
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:951
|
#: src/slic3r/GUI/Tab.cpp:951
|
||||||
msgid "It can't be deleted or modified."
|
msgid "It can't be deleted or modified."
|
||||||
|
@ -4375,15 +4373,17 @@ msgstr "打开 CA 证书文件"
|
||||||
#: src/slic3r/GUI/Tab.cpp:1959
|
#: src/slic3r/GUI/Tab.cpp:1959
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"HTTPS CA File:\n"
|
"On this system, %s uses HTTPS certificates from the system Certificate "
|
||||||
" \tOn this system, %s uses HTTPS certificates from the system Certificate "
|
"Store or Keychain."
|
||||||
"Store or Keychain.\n"
|
msgstr ""
|
||||||
" \tTo use a custom CA file, please import your CA file into Certificate "
|
"在此系统上,%s 使用来自系统证书存储或钥匙串的 HTTPS 证书。"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1959
|
||||||
|
msgid ""
|
||||||
|
"To use a custom CA file, please import your CA file into Certificate "
|
||||||
"Store / Keychain."
|
"Store / Keychain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"HTTPS CA 文件:\n"
|
"要使用自定义 CA 文件,请将 CA 文件导入证书存储/钥匙串。"
|
||||||
" \t在此系统上,%s 使用来自系统证书存储或钥匙串的 HTTPS 证书。\n"
|
|
||||||
" \t要使用自定义 CA 文件,请将 CA 文件导入证书存储/钥匙串。"
|
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1999 src/slic3r/GUI/Tab.cpp:2240
|
#: src/slic3r/GUI/Tab.cpp:1999 src/slic3r/GUI/Tab.cpp:2240
|
||||||
msgid "Size and coordinates"
|
msgid "Size and coordinates"
|
||||||
|
@ -4671,8 +4671,8 @@ msgstr "白色子弹"
|
||||||
#. TRN Description for "WHITE BULLET"
|
#. TRN Description for "WHITE BULLET"
|
||||||
#: src/slic3r/GUI/Tab.cpp:3424
|
#: src/slic3r/GUI/Tab.cpp:3424
|
||||||
msgid ""
|
msgid ""
|
||||||
"for the left button: \tindicates a non-system (or non-default) preset,\n"
|
"for the left button: indicates a non-system (or non-default) preset,\n"
|
||||||
"for the right button: \tindicates that the settings hasn't been modified."
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"对于左侧按钮:指示非系统(或非默认)预设,\n"
|
"对于左侧按钮:指示非系统(或非默认)预设,\n"
|
||||||
"对于右侧按钮:指示设置尚未修改。"
|
"对于右侧按钮:指示设置尚未修改。"
|
||||||
|
|
Binary file not shown.
|
@ -3391,16 +3391,19 @@ msgid "Open CA certificate file"
|
||||||
msgstr "打開 CA 證書文件"
|
msgstr "打開 CA 證書文件"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1725
|
#: src/slic3r/GUI/Tab.cpp:1725
|
||||||
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"HTTPS CA File:\n"
|
"On this system, %s uses HTTPS certificates from the system Certificate "
|
||||||
"\tOn this system, Slic3r uses HTTPS certificates from the system Certificate "
|
"Store or Keychain."
|
||||||
"Store or Keychain.\n"
|
msgstr ""
|
||||||
"\tTo use a custom CA file, please import your CA file into Certificate "
|
"在此係統上, %s 使用來自系統證書存儲或鑰匙串的 https 證書。"
|
||||||
|
|
||||||
|
#: src/slic3r/GUI/Tab.cpp:1725
|
||||||
|
msgid ""
|
||||||
|
"To use a custom CA file, please import your CA file into Certificate "
|
||||||
"Store / Keychain."
|
"Store / Keychain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"HTTPS CA 文件:\n"
|
"要使用自定義 CA 文件, 請將 CA 文件導入到證書存儲/鑰匙串。"
|
||||||
"\t在此係統上, Slic3r 使用來自系統證書存儲或鑰匙串的 https 證書。\n"
|
|
||||||
"\t要使用自定義 CA 文件, 請將 CA 文件導入到證書存儲/鑰匙串。"
|
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:1763 src/slic3r/GUI/Tab.cpp:1964
|
#: src/slic3r/GUI/Tab.cpp:1763 src/slic3r/GUI/Tab.cpp:1964
|
||||||
msgid "Size and coordinates"
|
msgid "Size and coordinates"
|
||||||
|
@ -3664,11 +3667,11 @@ msgstr ""
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:2998
|
#: src/slic3r/GUI/Tab.cpp:2998
|
||||||
msgid ""
|
msgid ""
|
||||||
"WHITE BULLET;for the left button: \tindicates a non-system preset,\n"
|
"WHITE BULLET;for the left button: indicates a non-system preset,\n"
|
||||||
"for the right button: \tindicates that the settings hasn't been modified."
|
"for the right button: indicates that the settings hasn't been modified."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"白色彈頭; 對於左側按鈕: \t表示非系統預設,\n"
|
"白色彈頭; 對於左側按鈕: 表示非系統預設,\n"
|
||||||
"對於右側按鈕: \t表示設置尚未被修改。"
|
"對於右側按鈕: 表示設置尚未被修改。"
|
||||||
|
|
||||||
#: src/slic3r/GUI/Tab.cpp:3002
|
#: src/slic3r/GUI/Tab.cpp:3002
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
384
resources/profiles/Lulzbot.ini
Normal file
384
resources/profiles/Lulzbot.ini
Normal file
|
@ -0,0 +1,384 @@
|
||||||
|
# generated by PrusaSlicer 2.1.1+win64 on 2020-02-25 at 01:51:21 UTC
|
||||||
|
|
||||||
|
[vendor]
|
||||||
|
# Vendor name will be shown by the Config Wizard.
|
||||||
|
name = Lulzbot
|
||||||
|
config_version = 0.0.1
|
||||||
|
config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Lulzbot/
|
||||||
|
|
||||||
|
[printer_model:MINI_AERO]
|
||||||
|
name = Mini Aero
|
||||||
|
variants = 0.5
|
||||||
|
technology = FFF
|
||||||
|
#bed_model = mini_bed.stl
|
||||||
|
#bed_texture = mini.svg
|
||||||
|
default_materials = ColorFabb PLA-PHA @lulzbot;PrintedSolid Jesse PLA @lulzbot
|
||||||
|
|
||||||
|
[printer_model:TAZ6_AERO]
|
||||||
|
name = Taz6 Aero
|
||||||
|
variants = 0.5
|
||||||
|
technology = FFF
|
||||||
|
default_materials = ColorFabb PLA-PHA @lulzbot;PrintedSolid Jesse PLA @lulzbot
|
||||||
|
|
||||||
|
[print:0.3mm @lulzbot]
|
||||||
|
avoid_crossing_perimeters = 0
|
||||||
|
bottom_fill_pattern = rectilinear
|
||||||
|
bottom_solid_layers = 3
|
||||||
|
bridge_acceleration = 500
|
||||||
|
bridge_angle = 0
|
||||||
|
bridge_flow_ratio = 1
|
||||||
|
bridge_speed = 30
|
||||||
|
brim_width = 0
|
||||||
|
clip_multipart_objects = 0
|
||||||
|
compatible_printers =
|
||||||
|
compatible_printers_condition =
|
||||||
|
complete_objects = 0
|
||||||
|
default_acceleration = 500
|
||||||
|
dont_support_bridges = 1
|
||||||
|
elefant_foot_compensation = 0
|
||||||
|
ensure_vertical_shell_thickness = 0
|
||||||
|
external_perimeter_extrusion_width = 0.56
|
||||||
|
external_perimeter_speed = 50%
|
||||||
|
external_perimeters_first = 0
|
||||||
|
extra_perimeters = 1
|
||||||
|
extruder_clearance_height = 20
|
||||||
|
extruder_clearance_radius = 20
|
||||||
|
extrusion_width = 0.56
|
||||||
|
fill_angle = 45
|
||||||
|
fill_density = 20%
|
||||||
|
fill_pattern = gyroid
|
||||||
|
first_layer_acceleration = 500
|
||||||
|
first_layer_extrusion_width = 0.6
|
||||||
|
first_layer_height = 100%
|
||||||
|
first_layer_speed = 40%
|
||||||
|
gap_fill_speed = 20
|
||||||
|
gcode_comments = 0
|
||||||
|
gcode_label_objects = 0
|
||||||
|
infill_acceleration = 500
|
||||||
|
infill_every_layers = 1
|
||||||
|
infill_extruder = 1
|
||||||
|
infill_extrusion_width = 0.56
|
||||||
|
infill_first = 0
|
||||||
|
infill_only_where_needed = 0
|
||||||
|
infill_overlap = 25%
|
||||||
|
infill_speed = 60
|
||||||
|
inherits =
|
||||||
|
interface_shells = 0
|
||||||
|
layer_height = 0.3
|
||||||
|
max_print_speed = 80
|
||||||
|
max_volumetric_speed = 0
|
||||||
|
min_skirt_length = 0
|
||||||
|
notes =
|
||||||
|
only_retract_when_crossing_perimeters = 1
|
||||||
|
ooze_prevention = 0
|
||||||
|
output_filename_format = [printer_settings_id]_[input_filename_base]_[layer_height]_[filament_type]_[print_time].gcode
|
||||||
|
overhangs = 1
|
||||||
|
perimeter_acceleration = 500
|
||||||
|
perimeter_extruder = 1
|
||||||
|
perimeter_extrusion_width = 0.56
|
||||||
|
perimeter_speed = 60
|
||||||
|
perimeters = 3
|
||||||
|
post_process =
|
||||||
|
raft_layers = 0
|
||||||
|
resolution = 0
|
||||||
|
seam_position = nearest
|
||||||
|
single_extruder_multi_material_priming = 1
|
||||||
|
skirt_distance = 3
|
||||||
|
skirt_height = 1
|
||||||
|
skirts = 3
|
||||||
|
slice_closing_radius = 0.049
|
||||||
|
small_perimeter_speed = 15
|
||||||
|
solid_infill_below_area = 70
|
||||||
|
solid_infill_every_layers = 0
|
||||||
|
solid_infill_extruder = 1
|
||||||
|
solid_infill_extrusion_width = 0.56
|
||||||
|
solid_infill_speed = 60
|
||||||
|
spiral_vase = 0
|
||||||
|
standby_temperature_delta = -5
|
||||||
|
support_material = 0
|
||||||
|
support_material_angle = 0
|
||||||
|
support_material_auto = 1
|
||||||
|
support_material_buildplate_only = 0
|
||||||
|
support_material_contact_distance = 0.2
|
||||||
|
support_material_enforce_layers = 0
|
||||||
|
support_material_extruder = 1
|
||||||
|
support_material_extrusion_width = 0.44
|
||||||
|
support_material_interface_contact_loops = 0
|
||||||
|
support_material_interface_extruder = 1
|
||||||
|
support_material_interface_layers = 3
|
||||||
|
support_material_interface_spacing = 0
|
||||||
|
support_material_interface_speed = 100%
|
||||||
|
support_material_pattern = rectilinear
|
||||||
|
support_material_spacing = 2.5
|
||||||
|
support_material_speed = 60
|
||||||
|
support_material_synchronize_layers = 0
|
||||||
|
support_material_threshold = 0
|
||||||
|
support_material_with_sheath = 1
|
||||||
|
support_material_xy_spacing = 50%
|
||||||
|
thin_walls = 1
|
||||||
|
threads = 12
|
||||||
|
top_fill_pattern = rectilinear
|
||||||
|
top_infill_extrusion_width = 0.52
|
||||||
|
top_solid_infill_speed = 40
|
||||||
|
top_solid_layers = 3
|
||||||
|
travel_speed = 175
|
||||||
|
wipe_tower = 0
|
||||||
|
wipe_tower_bridging = 10
|
||||||
|
wipe_tower_rotation_angle = 0
|
||||||
|
wipe_tower_width = 60
|
||||||
|
wipe_tower_x = 180
|
||||||
|
wipe_tower_y = 140
|
||||||
|
xy_size_compensation = 0
|
||||||
|
|
||||||
|
[filament:ColorFabb PLA-PHA @lulzbot]
|
||||||
|
filament_vendor = ColorFabb
|
||||||
|
bed_temperature = 60
|
||||||
|
bridge_fan_speed = 100
|
||||||
|
compatible_printers =
|
||||||
|
compatible_printers_condition =
|
||||||
|
compatible_prints =
|
||||||
|
compatible_prints_condition =
|
||||||
|
cooling = 1
|
||||||
|
disable_fan_first_layers = 3
|
||||||
|
end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n"
|
||||||
|
extrusion_multiplier = 1
|
||||||
|
fan_always_on = 0
|
||||||
|
fan_below_layer_time = 60
|
||||||
|
filament_colour = #29B2B2
|
||||||
|
filament_cooling_final_speed = 3.4
|
||||||
|
filament_cooling_initial_speed = 2.2
|
||||||
|
filament_cooling_moves = 4
|
||||||
|
filament_cost = 0
|
||||||
|
filament_density = 1.25
|
||||||
|
filament_deretract_speed = nil
|
||||||
|
filament_diameter = 2.85
|
||||||
|
filament_load_time = 0
|
||||||
|
filament_loading_speed = 28
|
||||||
|
filament_loading_speed_start = 3
|
||||||
|
filament_max_volumetric_speed = 0
|
||||||
|
filament_minimal_purge_on_wipe_tower = 15
|
||||||
|
filament_notes = ""
|
||||||
|
filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
|
||||||
|
filament_retract_before_travel = nil
|
||||||
|
filament_retract_before_wipe = nil
|
||||||
|
filament_retract_layer_change = nil
|
||||||
|
filament_retract_length = nil
|
||||||
|
filament_retract_lift = nil
|
||||||
|
filament_retract_lift_above = nil
|
||||||
|
filament_retract_lift_below = nil
|
||||||
|
filament_retract_restart_extra = nil
|
||||||
|
filament_retract_speed = nil
|
||||||
|
filament_soluble = 0
|
||||||
|
filament_toolchange_delay = 0
|
||||||
|
filament_type = PLA
|
||||||
|
filament_unload_time = 0
|
||||||
|
filament_unloading_speed = 90
|
||||||
|
filament_unloading_speed_start = 100
|
||||||
|
filament_wipe = nil
|
||||||
|
first_layer_bed_temperature = 60
|
||||||
|
first_layer_temperature = 200
|
||||||
|
inherits =
|
||||||
|
max_fan_speed = 100
|
||||||
|
min_fan_speed = 35
|
||||||
|
min_print_speed = 10
|
||||||
|
slowdown_below_layer_time = 5
|
||||||
|
start_filament_gcode = "; Filament gcode\n"
|
||||||
|
temperature = 200
|
||||||
|
|
||||||
|
[filament:PrintedSolid Jesse PLA @lulzbot]
|
||||||
|
filament_vendor = PrintedSolid
|
||||||
|
bed_temperature = 60
|
||||||
|
bridge_fan_speed = 100
|
||||||
|
compatible_printers =
|
||||||
|
compatible_printers_condition =
|
||||||
|
compatible_prints =
|
||||||
|
compatible_prints_condition =
|
||||||
|
cooling = 1
|
||||||
|
disable_fan_first_layers = 3
|
||||||
|
end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n"
|
||||||
|
extrusion_multiplier = 1
|
||||||
|
fan_always_on = 0
|
||||||
|
fan_below_layer_time = 60
|
||||||
|
filament_colour = #29B2B2
|
||||||
|
filament_cooling_final_speed = 3.4
|
||||||
|
filament_cooling_initial_speed = 2.2
|
||||||
|
filament_cooling_moves = 4
|
||||||
|
filament_cost = 27
|
||||||
|
filament_density = 1.25
|
||||||
|
filament_deretract_speed = nil
|
||||||
|
filament_diameter = 2.85
|
||||||
|
filament_load_time = 0
|
||||||
|
filament_loading_speed = 28
|
||||||
|
filament_loading_speed_start = 3
|
||||||
|
filament_max_volumetric_speed = 0
|
||||||
|
filament_minimal_purge_on_wipe_tower = 15
|
||||||
|
filament_notes = ""
|
||||||
|
filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
|
||||||
|
filament_retract_before_travel = nil
|
||||||
|
filament_retract_before_wipe = nil
|
||||||
|
filament_retract_layer_change = nil
|
||||||
|
filament_retract_length = nil
|
||||||
|
filament_retract_lift = nil
|
||||||
|
filament_retract_lift_above = nil
|
||||||
|
filament_retract_lift_below = nil
|
||||||
|
filament_retract_restart_extra = nil
|
||||||
|
filament_retract_speed = nil
|
||||||
|
filament_soluble = 0
|
||||||
|
filament_toolchange_delay = 0
|
||||||
|
filament_type = PLA
|
||||||
|
filament_unload_time = 0
|
||||||
|
filament_unloading_speed = 90
|
||||||
|
filament_unloading_speed_start = 100
|
||||||
|
filament_wipe = nil
|
||||||
|
first_layer_bed_temperature = 60
|
||||||
|
first_layer_temperature = 220
|
||||||
|
inherits =
|
||||||
|
max_fan_speed = 100
|
||||||
|
min_fan_speed = 35
|
||||||
|
min_print_speed = 10
|
||||||
|
slowdown_below_layer_time = 5
|
||||||
|
start_filament_gcode = "; Filament gcode\n"
|
||||||
|
temperature = 220
|
||||||
|
|
||||||
|
[printer:Mini Aero 0.5mm]
|
||||||
|
printer_model = MINI_AERO
|
||||||
|
printer_variant = 0.5
|
||||||
|
default_print_profile = 0.3mm @lulzbot
|
||||||
|
default_filament_profile = PrintedSolid Jesse PLA @lulzbot
|
||||||
|
bed_shape = 0x0,154x0,154x154,0x154
|
||||||
|
before_layer_gcode =
|
||||||
|
between_objects_gcode =
|
||||||
|
cooling_tube_length = 5
|
||||||
|
cooling_tube_retraction = 91.5
|
||||||
|
deretract_speed = 20
|
||||||
|
end_gcode = M400 ; wait for moves to finish\nM140 S40 ; start bed cooling\nM104 S0 ; disable hotend\nM107 ; disable fans\nG92 E1 ; set extruder to 1mm for retract on print end (LulzBot Cura had 5mm, might be a contributing factor to between print Aerostruder jamming)\nM117 Cooling please wait ; progress indicator message on LCD\nG1 X5 Y5 Z158 E0 F10000 ; move to cooling position\nG1 E1 ; re-prime extruder\nM190 R40 ; wait for bed to cool down to removal temp\nM77 ; Stop GLCD Timer\nG1 X145 F1000 ; move extruder out of the way\nG1 Y175 F1000 ; present finished print\nM140 S0; cool downs\nM84 ; disable steppers\nG90 ; absolute positioning\nM117 Print Complete. ; print complete message\n
|
||||||
|
extra_loading_move = -2
|
||||||
|
extruder_colour = ""
|
||||||
|
extruder_offset = 0x0
|
||||||
|
gcode_flavor = marlin
|
||||||
|
high_current_on_filament_swap = 0
|
||||||
|
host_type = octoprint
|
||||||
|
inherits =
|
||||||
|
layer_gcode =
|
||||||
|
machine_max_acceleration_e = 10000,5000
|
||||||
|
machine_max_acceleration_extruding = 1500,1250
|
||||||
|
machine_max_acceleration_retracting = 1500,1250
|
||||||
|
machine_max_acceleration_x = 9000,1000
|
||||||
|
machine_max_acceleration_y = 9000,1000
|
||||||
|
machine_max_acceleration_z = 100,200
|
||||||
|
machine_max_feedrate_e = 40,120
|
||||||
|
machine_max_feedrate_x = 800,200
|
||||||
|
machine_max_feedrate_y = 800,200
|
||||||
|
machine_max_feedrate_z = 8,12
|
||||||
|
machine_max_jerk_e = 2.5,2.5
|
||||||
|
machine_max_jerk_x = 20,10
|
||||||
|
machine_max_jerk_y = 20,10
|
||||||
|
machine_max_jerk_z = 0.2,0.4
|
||||||
|
machine_min_extruding_rate = 0,0
|
||||||
|
machine_min_travel_rate = 0,0
|
||||||
|
max_layer_height = 0
|
||||||
|
max_print_height = 158
|
||||||
|
min_layer_height = 0.07
|
||||||
|
nozzle_diameter = 0.5
|
||||||
|
parking_pos_retraction = 92
|
||||||
|
print_host =
|
||||||
|
printer_notes = LulzBot Mini w/ Aerostruder profile for Delaware Library System, Rt9 Library and Innovation Center.
|
||||||
|
printhost_apikey =
|
||||||
|
printhost_cafile =
|
||||||
|
remaining_times = 0
|
||||||
|
retract_before_travel = 2
|
||||||
|
retract_before_wipe = 0%
|
||||||
|
retract_layer_change = 1
|
||||||
|
retract_length = 1
|
||||||
|
retract_length_toolchange = 10
|
||||||
|
retract_lift = 0
|
||||||
|
retract_lift_above = 0
|
||||||
|
retract_lift_below = 0
|
||||||
|
retract_restart_extra = 0
|
||||||
|
retract_restart_extra_toolchange = 0
|
||||||
|
retract_speed = 40
|
||||||
|
serial_port =
|
||||||
|
serial_speed = 250000
|
||||||
|
silent_mode = 0
|
||||||
|
single_extruder_multi_material = 0
|
||||||
|
start_gcode = ;This G-Code has been generated specifically for the LulzBot Mini with Aerosturder\nM73 P0 ; clear GLCD progress bar\nM75 ; start GLCD timer\nG26 ; clear potential 'probe fail' condition\nM107 ; disable fans\nM420 S0 ; disable leveling matrix\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nG92 E0 ; set extruder position to 0\nM140 S{first_layer_bed_temperature[0]} ; start bed heating up\nG28; home all axes\nG0 X0 Y187 Z156 F200 ; move away from endstops\nM109 R{first_layer_temperature[0] - 60} ; soften filament before retraction\n;G1 E-15 F75 ; retract filament (LulzBot Cura is apparently trying to cold pull, might be a contributing factor to hob gear filling with filament)\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach wiping temp\nG1 X45 Y173 F11520 ; move above wiper pad\nG1 Z0 F1200 ; push nozzle into wiper\nG1 X42 Y173 Z-.5 F4000 ; wiping\nG1 X52 Y171 Z-.5 F4000 ; wiping\nG1 X42 Y173 Z0 F4000 ; wiping\nG1 X52 Y171 F4000 ; wiping\nG1 X42 Y173 F4000 ; wiping\nG1 X52 Y171 F4000 ; wiping\nG1 X42 Y173 F4000 ; wiping\nG1 X52 Y171 F4000 ; wiping\nG1 X57 Y173 F4000 ; wiping\nG1 X77 Y171 F4000 ; wiping\nG1 X57 Y173 F4000 ; wiping\nG1 X77 Y171 F4000 ; wiping\nG1 X57 Y173 F4000 ; wiping\nG1 X87 Y171 F4000 ; wiping\nG1 X77 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X77 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X77 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X107 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X107 Y173 F4000 ; wiping\nG1 X97 Y171 F4000 ; wiping\nG1 X107 Y173 F4000 ; wiping\nG1 X112 Y171 Z-0.5 F1000 ; wiping\nG1 Z10 ; raise extruder\nG28 X0 Y0 ; home X and Y\nG0 X0 Y187 F200 ; move away from endstops\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach probe temp\nM204 S300 ; set probing acceleration\nG29 ; start auto-leveling sequence\nM420 S1 ; enable leveling matrix\nM425 Z ; use measured Z backlash for compensation\nM425 Z F0 ; turn off measured Z backlash compensation. (if activated in the quality settings, this command will automatically be ignored)\nM204 S2000 ; restore standard acceleration\nG28 X0 Y0 ; re-home to account for build variance of earlier mini builds\nG0 X0 Y187 F200 ; move away from endstops\nG0 Y152 F4000 ; move in front of wiper pad\nG4 S1 ; pause\nM400 ; wait for moves to finish\nM117 Heating... ; progress indicator message on LCD\nM109 R{first_layer_temperature[0]} ; wait for extruder to reach printing temp\nM190 R{first_layer_bed_temperature[0]} ; wait for bed to reach printing temp\nG1 Z2 E0 F75 ; prime tiny bit of filament into the nozzle\nM117 Mini Printing... ; progress indicator message on LCD\nM221 S74 ; Printer specific extrusion modifier.
|
||||||
|
thumbnails =
|
||||||
|
toolchange_gcode =
|
||||||
|
use_firmware_retraction = 0
|
||||||
|
use_relative_e_distances = 0
|
||||||
|
use_volumetric_e = 0
|
||||||
|
variable_layer_height = 1
|
||||||
|
wipe = 1
|
||||||
|
z_offset = 0
|
||||||
|
|
||||||
|
[printer:Taz6 Aero 0.5mm]
|
||||||
|
printer_model = TAZ6_AERO
|
||||||
|
printer_variant = 0.5
|
||||||
|
default_print_profile = 0.3mm @lulzbot
|
||||||
|
default_filament_profile = PrintedSolid Jesse PLA @lulzbot
|
||||||
|
bed_shape = 0x0,280x0,280x280,0x280
|
||||||
|
before_layer_gcode =
|
||||||
|
between_objects_gcode =
|
||||||
|
cooling_tube_length = 5
|
||||||
|
cooling_tube_retraction = 91.5
|
||||||
|
deretract_speed = 20
|
||||||
|
end_gcode = M400 ; wait for moves to finish\nM140 S40 ; start bed cooling\nM104 S0 ; disable hotend\nM107 ; disable fans\nG91 ; relative positioning\nG1 E-1 F300 ; filament retraction to release pressure\nG1 Z20 E-5 X-20 Y-20 F3000 ; lift up and retract even more filament\nG1 E6 ; re-prime extruder\nM117 Cooling please wait ; progress indicator message on LCD\nG90 ; absolute positioning\nG1 Y0 F3000 ; move to cooling position\nM190 R40 ; wait for bed to cool down to removal temp\nG1 Y280 F3000 ; present finished print\nM140 S0; cool downs\nM77 ; stop GLCD timer\nM84 ; disable steppers\nG90 ; absolute positioning\nM117 Print Complete. ; print complete message\n
|
||||||
|
extra_loading_move = -2
|
||||||
|
extruder_colour = ""
|
||||||
|
extruder_offset = 0x0
|
||||||
|
gcode_flavor = marlin
|
||||||
|
high_current_on_filament_swap = 0
|
||||||
|
host_type = octoprint
|
||||||
|
inherits =
|
||||||
|
layer_gcode =
|
||||||
|
machine_max_acceleration_e = 1000,5000
|
||||||
|
machine_max_acceleration_extruding = 1000,1250
|
||||||
|
machine_max_acceleration_retracting = 1000,1250
|
||||||
|
machine_max_acceleration_x = 9000,1000
|
||||||
|
machine_max_acceleration_y = 9000,1000
|
||||||
|
machine_max_acceleration_z = 100,200
|
||||||
|
machine_max_feedrate_e = 40,120
|
||||||
|
machine_max_feedrate_x = 800,200
|
||||||
|
machine_max_feedrate_y = 800,200
|
||||||
|
machine_max_feedrate_z = 3,12
|
||||||
|
machine_max_jerk_e = 2.5,2.5
|
||||||
|
machine_max_jerk_x = 12,10
|
||||||
|
machine_max_jerk_y = 12,10
|
||||||
|
machine_max_jerk_z = 0.2,0.4
|
||||||
|
machine_min_extruding_rate = 0,0
|
||||||
|
machine_min_travel_rate = 0,0
|
||||||
|
max_layer_height = 0
|
||||||
|
max_print_height = 250
|
||||||
|
min_layer_height = 0.07
|
||||||
|
nozzle_diameter = 0.5
|
||||||
|
parking_pos_retraction = 92
|
||||||
|
print_host =
|
||||||
|
printer_notes = LulzBot Taz 6 w/ Aerostruder profile for Delaware Library System, Rt9 Library and Innovation Center.
|
||||||
|
printer_technology = FFF
|
||||||
|
printhost_apikey =
|
||||||
|
printhost_cafile =
|
||||||
|
remaining_times = 0
|
||||||
|
retract_before_travel = 2
|
||||||
|
retract_before_wipe = 0%
|
||||||
|
retract_layer_change = 0
|
||||||
|
retract_length = 2
|
||||||
|
retract_length_toolchange = 10
|
||||||
|
retract_lift = 0
|
||||||
|
retract_lift_above = 0
|
||||||
|
retract_lift_below = 0
|
||||||
|
retract_restart_extra = 0
|
||||||
|
retract_restart_extra_toolchange = 0
|
||||||
|
retract_speed = 40
|
||||||
|
serial_port =
|
||||||
|
serial_speed = 250000
|
||||||
|
silent_mode = 0
|
||||||
|
single_extruder_multi_material = 0
|
||||||
|
start_gcode = ;This G-Code has been generated specifically for the LulzBot TAZ 6 with Aerosturder\nM73 P0 ; clear GLCD progress bar\nM75 ; start GLCD timer\nG26 ; clear potential 'probe fail' condition\nM107 ; disable fans\nM420 S0 ; disable leveling matrix\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nG92 E0 ; set extruder position to 0\nM140 S{first_layer_bed_temperature[0]} ; start bed heating up\nG28 XY ; home X and Y\nG1 X-19 Y258 F1000 ; move to safe homing position\nM109 R{first_layer_temperature[0] - 60} ; soften filament before homing Z\nG28 Z ; home Z\nG1 E-15 F100 ; retract filament\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach wiping temp\nG1 X-15 Y100 F3000 ; move above wiper pad\nG1 Z1 ; push nozzle into wiper\nG1 X-17 Y95 F1000 ; slow wipe\nG1 X-17 Y90 F1000 ; slow wipe\nG1 X-17 Y85 F1000 ; slow wipe\nG1 X-15 Y90 F1000 ; slow wipe\nG1 X-17 Y80 F1000 ; slow wipe\nG1 X-15 Y95 F1000 ; slow wipe\nG1 X-17 Y75 F2000 ; fast wipe\nG1 X-15 Y65 F2000 ; fast wipe\nG1 X-17 Y70 F2000 ; fast wipe\nG1 X-15 Y60 F2000 ; fast wipe\nG1 X-17 Y55 F2000 ; fast wipe\nG1 X-15 Y50 F2000 ; fast wipe\nG1 X-17 Y40 F2000 ; fast wipe\nG1 X-15 Y45 F2000 ; fast wipe\nG1 X-17 Y35 F2000 ; fast wipe\nG1 X-15 Y40 F2000 ; fast wipe\nG1 X-17 Y70 F2000 ; fast wipe\nG1 X-15 Y30 Z2 F2000 ; fast wipe\nG1 X-17 Y35 F2000 ; fast wipe\nG1 X-15 Y25 F2000 ; fast wipe\nG1 X-17 Y30 F2000 ; fast wipe\nG1 X-15 Y25 Z1.5 F1000 ; slow wipe\nG1 X-17 Y23 F1000 ; slow wipe\nG1 Z10 ; raise extruder\nM109 R{first_layer_temperature[0] - 60} ; wait for extruder to reach probe temp\nG1 X-9 Y-9 ; move above first probe point\nM204 S100 ; set probing acceleration\nG29 ; start auto-leveling sequence\nM420 S1 ; enable leveling matrix\nM425 Z ; use measured Z backlash for compensation\nM425 Z F0 ; turn off measured Z backlash compensation. (if activated in the quality settings, this command will automatically be ignored)\nM204 S500 ; restore standard acceleration\nG1 X0 Y0 Z15 F5000 ; move up off last probe point\nG4 S1 ; pause\nM400 ; wait for moves to finish\nM117 Heating... ; progress indicator message on LCD\nM109 R{first_layer_temperature[0]} ; wait for extruder to reach printing temp\nM190 R{first_layer_bed_temperature[0]} ; wait for bed to reach printing temp\nG1 Z2 E0 F75 ; prime tiny bit of filament into the nozzle\nM117 TAZ 6 Printing... ; progress indicator message on LCD\n
|
||||||
|
thumbnails =
|
||||||
|
toolchange_gcode =
|
||||||
|
use_firmware_retraction = 0
|
||||||
|
use_relative_e_distances = 0
|
||||||
|
use_volumetric_e = 0
|
||||||
|
variable_layer_height = 1
|
||||||
|
wipe = 1
|
||||||
|
z_offset = 0
|
|
@ -104,33 +104,7 @@ endif ()
|
||||||
# Add the Slic3r GUI library, libcurl, OpenGL and GLU libraries.
|
# Add the Slic3r GUI library, libcurl, OpenGL and GLU libraries.
|
||||||
if (SLIC3R_GUI)
|
if (SLIC3R_GUI)
|
||||||
# target_link_libraries(PrusaSlicer ws2_32 uxtheme setupapi libslic3r_gui ${wxWidgets_LIBRARIES})
|
# target_link_libraries(PrusaSlicer ws2_32 uxtheme setupapi libslic3r_gui ${wxWidgets_LIBRARIES})
|
||||||
target_link_libraries(PrusaSlicer libslic3r_gui ${wxWidgets_LIBRARIES})
|
target_link_libraries(PrusaSlicer libslic3r_gui)
|
||||||
|
|
||||||
# Configure libcurl and its dependencies OpenSSL & zlib
|
|
||||||
find_package(CURL REQUIRED)
|
|
||||||
if (NOT WIN32)
|
|
||||||
# Required by libcurl
|
|
||||||
find_package(ZLIB REQUIRED)
|
|
||||||
endif()
|
|
||||||
target_include_directories(PrusaSlicer PRIVATE ${CURL_INCLUDE_DIRS})
|
|
||||||
target_link_libraries(PrusaSlicer ${CURL_LIBRARIES} ${ZLIB_LIBRARIES})
|
|
||||||
if (SLIC3R_STATIC)
|
|
||||||
if (NOT APPLE)
|
|
||||||
# libcurl is always linked dynamically to the system libcurl on OSX.
|
|
||||||
# On other systems, libcurl is linked statically if SLIC3R_STATIC is set.
|
|
||||||
target_compile_definitions(PrusaSlicer PRIVATE CURL_STATICLIB)
|
|
||||||
endif()
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
||||||
# As of now, our build system produces a statically linked libcurl,
|
|
||||||
# which links the OpenSSL library dynamically.
|
|
||||||
find_package(OpenSSL REQUIRED)
|
|
||||||
message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}")
|
|
||||||
message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
|
|
||||||
target_include_directories(PrusaSlicer PRIVATE ${OPENSSL_INCLUDE_DIR})
|
|
||||||
target_link_libraries(PrusaSlicer ${OPENSSL_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# Generate debug symbols even in release mode.
|
# Generate debug symbols even in release mode.
|
||||||
target_link_options(PrusaSlicer PUBLIC "$<$<CONFIG:RELEASE>:/DEBUG>")
|
target_link_options(PrusaSlicer PUBLIC "$<$<CONFIG:RELEASE>:/DEBUG>")
|
||||||
|
|
|
@ -632,8 +632,11 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
|
||||||
// Negative support_contact_z is not taken into account, it can result in false positives in cases
|
// Negative support_contact_z is not taken into account, it can result in false positives in cases
|
||||||
// where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752)
|
// where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752)
|
||||||
|
|
||||||
|
// Only check this layer in case it has some extrusions.
|
||||||
|
bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
||||||
|
|| (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions());
|
||||||
|
|
||||||
if (layer_to_print.print_z() > maximal_print_z + 2. * EPSILON)
|
if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON)
|
||||||
throw std::runtime_error(_(L("Empty layers detected, the output would not be printable.")) + "\n\n" +
|
throw std::runtime_error(_(L("Empty layers detected, the output would not be printable.")) + "\n\n" +
|
||||||
_(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " +
|
_(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " +
|
||||||
std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is "
|
std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is "
|
||||||
|
|
|
@ -212,10 +212,8 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
||||||
if (m_print_config_ptr) { // in this case complete_objects is false (see ToolOrdering constructors)
|
if (m_print_config_ptr) { // in this case complete_objects is false (see ToolOrdering constructors)
|
||||||
something_nonoverriddable = false;
|
something_nonoverriddable = false;
|
||||||
for (const auto& eec : layerm->perimeters.entities) // let's check if there are nonoverriddable entities
|
for (const auto& eec : layerm->perimeters.entities) // let's check if there are nonoverriddable entities
|
||||||
if (!layer_tools.wiping_extrusions().is_overriddable_and_mark(dynamic_cast<const ExtrusionEntityCollection&>(*eec), *m_print_config_ptr, object, region)) {
|
if (!layer_tools.wiping_extrusions().is_overriddable_and_mark(dynamic_cast<const ExtrusionEntityCollection&>(*eec), *m_print_config_ptr, object, region))
|
||||||
something_nonoverriddable = true;
|
something_nonoverriddable = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (something_nonoverriddable)
|
if (something_nonoverriddable)
|
||||||
|
@ -237,7 +235,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
||||||
has_infill = true;
|
has_infill = true;
|
||||||
|
|
||||||
if (m_print_config_ptr) {
|
if (m_print_config_ptr) {
|
||||||
if (!something_nonoverriddable && !layer_tools.wiping_extrusions().is_overriddable_and_mark(*fill, *m_print_config_ptr, object, region))
|
if (! layer_tools.wiping_extrusions().is_overriddable_and_mark(*fill, *m_print_config_ptr, object, region))
|
||||||
something_nonoverriddable = true;
|
something_nonoverriddable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ PRODUCTVERSION @SLIC3R_RC_VERSION@
|
||||||
VALUE "ProductName", "@SLIC3R_APP_NAME@"
|
VALUE "ProductName", "@SLIC3R_APP_NAME@"
|
||||||
VALUE "ProductVersion", "@SLIC3R_BUILD_ID@"
|
VALUE "ProductVersion", "@SLIC3R_BUILD_ID@"
|
||||||
VALUE "InternalName", "@SLIC3R_APP_NAME@"
|
VALUE "InternalName", "@SLIC3R_APP_NAME@"
|
||||||
VALUE "LegalCopyright", "Copyright \251 2016-2019 Prusa Research, \251 2011-2018 Alessandro Ranelucci"
|
VALUE "LegalCopyright", "Copyright \251 2016-2020 Prusa Research, \251 2011-2018 Alessandro Ranelucci"
|
||||||
VALUE "OriginalFilename", "prusa-slicer.exe"
|
VALUE "OriginalFilename", "prusa-slicer.exe"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>@SLIC3R_APP_KEY@</string>
|
<string>@SLIC3R_APP_KEY@</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>@SLIC3R_APP_NAME@ Copyright (C) 2011-2019 Alessandro Ranellucci, (C) 2016-2019 Prusa Reseach</string>
|
<string>@SLIC3R_APP_NAME@ Copyright (C) 2011-2019 Alessandro Ranellucci, (C) 2016-2020 Prusa Reseach</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>PrusaSlicer.icns</string>
|
<string>PrusaSlicer.icns</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
|
|
|
@ -191,7 +191,7 @@ add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
||||||
|
|
||||||
encoding_check(libslic3r_gui)
|
encoding_check(libslic3r_gui)
|
||||||
|
|
||||||
target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi)
|
target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi libcurl ${wxWidgets_LIBRARIES})
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY})
|
target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY})
|
||||||
|
|
|
@ -266,7 +266,7 @@ AboutDialog::AboutDialog()
|
||||||
"<html>"
|
"<html>"
|
||||||
"<body bgcolor= %1% link= %2%>"
|
"<body bgcolor= %1% link= %2%>"
|
||||||
"<font color=%3%>"
|
"<font color=%3%>"
|
||||||
"%4% © 2016-2019 Prusa Research. <br />"
|
"%4% © 2016-2020 Prusa Research. <br />"
|
||||||
"%5% © 2011-2018 Alessandro Ranellucci. <br />"
|
"%5% © 2011-2018 Alessandro Ranellucci. <br />"
|
||||||
"<a href=\"http://slic3r.org/\">Slic3r</a> %6% "
|
"<a href=\"http://slic3r.org/\">Slic3r</a> %6% "
|
||||||
"<a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">%7%</a>."
|
"<a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">%7%</a>."
|
||||||
|
|
|
@ -101,8 +101,7 @@ void BackgroundSlicingProcess::process_fff()
|
||||||
//FIXME localize the messages
|
//FIXME localize the messages
|
||||||
// Perform the final post-processing of the export path by applying the print statistics over the file name.
|
// Perform the final post-processing of the export path by applying the print statistics over the file name.
|
||||||
std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path);
|
std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path);
|
||||||
GUI::RemovableDriveManager::get_instance().update();
|
bool with_check = GUI::wxGetApp().removable_drive_manager()->is_path_on_removable_drive(export_path);
|
||||||
bool with_check = GUI::RemovableDriveManager::get_instance().is_path_on_removable_drive(export_path);
|
|
||||||
int copy_ret_val = copy_file(m_temp_output_path, export_path, with_check);
|
int copy_ret_val = copy_file(m_temp_output_path, export_path, with_check);
|
||||||
switch (copy_ret_val) {
|
switch (copy_ret_val) {
|
||||||
case SUCCESS: break; // no error
|
case SUCCESS: break; // no error
|
||||||
|
@ -236,7 +235,7 @@ void BackgroundSlicingProcess::thread_proc()
|
||||||
// Only post the canceled event, if canceled by user.
|
// Only post the canceled event, if canceled by user.
|
||||||
// Don't post the canceled event, if canceled from Print::apply().
|
// Don't post the canceled event, if canceled from Print::apply().
|
||||||
wxCommandEvent evt(m_event_finished_id);
|
wxCommandEvent evt(m_event_finished_id);
|
||||||
evt.SetString(error);
|
evt.SetString(GUI::from_u8(error));
|
||||||
evt.SetInt(m_print->canceled() ? -1 : (error.empty() ? 1 : 0));
|
evt.SetInt(m_print->canceled() ? -1 : (error.empty() ? 1 : 0));
|
||||||
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
|
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ void Camera::debug_render() const
|
||||||
imgui.begin(std::string("Camera statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
imgui.begin(std::string("Camera statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
std::string type = get_type_as_string();
|
std::string type = get_type_as_string();
|
||||||
if (wxGetApp().plater()->get_mouse3d_controller().is_running() || (wxGetApp().app_config->get("use_free_camera") == "1"))
|
if (wxGetApp().plater()->get_mouse3d_controller().connected() || (wxGetApp().app_config->get("use_free_camera") == "1"))
|
||||||
type += "/free";
|
type += "/free";
|
||||||
else
|
else
|
||||||
type += "/constrained";
|
type += "/constrained";
|
||||||
|
@ -537,6 +537,7 @@ void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up
|
||||||
Vec3d unit_y = unit_z.cross(unit_x).normalized();
|
Vec3d unit_y = unit_z.cross(unit_x).normalized();
|
||||||
|
|
||||||
m_target = target;
|
m_target = target;
|
||||||
|
m_distance = (position - target).norm();
|
||||||
Vec3d new_position = m_target + m_distance * unit_z;
|
Vec3d new_position = m_target + m_distance * unit_z;
|
||||||
|
|
||||||
m_view_matrix(0, 0) = unit_x(0);
|
m_view_matrix(0, 0) = unit_x(0);
|
||||||
|
|
|
@ -122,6 +122,8 @@ public:
|
||||||
// returns true if the camera z axis (forward) is pointing in the negative direction of the world z axis
|
// returns true if the camera z axis (forward) is pointing in the negative direction of the world z axis
|
||||||
bool is_looking_downward() const { return get_dir_forward().dot(Vec3d::UnitZ()) < 0.0; }
|
bool is_looking_downward() const { return get_dir_forward().dot(Vec3d::UnitZ()) < 0.0; }
|
||||||
|
|
||||||
|
void look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up);
|
||||||
|
|
||||||
double max_zoom() const { return 100.0; }
|
double max_zoom() const { return 100.0; }
|
||||||
double min_zoom() const;
|
double min_zoom() const;
|
||||||
|
|
||||||
|
@ -137,7 +139,6 @@ private:
|
||||||
#endif // ENABLE_THUMBNAIL_GENERATOR
|
#endif // ENABLE_THUMBNAIL_GENERATOR
|
||||||
void set_distance(double distance) const;
|
void set_distance(double distance) const;
|
||||||
|
|
||||||
void look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up);
|
|
||||||
void set_default_orientation();
|
void set_default_orientation();
|
||||||
Vec3d validate_target(const Vec3d& target) const;
|
Vec3d validate_target(const Vec3d& target) const;
|
||||||
void update_zenit();
|
void update_zenit();
|
||||||
|
|
|
@ -42,16 +42,27 @@ using Config::SnapshotDB;
|
||||||
|
|
||||||
// Configuration data structures extensions needed for the wizard
|
// Configuration data structures extensions needed for the wizard
|
||||||
|
|
||||||
Bundle::Bundle(fs::path source_path, bool is_in_resources, bool is_prusa_bundle)
|
bool Bundle::load(fs::path source_path, bool ais_in_resources, bool ais_prusa_bundle)
|
||||||
: preset_bundle(new PresetBundle)
|
|
||||||
, vendor_profile(nullptr)
|
|
||||||
, is_in_resources(is_in_resources)
|
|
||||||
, is_prusa_bundle(is_prusa_bundle)
|
|
||||||
{
|
{
|
||||||
preset_bundle->load_configbundle(source_path.string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM);
|
this->preset_bundle = std::make_unique<PresetBundle>();
|
||||||
|
this->is_in_resources = ais_in_resources;
|
||||||
|
this->is_prusa_bundle = ais_prusa_bundle;
|
||||||
|
|
||||||
|
std::string path_string = source_path.string();
|
||||||
|
size_t presets_loaded = preset_bundle->load_configbundle(path_string, PresetBundle::LOAD_CFGBNDLE_SYSTEM);
|
||||||
auto first_vendor = preset_bundle->vendors.begin();
|
auto first_vendor = preset_bundle->vendors.begin();
|
||||||
wxCHECK_RET(first_vendor != preset_bundle->vendors.end(), "Failed to load preset bundle");
|
if (first_vendor == preset_bundle->vendors.end()) {
|
||||||
vendor_profile = &first_vendor->second;
|
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: No vendor information defined, cannot install.") % path_string;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (presets_loaded == 0) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: No profile loaded.") % path_string;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << boost::format("Vendor bundle: `%1%`: %2% profiles loaded.") % path_string % presets_loaded;
|
||||||
|
this->vendor_profile = &first_vendor->second;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bundle::Bundle(Bundle &&other)
|
Bundle::Bundle(Bundle &&other)
|
||||||
|
@ -76,8 +87,11 @@ BundleMap BundleMap::load()
|
||||||
prusa_bundle_path = (rsrc_vendor_dir / PresetBundle::PRUSA_BUNDLE).replace_extension(".ini");
|
prusa_bundle_path = (rsrc_vendor_dir / PresetBundle::PRUSA_BUNDLE).replace_extension(".ini");
|
||||||
prusa_bundle_rsrc = true;
|
prusa_bundle_rsrc = true;
|
||||||
}
|
}
|
||||||
Bundle prusa_bundle(std::move(prusa_bundle_path), prusa_bundle_rsrc, true);
|
{
|
||||||
|
Bundle prusa_bundle;
|
||||||
|
if (prusa_bundle.load(std::move(prusa_bundle_path), prusa_bundle_rsrc, true))
|
||||||
res.emplace(PresetBundle::PRUSA_BUNDLE, std::move(prusa_bundle));
|
res.emplace(PresetBundle::PRUSA_BUNDLE, std::move(prusa_bundle));
|
||||||
|
}
|
||||||
|
|
||||||
// Load the other bundles in the datadir/vendor directory
|
// Load the other bundles in the datadir/vendor directory
|
||||||
// and then additionally from resources/profiles.
|
// and then additionally from resources/profiles.
|
||||||
|
@ -90,7 +104,8 @@ BundleMap BundleMap::load()
|
||||||
// Don't load this bundle if we've already loaded it.
|
// Don't load this bundle if we've already loaded it.
|
||||||
if (res.find(id) != res.end()) { continue; }
|
if (res.find(id) != res.end()) { continue; }
|
||||||
|
|
||||||
Bundle bundle(dir_entry.path(), is_in_resources);
|
Bundle bundle;
|
||||||
|
if (bundle.load(dir_entry.path(), is_in_resources))
|
||||||
res.emplace(std::move(id), std::move(bundle));
|
res.emplace(std::move(id), std::move(bundle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,13 +100,16 @@ struct Materials
|
||||||
struct Bundle
|
struct Bundle
|
||||||
{
|
{
|
||||||
std::unique_ptr<PresetBundle> preset_bundle;
|
std::unique_ptr<PresetBundle> preset_bundle;
|
||||||
VendorProfile *vendor_profile;
|
VendorProfile *vendor_profile { nullptr };
|
||||||
const bool is_in_resources;
|
bool is_in_resources { false };
|
||||||
const bool is_prusa_bundle;
|
bool is_prusa_bundle { false };
|
||||||
|
|
||||||
Bundle(fs::path source_path, bool is_in_resources, bool is_prusa_bundle = false);
|
Bundle() = default;
|
||||||
Bundle(Bundle &&other);
|
Bundle(Bundle &&other);
|
||||||
|
|
||||||
|
// Returns false if not loaded. Reason for that is logged as boost::log error.
|
||||||
|
bool load(fs::path source_path, bool is_in_resources, bool is_prusa_bundle = false);
|
||||||
|
|
||||||
const std::string& vendor_id() const { return vendor_profile->id; }
|
const std::string& vendor_id() const { return vendor_profile->id; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,19 @@ template<class T, size_t N> struct ArrayEvent : public wxEvent
|
||||||
return new ArrayEvent<T, N>(GetEventType(), data, GetEventObject());
|
return new ArrayEvent<T, N>(GetEventType(), data, GetEventObject());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<class T> struct ArrayEvent<T, 1> : public wxEvent
|
|
||||||
|
template<class T> struct Event : public wxEvent
|
||||||
{
|
{
|
||||||
T data;
|
T data;
|
||||||
|
|
||||||
ArrayEvent(wxEventType type, T data, wxObject* origin = nullptr)
|
Event(wxEventType type, const T &data, wxObject* origin = nullptr)
|
||||||
|
: wxEvent(0, type), data(std::move(data))
|
||||||
|
{
|
||||||
|
m_propagationLevel = wxEVENT_PROPAGATE_MAX;
|
||||||
|
SetEventObject(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
Event(wxEventType type, T&& data, wxObject* origin = nullptr)
|
||||||
: wxEvent(0, type), data(std::move(data))
|
: wxEvent(0, type), data(std::move(data))
|
||||||
{
|
{
|
||||||
m_propagationLevel = wxEVENT_PROPAGATE_MAX;
|
m_propagationLevel = wxEVENT_PROPAGATE_MAX;
|
||||||
|
@ -53,13 +61,10 @@ template<class T> struct ArrayEvent<T, 1> : public wxEvent
|
||||||
|
|
||||||
virtual wxEvent* Clone() const
|
virtual wxEvent* Clone() const
|
||||||
{
|
{
|
||||||
return new ArrayEvent<T, 1>(GetEventType(), data, GetEventObject());
|
return new Event<T>(GetEventType(), data, GetEventObject());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> using Event = ArrayEvent<T, 1>;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4088,12 +4088,6 @@ void GLCanvas3D::handle_layers_data_focus_event(const t_layer_height_range range
|
||||||
|
|
||||||
void GLCanvas3D::update_ui_from_settings()
|
void GLCanvas3D::update_ui_from_settings()
|
||||||
{
|
{
|
||||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
|
||||||
Camera& camera = wxGetApp().plater()->get_camera();
|
|
||||||
camera.set_type(wxGetApp().app_config->get("use_perspective_camera"));
|
|
||||||
#else
|
|
||||||
m_camera.set_type(wxGetApp().app_config->get("use_perspective_camera"));
|
|
||||||
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
|
||||||
#if ENABLE_RETINA_GL
|
#if ENABLE_RETINA_GL
|
||||||
|
|
|
@ -155,6 +155,7 @@ GUI_App::GUI_App()
|
||||||
, m_em_unit(10)
|
, m_em_unit(10)
|
||||||
, m_imgui(new ImGuiWrapper())
|
, m_imgui(new ImGuiWrapper())
|
||||||
, m_wizard(nullptr)
|
, m_wizard(nullptr)
|
||||||
|
, m_removable_drive_manager(std::make_unique<RemovableDriveManager>())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GUI_App::~GUI_App()
|
GUI_App::~GUI_App()
|
||||||
|
@ -279,7 +280,6 @@ bool GUI_App::on_init_inner()
|
||||||
|
|
||||||
m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
|
m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
|
||||||
|
|
||||||
RemovableDriveManager::get_instance().init();
|
|
||||||
|
|
||||||
Bind(wxEVT_IDLE, [this](wxIdleEvent& event)
|
Bind(wxEVT_IDLE, [this](wxIdleEvent& event)
|
||||||
{
|
{
|
||||||
|
@ -291,10 +291,6 @@ bool GUI_App::on_init_inner()
|
||||||
|
|
||||||
this->obj_manipul()->update_if_dirty();
|
this->obj_manipul()->update_if_dirty();
|
||||||
|
|
||||||
#if !__APPLE__
|
|
||||||
RemovableDriveManager::get_instance().update(wxGetLocalTime(), true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Preset updating & Configwizard are done after the above initializations,
|
// Preset updating & Configwizard are done after the above initializations,
|
||||||
// and after MainFrame is created & shown.
|
// and after MainFrame is created & shown.
|
||||||
// The extra CallAfter() is needed because of Mac, where this is the only way
|
// The extra CallAfter() is needed because of Mac, where this is the only way
|
||||||
|
@ -454,46 +450,30 @@ float GUI_App::toolbar_icon_scale(const bool is_limited/* = false*/) const
|
||||||
|
|
||||||
void GUI_App::recreate_GUI()
|
void GUI_App::recreate_GUI()
|
||||||
{
|
{
|
||||||
// Weird things happen as the Paint messages are floating around the windows being destructed.
|
mainframe->shutdown();
|
||||||
// Avoid the Paint messages by hiding the main window.
|
|
||||||
// Also the application closes much faster without these unnecessary screen refreshes.
|
|
||||||
// In addition, there were some crashes due to the Paint events sent to already destructed windows.
|
|
||||||
mainframe->Show(false);
|
|
||||||
|
|
||||||
const auto msg_name = _(L("Changing of an application language")) + dots;
|
const auto msg_name = _(L("Changing of an application language")) + dots;
|
||||||
wxProgressDialog dlg(msg_name, msg_name);
|
wxProgressDialog dlg(msg_name, msg_name);
|
||||||
dlg.Pulse();
|
dlg.Pulse();
|
||||||
|
|
||||||
// to make sure nobody accesses data from the soon-to-be-destroyed widgets:
|
|
||||||
tabs_list.clear();
|
|
||||||
plater_ = nullptr;
|
|
||||||
|
|
||||||
dlg.Update(10, _(L("Recreating")) + dots);
|
dlg.Update(10, _(L("Recreating")) + dots);
|
||||||
|
|
||||||
MainFrame* topwindow = mainframe;
|
MainFrame *old_main_frame = mainframe;
|
||||||
mainframe = new MainFrame();
|
mainframe = new MainFrame();
|
||||||
sidebar().obj_list()->init_objects(); // propagate model objects to object list
|
// Propagate model objects to object list.
|
||||||
|
sidebar().obj_list()->init_objects();
|
||||||
if (topwindow) {
|
|
||||||
SetTopWindow(mainframe);
|
SetTopWindow(mainframe);
|
||||||
|
|
||||||
dlg.Update(30, _(L("Recreating")) + dots);
|
dlg.Update(30, _(L("Recreating")) + dots);
|
||||||
topwindow->Destroy();
|
old_main_frame->Destroy();
|
||||||
|
// For this moment ConfigWizard is deleted, invalidate it.
|
||||||
// For this moment ConfigWizard is deleted, invalidate it
|
|
||||||
m_wizard = nullptr;
|
m_wizard = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
dlg.Update(80, _(L("Loading of current presets")) + dots);
|
dlg.Update(80, _(L("Loading of current presets")) + dots);
|
||||||
|
|
||||||
m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
|
m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
|
||||||
|
|
||||||
load_current_presets();
|
load_current_presets();
|
||||||
|
|
||||||
mainframe->Show(true);
|
mainframe->Show(true);
|
||||||
|
|
||||||
dlg.Update(90, _(L("Loading of a mode view")) + dots);
|
dlg.Update(90, _(L("Loading of a mode view")) + dots);
|
||||||
|
|
||||||
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
|
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
|
||||||
* change min hight of object list to the normal min value (15 * wxGetApp().em_unit())
|
* change min hight of object list to the normal min value (15 * wxGetApp().em_unit())
|
||||||
* after first whole Mainframe updating/layouting
|
* after first whole Mainframe updating/layouting
|
||||||
|
@ -501,7 +481,6 @@ void GUI_App::recreate_GUI()
|
||||||
const int list_min_height = 15 * em_unit();
|
const int list_min_height = 15 * em_unit();
|
||||||
if (obj_list()->GetMinSize().GetY() > list_min_height)
|
if (obj_list()->GetMinSize().GetY() > list_min_height)
|
||||||
obj_list()->SetMinSize(wxSize(-1, list_min_height));
|
obj_list()->SetMinSize(wxSize(-1, list_min_height));
|
||||||
|
|
||||||
update_mode();
|
update_mode();
|
||||||
|
|
||||||
// #ys_FIXME_delete_after_testing Do we still need this ?
|
// #ys_FIXME_delete_after_testing Do we still need this ?
|
||||||
|
@ -596,9 +575,6 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const
|
||||||
bool GUI_App::switch_language()
|
bool GUI_App::switch_language()
|
||||||
{
|
{
|
||||||
if (select_language()) {
|
if (select_language()) {
|
||||||
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
|
||||||
_3DScene::remove_all_canvases();
|
|
||||||
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
|
||||||
recreate_GUI();
|
recreate_GUI();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -32,9 +32,9 @@ class PresetUpdater;
|
||||||
class ModelObject;
|
class ModelObject;
|
||||||
class PrintHostJobQueue;
|
class PrintHostJobQueue;
|
||||||
|
|
||||||
namespace GUI
|
|
||||||
{
|
|
||||||
|
|
||||||
|
namespace GUI{
|
||||||
|
class RemovableDriveManager;
|
||||||
enum FileType
|
enum FileType
|
||||||
{
|
{
|
||||||
FT_STL,
|
FT_STL,
|
||||||
|
@ -102,6 +102,9 @@ class GUI_App : public wxApp
|
||||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
GLCanvas3DManager m_canvas_mgr;
|
GLCanvas3DManager m_canvas_mgr;
|
||||||
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
|
std::unique_ptr<RemovableDriveManager> m_removable_drive_manager;
|
||||||
|
|
||||||
std::unique_ptr<ImGuiWrapper> m_imgui;
|
std::unique_ptr<ImGuiWrapper> m_imgui;
|
||||||
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
||||||
ConfigWizard* m_wizard; // Managed by wxWindow tree
|
ConfigWizard* m_wizard; // Managed by wxWindow tree
|
||||||
|
@ -192,6 +195,8 @@ public:
|
||||||
|
|
||||||
std::vector<Tab *> tabs_list;
|
std::vector<Tab *> tabs_list;
|
||||||
|
|
||||||
|
RemovableDriveManager* removable_drive_manager() { return m_removable_drive_manager.get(); }
|
||||||
|
|
||||||
ImGuiWrapper* imgui() { return m_imgui.get(); }
|
ImGuiWrapper* imgui() { return m_imgui.get(); }
|
||||||
|
|
||||||
PrintHostJobQueue& printhost_job_queue() { return *m_printhost_job_queue.get(); }
|
PrintHostJobQueue& printhost_job_queue() { return *m_printhost_job_queue.get(); }
|
||||||
|
|
|
@ -122,6 +122,8 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||||
{ ctrl + "G", L("Export G-code") },
|
{ ctrl + "G", L("Export G-code") },
|
||||||
{ ctrl + "Shift+" + "G", L("Send G-code") },
|
{ ctrl + "Shift+" + "G", L("Send G-code") },
|
||||||
{ ctrl + "E", L("Export config") },
|
{ ctrl + "E", L("Export config") },
|
||||||
|
{ ctrl + "U", L("Export to SD card / Flash drive") },
|
||||||
|
{ ctrl + "T", L("Eject SD card / Flash drive") },
|
||||||
// Edit
|
// Edit
|
||||||
{ ctrl + "A", L("Select all objects") },
|
{ ctrl + "A", L("Select all objects") },
|
||||||
{ "Esc", L("Deselect all") },
|
{ "Esc", L("Deselect all") },
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "wxExtensions.hpp"
|
#include "wxExtensions.hpp"
|
||||||
#include "GUI_ObjectList.hpp"
|
#include "GUI_ObjectList.hpp"
|
||||||
#include "Mouse3DController.hpp"
|
#include "Mouse3DController.hpp"
|
||||||
|
#include "RemovableDriveManager.hpp"
|
||||||
#include "I18N.hpp"
|
#include "I18N.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -108,7 +109,28 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
||||||
event.Veto();
|
event.Veto();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this->shutdown();
|
||||||
|
// propagate event
|
||||||
|
event.Skip();
|
||||||
|
});
|
||||||
|
|
||||||
|
Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& event) {
|
||||||
|
if (m_plater != nullptr && event.GetActive())
|
||||||
|
m_plater->on_activate();
|
||||||
|
event.Skip();
|
||||||
|
});
|
||||||
|
|
||||||
|
wxGetApp().persist_window_geometry(this, true);
|
||||||
|
|
||||||
|
update_ui_from_settings(); // FIXME (?)
|
||||||
|
|
||||||
|
if (m_plater != nullptr)
|
||||||
|
m_plater->show_action_buttons(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when closing the application and when switching the application language.
|
||||||
|
void MainFrame::shutdown()
|
||||||
|
{
|
||||||
if (m_plater)
|
if (m_plater)
|
||||||
m_plater->stop_jobs();
|
m_plater->stop_jobs();
|
||||||
|
|
||||||
|
@ -131,6 +153,9 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
||||||
// Store the device parameter database back to appconfig.
|
// Store the device parameter database back to appconfig.
|
||||||
m_plater->get_mouse3d_controller().save_config(*wxGetApp().app_config);
|
m_plater->get_mouse3d_controller().save_config(*wxGetApp().app_config);
|
||||||
|
|
||||||
|
// Stop the background thread of the removable drive manager, so that no new updates will be sent to the Plater.
|
||||||
|
wxGetApp().removable_drive_manager()->shutdown();
|
||||||
|
|
||||||
// Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
|
// Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
|
||||||
// but in rare cases it may not have been called yet.
|
// but in rare cases it may not have been called yet.
|
||||||
wxGetApp().app_config->save();
|
wxGetApp().app_config->save();
|
||||||
|
@ -145,23 +170,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
||||||
// to avoid any manipulations with them from App->wxEVT_IDLE after of the mainframe closing
|
// to avoid any manipulations with them from App->wxEVT_IDLE after of the mainframe closing
|
||||||
wxGetApp().tabs_list.clear();
|
wxGetApp().tabs_list.clear();
|
||||||
wxGetApp().plater_ = nullptr;
|
wxGetApp().plater_ = nullptr;
|
||||||
|
|
||||||
// propagate event
|
|
||||||
event.Skip();
|
|
||||||
});
|
|
||||||
|
|
||||||
Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& event) {
|
|
||||||
if (m_plater != nullptr && event.GetActive())
|
|
||||||
m_plater->on_activate();
|
|
||||||
event.Skip();
|
|
||||||
});
|
|
||||||
|
|
||||||
wxGetApp().persist_window_geometry(this, true);
|
|
||||||
|
|
||||||
update_ui_from_settings(); // FIXME (?)
|
|
||||||
|
|
||||||
if (m_plater != nullptr)
|
|
||||||
m_plater->show_action_buttons(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainFrame::update_title()
|
void MainFrame::update_title()
|
||||||
|
@ -332,6 +340,27 @@ bool MainFrame::can_send_gcode() const
|
||||||
return print_host_opt != nullptr && !print_host_opt->value.empty();
|
return print_host_opt != nullptr && !print_host_opt->value.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MainFrame::can_export_gcode_sd() const
|
||||||
|
{
|
||||||
|
if (m_plater == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_plater->model().objects.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_plater->is_export_gcode_scheduled())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO:: add other filters
|
||||||
|
|
||||||
|
return wxGetApp().removable_drive_manager()->status().has_removable_drives;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainFrame::can_eject() const
|
||||||
|
{
|
||||||
|
return wxGetApp().removable_drive_manager()->status().has_eject;
|
||||||
|
}
|
||||||
|
|
||||||
bool MainFrame::can_slice() const
|
bool MainFrame::can_slice() const
|
||||||
{
|
{
|
||||||
bool bg_proc = wxGetApp().app_config->get("background_processing") == "1";
|
bool bg_proc = wxGetApp().app_config->get("background_processing") == "1";
|
||||||
|
@ -502,6 +531,9 @@ void MainFrame::init_menubar()
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->send_gcode(); }, "export_gcode", nullptr,
|
[this](wxCommandEvent&) { if (m_plater) m_plater->send_gcode(); }, "export_gcode", nullptr,
|
||||||
[this](){return can_send_gcode(); }, this);
|
[this](){return can_send_gcode(); }, this);
|
||||||
m_changeable_menu_items.push_back(item_send_gcode);
|
m_changeable_menu_items.push_back(item_send_gcode);
|
||||||
|
append_menu_item(export_menu, wxID_ANY, _(L("Export G-code to SD card / Flash drive")) + dots + "\tCtrl+U", _(L("Export current plate as G-code to SD card / Flash drive")),
|
||||||
|
[this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(true); }, "export_to_sd", nullptr,
|
||||||
|
[this]() {return can_export_gcode_sd(); }, this);
|
||||||
export_menu->AppendSeparator();
|
export_menu->AppendSeparator();
|
||||||
append_menu_item(export_menu, wxID_ANY, _(L("Export plate as &STL")) + dots, _(L("Export current plate as STL")),
|
append_menu_item(export_menu, wxID_ANY, _(L("Export plate as &STL")) + dots, _(L("Export current plate as STL")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "export_plater", nullptr,
|
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "export_plater", nullptr,
|
||||||
|
@ -525,6 +557,10 @@ void MainFrame::init_menubar()
|
||||||
[this]() {return true; }, this);
|
[this]() {return true; }, this);
|
||||||
append_submenu(fileMenu, export_menu, wxID_ANY, _(L("&Export")), "");
|
append_submenu(fileMenu, export_menu, wxID_ANY, _(L("&Export")), "");
|
||||||
|
|
||||||
|
append_menu_item(fileMenu, wxID_ANY, _(L("Ejec&t SD card / Flash drive")) + dots + "\tCtrl+T", _(L("Eject SD card / Flash drive after the G-code was exported to it.")),
|
||||||
|
[this](wxCommandEvent&) { if (m_plater) m_plater->eject_drive(); }, "eject_sd", nullptr,
|
||||||
|
[this]() {return can_eject(); }, this);
|
||||||
|
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -70,6 +70,8 @@ class MainFrame : public DPIFrame
|
||||||
bool can_export_supports() const;
|
bool can_export_supports() const;
|
||||||
bool can_export_gcode() const;
|
bool can_export_gcode() const;
|
||||||
bool can_send_gcode() const;
|
bool can_send_gcode() const;
|
||||||
|
bool can_export_gcode_sd() const;
|
||||||
|
bool can_eject() const;
|
||||||
bool can_slice() const;
|
bool can_slice() const;
|
||||||
bool can_change_view() const;
|
bool can_change_view() const;
|
||||||
bool can_select() const;
|
bool can_select() const;
|
||||||
|
@ -98,6 +100,9 @@ public:
|
||||||
MainFrame();
|
MainFrame();
|
||||||
~MainFrame() = default;
|
~MainFrame() = default;
|
||||||
|
|
||||||
|
// Called when closing the application and when switching the application language.
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
Plater* plater() { return m_plater; }
|
Plater* plater() { return m_plater; }
|
||||||
|
|
||||||
void update_title();
|
void update_title();
|
||||||
|
|
|
@ -368,6 +368,8 @@ void Mouse3DController::render_settings_dialog(GLCanvas3D& canvas) const
|
||||||
|
|
||||||
void Mouse3DController::connected(std::string device_name)
|
void Mouse3DController::connected(std::string device_name)
|
||||||
{
|
{
|
||||||
|
assert(! m_connected);
|
||||||
|
assert(m_device_str.empty());
|
||||||
m_device_str = device_name;
|
m_device_str = device_name;
|
||||||
// Copy the parameters for m_device_str into the current parameters.
|
// Copy the parameters for m_device_str into the current parameters.
|
||||||
if (auto it_params = m_params_by_device.find(m_device_str); it_params != m_params_by_device.end()) {
|
if (auto it_params = m_params_by_device.find(m_device_str); it_params != m_params_by_device.end()) {
|
||||||
|
@ -380,14 +382,14 @@ void Mouse3DController::connected(std::string device_name)
|
||||||
void Mouse3DController::disconnected()
|
void Mouse3DController::disconnected()
|
||||||
{
|
{
|
||||||
// Copy the current parameters for m_device_str into the parameter database.
|
// Copy the current parameters for m_device_str into the parameter database.
|
||||||
assert(! m_device_str.empty());
|
assert(m_connected == ! m_device_str.empty());
|
||||||
if (! m_device_str.empty()) {
|
if (m_connected) {
|
||||||
tbb::mutex::scoped_lock lock(m_params_ui_mutex);
|
tbb::mutex::scoped_lock lock(m_params_ui_mutex);
|
||||||
m_params_by_device[m_device_str] = m_params_ui;
|
m_params_by_device[m_device_str] = m_params_ui;
|
||||||
}
|
|
||||||
m_device_str.clear();
|
m_device_str.clear();
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Mouse3DController::handle_input(const DataPacketAxis& packet)
|
bool Mouse3DController::handle_input(const DataPacketAxis& packet)
|
||||||
{
|
{
|
||||||
|
@ -451,12 +453,13 @@ void Mouse3DController::shutdown()
|
||||||
// Stop the worker thread, if running.
|
// Stop the worker thread, if running.
|
||||||
{
|
{
|
||||||
// Notify the worker thread to cancel wait on detection polling.
|
// Notify the worker thread to cancel wait on detection polling.
|
||||||
std::unique_lock<std::mutex> lock(m_stop_condition_mutex);
|
std::lock_guard<std::mutex> lock(m_stop_condition_mutex);
|
||||||
m_stop = true;
|
m_stop = true;
|
||||||
m_stop_condition.notify_all();
|
|
||||||
}
|
}
|
||||||
|
m_stop_condition.notify_all();
|
||||||
// Wait for the worker thread to stop.
|
// Wait for the worker thread to stop.
|
||||||
m_thread.join();
|
m_thread.join();
|
||||||
|
m_stop = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
#include <tbb/mutex.h>
|
#include <tbb/mutex.h>
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@ class Mouse3DController
|
||||||
std::map<std::string, Params> m_params_by_device;
|
std::map<std::string, Params> m_params_by_device;
|
||||||
|
|
||||||
mutable State m_state;
|
mutable State m_state;
|
||||||
std::atomic<bool> m_connected;
|
std::atomic<bool> m_connected { false };
|
||||||
std::string m_device_str;
|
std::string m_device_str;
|
||||||
|
|
||||||
#if ! __APPLE__
|
#if ! __APPLE__
|
||||||
|
|
|
@ -152,6 +152,8 @@ static void DeviceAdded(uint32_t unused)
|
||||||
static void DeviceRemoved(uint32_t unused)
|
static void DeviceRemoved(uint32_t unused)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << "3dx device removed\n";
|
BOOST_LOG_TRIVIAL(info) << "3dx device removed\n";
|
||||||
|
assert(m_connected);
|
||||||
|
assert(! m_device_str.empty());
|
||||||
mouse_3d_controller->disconnected();
|
mouse_3d_controller->disconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +216,8 @@ void Mouse3DController::shutdown()
|
||||||
CleanupConnexionHandlers();
|
CleanupConnexionHandlers();
|
||||||
unload_driver();
|
unload_driver();
|
||||||
}
|
}
|
||||||
|
// Copy the current parameters to parameter database, mark the device as disconnected.
|
||||||
|
this->disconnected();
|
||||||
mouse_3d_controller = nullptr;
|
mouse_3d_controller = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg)
|
||||||
html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), -1));
|
html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), -1));
|
||||||
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||||
wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||||
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK); // wxSYS_COLOUR_WINDOW
|
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||||
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
|
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
|
||||||
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
|
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
|
||||||
const int font_size = font.GetPointSize()-1;
|
const int font_size = font.GetPointSize()-1;
|
||||||
|
|
|
@ -113,7 +113,11 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = nullptr*/) {
|
void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = nullptr*/) {
|
||||||
if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width) {
|
if ( line.full_width && (
|
||||||
|
line.sizer != nullptr ||
|
||||||
|
line.widget != nullptr ||
|
||||||
|
!line.get_extra_widgets().empty() )
|
||||||
|
) {
|
||||||
if (line.sizer != nullptr) {
|
if (line.sizer != nullptr) {
|
||||||
sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
||||||
return;
|
return;
|
||||||
|
@ -122,6 +126,17 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
|
||||||
sizer->Add(line.widget(this->ctrl_parent()), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
sizer->Add(line.widget(this->ctrl_parent()), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!line.get_extra_widgets().empty()) {
|
||||||
|
const auto h_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
sizer->Add(h_sizer, 1, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
||||||
|
|
||||||
|
bool is_first_item = true;
|
||||||
|
for (auto extra_widget : line.get_extra_widgets()) {
|
||||||
|
h_sizer->Add(extra_widget(this->ctrl_parent()), is_first_item ? 1 : 0, wxLEFT, 15);
|
||||||
|
is_first_item = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto option_set = line.get_options();
|
auto option_set = line.get_options();
|
||||||
|
@ -412,7 +427,9 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
|
||||||
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
|
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
|
||||||
value = int(nozzle_diameter->values.size());
|
value = int(nozzle_diameter->values.size());
|
||||||
}
|
}
|
||||||
else if (m_opt_map.find(opt_key) == m_opt_map.end() || opt_key == "bed_shape") {
|
else if (m_opt_map.find(opt_key) == m_opt_map.end() ||
|
||||||
|
// This option don't have corresponded field
|
||||||
|
opt_key == "bed_shape" || opt_key == "compatible_printers" || opt_key == "compatible_prints" ) {
|
||||||
value = get_config_value(config, opt_key);
|
value = get_config_value(config, opt_key);
|
||||||
change_opt_value(*m_config, opt_key, value);
|
change_opt_value(*m_config, opt_key, value);
|
||||||
return;
|
return;
|
||||||
|
@ -629,7 +646,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||||
ret = static_cast<wxString>(config.opt_string(opt_key));
|
ret = static_cast<wxString>(config.opt_string(opt_key));
|
||||||
break;
|
break;
|
||||||
case coStrings:
|
case coStrings:
|
||||||
if (opt_key.compare("compatible_printers") == 0) {
|
if (opt_key == "compatible_printers" || opt_key == "compatible_prints") {
|
||||||
ret = config.option<ConfigOptionStrings>(opt_key)->values;
|
ret = config.option<ConfigOptionStrings>(opt_key)->values;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,15 +301,20 @@ PresetBitmapComboBox(parent, wxSize(15 * wxGetApp().em_unit(), -1)),
|
||||||
if (preset_type == Slic3r::Preset::TYPE_FILAMENT)
|
if (preset_type == Slic3r::Preset::TYPE_FILAMENT)
|
||||||
{
|
{
|
||||||
Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &event) {
|
Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &event) {
|
||||||
int shifl_Left = 0;
|
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||||
|
const Preset* selected_preset = preset_bundle->filaments.find_preset(preset_bundle->filament_presets[extruder_idx]);
|
||||||
|
// Wide icons are shown if the currently selected preset is not compatible with the current printer,
|
||||||
|
// and red flag is drown in front of the selected preset.
|
||||||
|
bool wide_icons = selected_preset != nullptr && !selected_preset->is_compatible;
|
||||||
float scale = m_em_unit*0.1f;
|
float scale = m_em_unit*0.1f;
|
||||||
|
|
||||||
|
int shifl_Left = wide_icons ? int(scale * 16 + 0.5) : 0;
|
||||||
#if defined(wxBITMAPCOMBOBOX_OWNERDRAWN_BASED)
|
#if defined(wxBITMAPCOMBOBOX_OWNERDRAWN_BASED)
|
||||||
shifl_Left = int(scale * 4 + 0.5f); // IMAGE_SPACING_RIGHT = 4 for wxBitmapComboBox -> Space left of image
|
shifl_Left += int(scale * 4 + 0.5f); // IMAGE_SPACING_RIGHT = 4 for wxBitmapComboBox -> Space left of image
|
||||||
#endif
|
#endif
|
||||||
int icon_right_pos = int(scale * (24+4) + 0.5);
|
int icon_right_pos = shifl_Left + int(scale * (24+4) + 0.5);
|
||||||
int mouse_pos = event.GetLogicalPosition(wxClientDC(this)).x;
|
int mouse_pos = event.GetLogicalPosition(wxClientDC(this)).x;
|
||||||
// if (extruder_idx < 0 || event.GetLogicalPosition(wxClientDC(this)).x > 24) {
|
if (mouse_pos < shifl_Left || mouse_pos > icon_right_pos ) {
|
||||||
if ( extruder_idx < 0 || mouse_pos < shifl_Left || mouse_pos > icon_right_pos ) {
|
|
||||||
// Let the combo box process the mouse click.
|
// Let the combo box process the mouse click.
|
||||||
event.Skip();
|
event.Skip();
|
||||||
return;
|
return;
|
||||||
|
@ -338,7 +343,7 @@ PresetBitmapComboBox(parent, wxSize(15 * wxGetApp().em_unit(), -1)),
|
||||||
cfg_new.set_key_value("extruder_colour", colors);
|
cfg_new.set_key_value("extruder_colour", colors);
|
||||||
|
|
||||||
wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg_new);
|
wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg_new);
|
||||||
wxGetApp().preset_bundle->update_plater_filament_ui(extruder_idx, this);
|
preset_bundle->update_plater_filament_ui(extruder_idx, this);
|
||||||
wxGetApp().plater()->on_config_change(cfg_new);
|
wxGetApp().plater()->on_config_change(cfg_new);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -881,8 +886,8 @@ Sidebar::Sidebar(Plater *parent)
|
||||||
};
|
};
|
||||||
|
|
||||||
init_scalable_btn(&p->btn_send_gcode , "export_gcode", _(L("Send to printer")) + "\tCtrl+Shift+G");
|
init_scalable_btn(&p->btn_send_gcode , "export_gcode", _(L("Send to printer")) + "\tCtrl+Shift+G");
|
||||||
init_scalable_btn(&p->btn_remove_device, "eject_sd" , _(L("Remove device")));
|
init_scalable_btn(&p->btn_remove_device, "eject_sd" , _(L("Remove device")) + "\tCtrl+T");
|
||||||
init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _(L("Export to SD card / Flash drive")));
|
init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _(L("Export to SD card / Flash drive")) + "\tCtrl+U");
|
||||||
|
|
||||||
// regular buttons "Slice now" and "Export G-code"
|
// regular buttons "Slice now" and "Export G-code"
|
||||||
|
|
||||||
|
@ -1509,6 +1514,7 @@ struct Plater::priv
|
||||||
ret.poly.contour = std::move(p);
|
ret.poly.contour = std::move(p);
|
||||||
ret.translation = scaled(m_pos);
|
ret.translation = scaled(m_pos);
|
||||||
ret.rotation = m_rotation;
|
ret.rotation = m_rotation;
|
||||||
|
ret.priority++;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} wipetower;
|
} wipetower;
|
||||||
|
@ -1572,18 +1578,23 @@ struct Plater::priv
|
||||||
// the current bed width.
|
// the current bed width.
|
||||||
static const constexpr double LOGICAL_BED_GAP = 1. / 5.;
|
static const constexpr double LOGICAL_BED_GAP = 1. / 5.;
|
||||||
|
|
||||||
ArrangePolygons m_selected, m_unselected;
|
ArrangePolygons m_selected, m_unselected, m_unprintable;
|
||||||
|
|
||||||
// clear m_selected and m_unselected, reserve space for next usage
|
// clear m_selected and m_unselected, reserve space for next usage
|
||||||
void clear_input() {
|
void clear_input() {
|
||||||
const Model &model = plater().model;
|
const Model &model = plater().model;
|
||||||
|
|
||||||
size_t count = 0; // To know how much space to reserve
|
size_t count = 0, cunprint = 0; // To know how much space to reserve
|
||||||
for (auto obj : model.objects) count += obj->instances.size();
|
for (auto obj : model.objects)
|
||||||
|
for (auto mi : obj->instances)
|
||||||
|
mi->printable ? count++ : cunprint++;
|
||||||
|
|
||||||
m_selected.clear();
|
m_selected.clear();
|
||||||
m_unselected.clear();
|
m_unselected.clear();
|
||||||
|
m_unprintable.clear();
|
||||||
m_selected.reserve(count + 1 /* for optional wti */);
|
m_selected.reserve(count + 1 /* for optional wti */);
|
||||||
m_unselected.reserve(count + 1 /* for optional wti */);
|
m_unselected.reserve(count + 1 /* for optional wti */);
|
||||||
|
m_unprintable.reserve(cunprint /* for optional wti */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stride between logical beds
|
// Stride between logical beds
|
||||||
|
@ -1612,8 +1623,10 @@ struct Plater::priv
|
||||||
clear_input();
|
clear_input();
|
||||||
|
|
||||||
for (ModelObject *obj: plater().model.objects)
|
for (ModelObject *obj: plater().model.objects)
|
||||||
for (ModelInstance *mi : obj->instances)
|
for (ModelInstance *mi : obj->instances) {
|
||||||
m_selected.emplace_back(get_arrange_poly(mi));
|
ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable;
|
||||||
|
cont.emplace_back(get_arrange_poly(mi));
|
||||||
|
}
|
||||||
|
|
||||||
auto& wti = plater().updated_wipe_tower();
|
auto& wti = plater().updated_wipe_tower();
|
||||||
if (wti) m_selected.emplace_back(get_arrange_poly(&wti));
|
if (wti) m_selected.emplace_back(get_arrange_poly(&wti));
|
||||||
|
@ -1648,9 +1661,12 @@ struct Plater::priv
|
||||||
for (size_t i = 0; i < inst_sel.size(); ++i) {
|
for (size_t i = 0; i < inst_sel.size(); ++i) {
|
||||||
ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]);
|
ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]);
|
||||||
|
|
||||||
inst_sel[i] ?
|
ArrangePolygons &cont = mo->instances[i]->printable ?
|
||||||
m_selected.emplace_back(std::move(ap)) :
|
(inst_sel[i] ? m_selected :
|
||||||
m_unselected.emplace_back(std::move(ap));
|
m_unselected) :
|
||||||
|
m_unprintable;
|
||||||
|
|
||||||
|
cont.emplace_back(std::move(ap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1682,7 +1698,10 @@ struct Plater::priv
|
||||||
public:
|
public:
|
||||||
using PlaterJob::PlaterJob;
|
using PlaterJob::PlaterJob;
|
||||||
|
|
||||||
int status_range() const override { return int(m_selected.size()); }
|
int status_range() const override
|
||||||
|
{
|
||||||
|
return int(m_selected.size() + m_unprintable.size());
|
||||||
|
}
|
||||||
|
|
||||||
void process() override;
|
void process() override;
|
||||||
|
|
||||||
|
@ -1690,8 +1709,24 @@ struct Plater::priv
|
||||||
// Ignore the arrange result if aborted.
|
// Ignore the arrange result if aborted.
|
||||||
if (was_canceled()) return;
|
if (was_canceled()) return;
|
||||||
|
|
||||||
|
// Unprintable items go to the last virtual bed
|
||||||
|
int beds = 0;
|
||||||
|
|
||||||
// Apply the arrange result to all selected objects
|
// Apply the arrange result to all selected objects
|
||||||
for (ArrangePolygon &ap : m_selected) ap.apply();
|
for (ArrangePolygon &ap : m_selected) {
|
||||||
|
beds = std::max(ap.bed_idx, beds);
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the virtual beds from the unselected items
|
||||||
|
for (ArrangePolygon &ap : m_unselected)
|
||||||
|
beds = std::max(ap.bed_idx, beds);
|
||||||
|
|
||||||
|
// Move the unprintable items to the last virtual bed.
|
||||||
|
for (ArrangePolygon &ap : m_unprintable) {
|
||||||
|
ap.bed_idx += beds + 1;
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
plater().update();
|
plater().update();
|
||||||
}
|
}
|
||||||
|
@ -1961,6 +1996,11 @@ struct Plater::priv
|
||||||
wxString get_project_filename(const wxString& extension = wxEmptyString) const;
|
wxString get_project_filename(const wxString& extension = wxEmptyString) const;
|
||||||
void set_project_filename(const wxString& filename);
|
void set_project_filename(const wxString& filename);
|
||||||
|
|
||||||
|
// Caching last value of show_action_buttons parameter for show_action_buttons(), so that a callback which does not know this state will not override it.
|
||||||
|
mutable bool ready_to_slice = { false };
|
||||||
|
// Flag indicating that the G-code export targets a removable device, therefore the show_action_buttons() needs to be called at any case when the background processing finishes.
|
||||||
|
bool writing_to_removable_device = { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool init_object_menu();
|
bool init_object_menu();
|
||||||
bool init_common_menu(wxMenu* menu, const bool is_part = false);
|
bool init_common_menu(wxMenu* menu, const bool is_part = false);
|
||||||
|
@ -2171,11 +2211,17 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||||
// Connect to a 3DConnextion driver (OSX).
|
// Connect to a 3DConnextion driver (OSX).
|
||||||
mouse3d_controller.init();
|
mouse3d_controller.init();
|
||||||
|
|
||||||
|
this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this](RemovableDriveEjectEvent &evt) {
|
||||||
|
this->show_action_buttons(this->ready_to_slice);
|
||||||
|
Slic3r::GUI::show_info(this->q, (boost::format(_utf8(L("Unmounting successful. The device %s(%s) can now be safely removed from the computer.")))
|
||||||
|
% evt.data.name % evt.data.path).str());
|
||||||
|
});
|
||||||
|
this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this](RemovableDrivesChangedEvent &) { this->show_action_buttons(this->ready_to_slice); });
|
||||||
|
// Start the background thread and register this window as a target for update events.
|
||||||
|
wxGetApp().removable_drive_manager()->init(this->q);
|
||||||
|
|
||||||
// Initialize the Undo / Redo stack with a first snapshot.
|
// Initialize the Undo / Redo stack with a first snapshot.
|
||||||
this->take_snapshot(_(L("New Project")));
|
this->take_snapshot(_(L("New Project")));
|
||||||
|
|
||||||
//void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
|
||||||
RemovableDriveManager::get_instance().set_drive_count_changed_callback(std::bind(&Plater::priv::show_action_buttons, this, std::placeholders::_1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Plater::priv::~priv()
|
Plater::priv::~priv()
|
||||||
|
@ -2249,6 +2295,14 @@ void Plater::priv::update_ui_from_settings()
|
||||||
// $self->{buttons_sizer}->Layout;
|
// $self->{buttons_sizer}->Layout;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
camera.set_type(wxGetApp().app_config->get("use_perspective_camera"));
|
||||||
|
if (wxGetApp().app_config->get("use_free_camera") != "1")
|
||||||
|
{
|
||||||
|
// forces camera right vector to be parallel to XY plane
|
||||||
|
if (std::abs(camera.get_dir_right()(2)) > EPSILON)
|
||||||
|
camera.look_at(camera.get_position(), camera.get_target(), Vec3d::UnitZ());
|
||||||
|
}
|
||||||
|
|
||||||
view3D->get_canvas3d()->update_ui_from_settings();
|
view3D->get_canvas3d()->update_ui_from_settings();
|
||||||
preview->get_canvas3d()->update_ui_from_settings();
|
preview->get_canvas3d()->update_ui_from_settings();
|
||||||
}
|
}
|
||||||
|
@ -2842,16 +2896,21 @@ void Plater::priv::ArrangeJob::process() {
|
||||||
}
|
}
|
||||||
|
|
||||||
coord_t min_d = scaled(dist);
|
coord_t min_d = scaled(dist);
|
||||||
auto count = unsigned(m_selected.size());
|
auto count = unsigned(m_selected.size() + m_unprintable.size());
|
||||||
arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint();
|
arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint();
|
||||||
|
|
||||||
|
auto stopfn = [this]() { return was_canceled(); };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arrangement::arrange(m_selected, m_unselected, min_d, bedshape,
|
arrangement::arrange(m_selected, m_unselected, min_d, bedshape,
|
||||||
[this, count](unsigned st) {
|
[this, count](unsigned st) {
|
||||||
if (st > 0) // will not finalize after last one
|
st += m_unprintable.size();
|
||||||
update_status(int(count - st), arrangestr);
|
if (st > 0) update_status(int(count - st), arrangestr);
|
||||||
},
|
}, stopfn);
|
||||||
[this]() { return was_canceled(); });
|
arrangement::arrange(m_unprintable, {}, min_d, bedshape,
|
||||||
|
[this, count](unsigned st) {
|
||||||
|
if (st > 0) update_status(int(count - st), arrangestr);
|
||||||
|
}, stopfn);
|
||||||
} catch (std::exception & /*e*/) {
|
} catch (std::exception & /*e*/) {
|
||||||
GUI::show_error(plater().q,
|
GUI::show_error(plater().q,
|
||||||
_(L("Could not arrange model objects! "
|
_(L("Could not arrange model objects! "
|
||||||
|
@ -3717,14 +3776,9 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
|
||||||
sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now");
|
sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now");
|
||||||
show_action_buttons(true);
|
show_action_buttons(true);
|
||||||
}
|
}
|
||||||
else if (wxGetApp().get_mode() == comSimple)
|
else if (this->writing_to_removable_device || wxGetApp().get_mode() == comSimple)
|
||||||
show_action_buttons(false);
|
show_action_buttons(false);
|
||||||
|
this->writing_to_removable_device = false;
|
||||||
if(!canceled && RemovableDriveManager::get_instance().get_is_writing())
|
|
||||||
{
|
|
||||||
RemovableDriveManager::get_instance().set_is_writing(false);
|
|
||||||
show_action_buttons(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::priv::on_layer_editing_toggled(bool enable)
|
void Plater::priv::on_layer_editing_toggled(bool enable)
|
||||||
|
@ -4295,32 +4349,36 @@ void Plater::priv::update_object_menu()
|
||||||
sidebar->obj_list()->append_menu_items_add_volume(&object_menu);
|
sidebar->obj_list()->append_menu_items_add_volume(&object_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
void Plater::priv::show_action_buttons(const bool ready_to_slice) const
|
||||||
{
|
{
|
||||||
RemovableDriveManager::get_instance().set_plater_ready_to_slice(is_ready_to_slice);
|
// Cache this value, so that the callbacks from the RemovableDriveManager may repeat that value when calling show_action_buttons().
|
||||||
|
this->ready_to_slice = ready_to_slice;
|
||||||
|
|
||||||
wxWindowUpdateLocker noUpdater(sidebar);
|
wxWindowUpdateLocker noUpdater(sidebar);
|
||||||
const auto prin_host_opt = config->option<ConfigOptionString>("print_host");
|
const auto prin_host_opt = config->option<ConfigOptionString>("print_host");
|
||||||
const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty();
|
const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty();
|
||||||
|
|
||||||
bool disconnect_shown = !RemovableDriveManager::get_instance().is_last_drive_removed();
|
|
||||||
bool export_removable_shown = RemovableDriveManager::get_instance().get_drives_count() > 0;
|
|
||||||
// when a background processing is ON, export_btn and/or send_btn are showing
|
// when a background processing is ON, export_btn and/or send_btn are showing
|
||||||
if (wxGetApp().app_config->get("background_processing") == "1")
|
if (wxGetApp().app_config->get("background_processing") == "1")
|
||||||
{
|
{
|
||||||
|
RemovableDriveManager::RemovableDrivesStatus removable_media_status = wxGetApp().removable_drive_manager()->status();
|
||||||
if (sidebar->show_reslice(false) |
|
if (sidebar->show_reslice(false) |
|
||||||
sidebar->show_export(true) |
|
sidebar->show_export(true) |
|
||||||
sidebar->show_send(send_gcode_shown) |
|
sidebar->show_send(send_gcode_shown) |
|
||||||
sidebar->show_export_removable(export_removable_shown) |
|
sidebar->show_export_removable(removable_media_status.has_removable_drives) |
|
||||||
sidebar->show_disconnect(disconnect_shown))
|
sidebar->show_disconnect(removable_media_status.has_eject))
|
||||||
sidebar->Layout();
|
sidebar->Layout();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sidebar->show_reslice(is_ready_to_slice) |
|
RemovableDriveManager::RemovableDrivesStatus removable_media_status;
|
||||||
sidebar->show_export(!is_ready_to_slice) |
|
if (! ready_to_slice)
|
||||||
sidebar->show_send(send_gcode_shown && !is_ready_to_slice) |
|
removable_media_status = wxGetApp().removable_drive_manager()->status();
|
||||||
sidebar->show_export_removable(export_removable_shown && !is_ready_to_slice) |
|
if (sidebar->show_reslice(ready_to_slice) |
|
||||||
sidebar->show_disconnect(disconnect_shown && !is_ready_to_slice))
|
sidebar->show_export(!ready_to_slice) |
|
||||||
|
sidebar->show_send(send_gcode_shown && !ready_to_slice) |
|
||||||
|
sidebar->show_export_removable(!ready_to_slice && removable_media_status.has_removable_drives) |
|
||||||
|
sidebar->show_disconnect(!ready_to_slice && removable_media_status.has_eject))
|
||||||
sidebar->Layout();
|
sidebar->Layout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4854,51 +4912,38 @@ void Plater::export_gcode(bool prefer_removable)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
|
default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
|
||||||
auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string());
|
AppConfig &appconfig = *wxGetApp().app_config;
|
||||||
bool removable_drives_connected = GUI::RemovableDriveManager::get_instance().update();
|
RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager();
|
||||||
if(prefer_removable)
|
// Get a last save path, either to removable media or to an internal media.
|
||||||
{
|
std::string start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), prefer_removable);
|
||||||
if(removable_drives_connected)
|
if (prefer_removable) {
|
||||||
{
|
// Returns a path to a removable media if it exists, prefering start_dir. Update the internal removable drives database.
|
||||||
auto start_dir_removable = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string(), true);
|
start_dir = removable_drive_manager.get_removable_drive_path(start_dir);
|
||||||
if (RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir_removable))
|
if (start_dir.empty())
|
||||||
{
|
// Direct user to the last internal media.
|
||||||
start_dir = start_dir_removable;
|
start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), false);
|
||||||
}else
|
|
||||||
{
|
|
||||||
start_dir = RemovableDriveManager::get_instance().get_drive_path();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs::path output_path;
|
||||||
|
{
|
||||||
wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")),
|
wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")),
|
||||||
start_dir,
|
start_dir,
|
||||||
from_path(default_output_file.filename()),
|
from_path(default_output_file.filename()),
|
||||||
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_PNGZIP, default_output_file.extension().string()),
|
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_PNGZIP, default_output_file.extension().string()),
|
||||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
||||||
);
|
);
|
||||||
|
if (dlg.ShowModal() == wxID_OK)
|
||||||
fs::path output_path;
|
output_path = into_path(dlg.GetPath());
|
||||||
if (dlg.ShowModal() == wxID_OK) {
|
|
||||||
fs::path path = into_path(dlg.GetPath());
|
|
||||||
wxGetApp().app_config->update_last_output_dir(path.parent_path().string(), RemovableDriveManager::get_instance().is_path_on_removable_drive(path.parent_path().string()));
|
|
||||||
output_path = std::move(path);
|
|
||||||
}
|
|
||||||
if (! output_path.empty())
|
|
||||||
{
|
|
||||||
std::string path = output_path.string();
|
|
||||||
p->export_gcode(std::move(output_path), PrintHostJob());
|
|
||||||
|
|
||||||
RemovableDriveManager::get_instance().update(0, false);
|
|
||||||
RemovableDriveManager::get_instance().set_last_save_path(path);
|
|
||||||
RemovableDriveManager::get_instance().verify_last_save_path();
|
|
||||||
|
|
||||||
if(!RemovableDriveManager::get_instance().is_last_drive_removed())
|
|
||||||
{
|
|
||||||
RemovableDriveManager::get_instance().set_is_writing(true);
|
|
||||||
RemovableDriveManager::get_instance().erase_callbacks();
|
|
||||||
RemovableDriveManager::get_instance().add_remove_callback(std::bind(&Plater::drive_ejected_callback, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! output_path.empty()) {
|
||||||
|
p->export_gcode(output_path, PrintHostJob());
|
||||||
|
bool path_on_removable_media = removable_drive_manager.set_and_verify_last_save_path(output_path.string());
|
||||||
|
// Storing a path to AppConfig either as path to removable media or a path to internal media.
|
||||||
|
// is_path_on_removable_drive() is called with the "true" parameter to update its internal database as the user may have shuffled the external drives
|
||||||
|
// while the dialog was open.
|
||||||
|
appconfig.update_last_output_dir(output_path.parent_path().string(), path_on_removable_media);
|
||||||
|
p->writing_to_removable_device = path_on_removable_media;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5220,28 +5265,11 @@ void Plater::send_gcode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called when the Eject button is pressed.
|
||||||
void Plater::eject_drive()
|
void Plater::eject_drive()
|
||||||
{
|
{
|
||||||
RemovableDriveManager::get_instance().update(0, true);
|
wxGetApp().removable_drive_manager()->eject_drive();
|
||||||
RemovableDriveManager::get_instance().erase_callbacks();
|
|
||||||
RemovableDriveManager::get_instance().add_remove_callback(std::bind(&Plater::drive_ejected_callback, this));
|
|
||||||
RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void Plater::drive_ejected_callback()
|
|
||||||
{
|
|
||||||
if (RemovableDriveManager::get_instance().get_did_eject())
|
|
||||||
{
|
|
||||||
RemovableDriveManager::get_instance().set_did_eject(false);
|
|
||||||
show_info(this,
|
|
||||||
(boost::format(_utf8(L("Unmounting successful. The device %s(%s) can now be safely removed from the computer.")))
|
|
||||||
% RemovableDriveManager::get_instance().get_ejected_name()
|
|
||||||
% RemovableDriveManager::get_instance().get_ejected_path()).str());
|
|
||||||
}
|
|
||||||
p->show_action_buttons(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); }
|
void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); }
|
||||||
void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); }
|
void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); }
|
||||||
|
@ -5631,7 +5659,7 @@ void Plater::suppress_background_process(const bool stop_background_process)
|
||||||
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
|
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
|
||||||
|
|
||||||
void Plater::update_object_menu() { p->update_object_menu(); }
|
void Plater::update_object_menu() { p->update_object_menu(); }
|
||||||
void Plater::show_action_buttons(const bool is_ready_to_slice) const { p->show_action_buttons(is_ready_to_slice); }
|
void Plater::show_action_buttons(const bool ready_to_slice) const { p->show_action_buttons(ready_to_slice); }
|
||||||
|
|
||||||
void Plater::copy_selection_to_clipboard()
|
void Plater::copy_selection_to_clipboard()
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,7 +213,6 @@ public:
|
||||||
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
|
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
|
||||||
void send_gcode();
|
void send_gcode();
|
||||||
void eject_drive();
|
void eject_drive();
|
||||||
void drive_ejected_callback();
|
|
||||||
|
|
||||||
void take_snapshot(const std::string &snapshot_name);
|
void take_snapshot(const std::string &snapshot_name);
|
||||||
void take_snapshot(const wxString &snapshot_name);
|
void take_snapshot(const wxString &snapshot_name);
|
||||||
|
|
|
@ -851,7 +851,7 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string
|
||||||
return preset;
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresetCollection::save_current_preset(const std::string &new_name)
|
void PresetCollection::save_current_preset(const std::string &new_name, bool detach)
|
||||||
{
|
{
|
||||||
// 1) Find the preset with a new_name or create a new one,
|
// 1) Find the preset with a new_name or create a new one,
|
||||||
// initialize it with the edited config.
|
// initialize it with the edited config.
|
||||||
|
@ -866,6 +866,13 @@ void PresetCollection::save_current_preset(const std::string &new_name)
|
||||||
preset.config = std::move(m_edited_preset.config);
|
preset.config = std::move(m_edited_preset.config);
|
||||||
// The newly saved preset will be activated -> make it visible.
|
// The newly saved preset will be activated -> make it visible.
|
||||||
preset.is_visible = true;
|
preset.is_visible = true;
|
||||||
|
if (detach) {
|
||||||
|
// Clear the link to the parent profile.
|
||||||
|
preset.vendor = nullptr;
|
||||||
|
preset.inherits().clear();
|
||||||
|
preset.alias.clear();
|
||||||
|
preset.renamed_from.clear();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Creating a new preset.
|
// Creating a new preset.
|
||||||
Preset &preset = *m_presets.insert(it, m_edited_preset);
|
Preset &preset = *m_presets.insert(it, m_edited_preset);
|
||||||
|
@ -874,7 +881,12 @@ void PresetCollection::save_current_preset(const std::string &new_name)
|
||||||
preset.name = new_name;
|
preset.name = new_name;
|
||||||
preset.file = this->path_from_name(new_name);
|
preset.file = this->path_from_name(new_name);
|
||||||
preset.vendor = nullptr;
|
preset.vendor = nullptr;
|
||||||
if (preset.is_system) {
|
preset.alias.clear();
|
||||||
|
preset.renamed_from.clear();
|
||||||
|
if (detach) {
|
||||||
|
// Clear the link to the parent profile.
|
||||||
|
inherits.clear();
|
||||||
|
} else if (preset.is_system) {
|
||||||
// Inheriting from a system preset.
|
// Inheriting from a system preset.
|
||||||
inherits = /* preset.vendor->name + "/" + */ old_name;
|
inherits = /* preset.vendor->name + "/" + */ old_name;
|
||||||
} else if (inherits.empty()) {
|
} else if (inherits.empty()) {
|
||||||
|
@ -1061,6 +1073,7 @@ size_t PresetCollection::update_compatible_internal(const PresetWithVendorProfil
|
||||||
const ConfigOption *opt = active_printer.preset.config.option("nozzle_diameter");
|
const ConfigOption *opt = active_printer.preset.config.option("nozzle_diameter");
|
||||||
if (opt)
|
if (opt)
|
||||||
config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast<const ConfigOptionFloats*>(opt)->values.size()));
|
config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast<const ConfigOptionFloats*>(opt)->values.size()));
|
||||||
|
bool some_compatible = false;
|
||||||
for (size_t idx_preset = m_num_default_presets; idx_preset < m_presets.size(); ++ idx_preset) {
|
for (size_t idx_preset = m_num_default_presets; idx_preset < m_presets.size(); ++ idx_preset) {
|
||||||
bool selected = idx_preset == m_idx_selected;
|
bool selected = idx_preset == m_idx_selected;
|
||||||
Preset &preset_selected = m_presets[idx_preset];
|
Preset &preset_selected = m_presets[idx_preset];
|
||||||
|
@ -1068,6 +1081,7 @@ size_t PresetCollection::update_compatible_internal(const PresetWithVendorProfil
|
||||||
const PresetWithVendorProfile this_preset_with_vendor_profile = this->get_preset_with_vendor_profile(preset_edited);
|
const PresetWithVendorProfile this_preset_with_vendor_profile = this->get_preset_with_vendor_profile(preset_edited);
|
||||||
bool was_compatible = preset_edited.is_compatible;
|
bool was_compatible = preset_edited.is_compatible;
|
||||||
preset_edited.is_compatible = is_compatible_with_printer(this_preset_with_vendor_profile, active_printer, &config);
|
preset_edited.is_compatible = is_compatible_with_printer(this_preset_with_vendor_profile, active_printer, &config);
|
||||||
|
some_compatible |= preset_edited.is_compatible;
|
||||||
if (active_print != nullptr)
|
if (active_print != nullptr)
|
||||||
preset_edited.is_compatible &= is_compatible_with_print(this_preset_with_vendor_profile, *active_print, active_printer);
|
preset_edited.is_compatible &= is_compatible_with_print(this_preset_with_vendor_profile, *active_print, active_printer);
|
||||||
if (! preset_edited.is_compatible && selected &&
|
if (! preset_edited.is_compatible && selected &&
|
||||||
|
@ -1076,6 +1090,10 @@ size_t PresetCollection::update_compatible_internal(const PresetWithVendorProfil
|
||||||
if (selected)
|
if (selected)
|
||||||
preset_selected.is_compatible = preset_edited.is_compatible;
|
preset_selected.is_compatible = preset_edited.is_compatible;
|
||||||
}
|
}
|
||||||
|
// Update visibility of the default profiles here if the defaults are suppressed, the current profile is not compatible and we don't want to select another compatible profile.
|
||||||
|
if (m_idx_selected >= m_num_default_presets && m_default_suppressed)
|
||||||
|
for (size_t i = 0; i < m_num_default_presets; ++ i)
|
||||||
|
m_presets[i].is_visible = ! some_compatible;
|
||||||
return m_idx_selected;
|
return m_idx_selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,7 +312,7 @@ public:
|
||||||
// Save the preset under a new name. If the name is different from the old one,
|
// Save the preset under a new name. If the name is different from the old one,
|
||||||
// a new preset is stored into the list of presets.
|
// a new preset is stored into the list of presets.
|
||||||
// All presets are marked as not modified and the new preset is activated.
|
// All presets are marked as not modified and the new preset is activated.
|
||||||
void save_current_preset(const std::string &new_name);
|
void save_current_preset(const std::string &new_name, bool detach = false);
|
||||||
|
|
||||||
// Delete the current preset, activate the first visible preset.
|
// Delete the current preset, activate the first visible preset.
|
||||||
// returns true if the preset was deleted successfully.
|
// returns true if the preset was deleted successfully.
|
||||||
|
|
|
@ -703,7 +703,10 @@ void PresetBundle::load_config_file(const std::string &path)
|
||||||
boost::nowide::ifstream ifs(path);
|
boost::nowide::ifstream ifs(path);
|
||||||
boost::property_tree::read_ini(ifs, tree);
|
boost::property_tree::read_ini(ifs, tree);
|
||||||
} catch (const std::ifstream::failure &err) {
|
} catch (const std::ifstream::failure &err) {
|
||||||
throw std::runtime_error(std::string("The config file cannot be loaded: ") + path + "\n\tReason: " + err.what());
|
throw std::runtime_error(std::string("The Config Bundle cannot be loaded: ") + path + "\n\tReason: " + err.what());
|
||||||
|
} catch (const boost::property_tree::file_parser_error &err) {
|
||||||
|
throw std::runtime_error((boost::format("Failed loading the Config Bundle \"%1%\": %2% at line %3%")
|
||||||
|
% err.filename() % err.message() % err.line()).str());
|
||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
throw std::runtime_error(std::string("Failed loading the preset file: ") + path + "\n\tReason: " + err.what());
|
throw std::runtime_error(std::string("Failed loading the preset file: ") + path + "\n\tReason: " + err.what());
|
||||||
}
|
}
|
||||||
|
@ -1109,8 +1112,13 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
||||||
const VendorProfile *vendor_profile = nullptr;
|
const VendorProfile *vendor_profile = nullptr;
|
||||||
if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) {
|
if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) {
|
||||||
auto vp = VendorProfile::from_ini(tree, path);
|
auto vp = VendorProfile::from_ini(tree, path);
|
||||||
if (vp.num_variants() == 0)
|
if (vp.models.size() == 0) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: No printer model defined.") % path;
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (vp.num_variants() == 0) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: No printer variant defined") % path;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
vendor_profile = &this->vendors.insert({vp.id, vp}).first->second;
|
vendor_profile = &this->vendors.insert({vp.id, vp}).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1599,21 +1607,23 @@ void PresetBundle::update_plater_filament_ui(unsigned int idx_extruder, GUI::Pre
|
||||||
|
|
||||||
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so
|
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so
|
||||||
// set a bitmap height to m_bitmapLock->GetHeight()
|
// set a bitmap height to m_bitmapLock->GetHeight()
|
||||||
// Note, under OSX we should use a ScaledHeight because of Retina scale
|
//
|
||||||
|
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size.
|
||||||
|
// But for some display scaling (for example 125% or 175%) normal_icon_width differs from icon width.
|
||||||
|
// So:
|
||||||
|
// for nonsystem presets set a width of empty bitmap to m_bitmapLock->GetWidth()
|
||||||
|
// for compatible presets set a width of empty bitmap to m_bitmapIncompatible->GetWidth()
|
||||||
|
//
|
||||||
|
// Note, under OSX we should use a Scaled Height/Width because of Retina scale
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
const int icon_height = m_bitmapLock->GetScaledHeight();
|
const int icon_height = m_bitmapLock->GetScaledHeight();
|
||||||
|
const int lock_icon_width = m_bitmapLock->GetScaledWidth();
|
||||||
|
const int flag_icon_width = m_bitmapIncompatible->GetScaledWidth();
|
||||||
#else
|
#else
|
||||||
const int icon_height = m_bitmapLock->GetHeight();
|
const int icon_height = m_bitmapLock->GetHeight();
|
||||||
#endif
|
|
||||||
|
|
||||||
/* To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size.
|
|
||||||
* But for some display scaling (for example 125% or 175%) normal_icon_width differs from icon width.
|
|
||||||
* So:
|
|
||||||
* for nonsystem presets set a width of empty bitmap to m_bitmapLock->GetWidth()
|
|
||||||
* for compatible presets set a width of empty bitmap to m_bitmapIncompatible->GetWidth()
|
|
||||||
**/
|
|
||||||
const int lock_icon_width = m_bitmapLock->GetWidth();
|
const int lock_icon_width = m_bitmapLock->GetWidth();
|
||||||
const int flag_icon_width = m_bitmapIncompatible->GetWidth();
|
const int flag_icon_width = m_bitmapIncompatible->GetWidth();
|
||||||
|
#endif
|
||||||
|
|
||||||
wxString tooltip = "";
|
wxString tooltip = "";
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "RemovableDriveManager.hpp"
|
#include "RemovableDriveManager.hpp"
|
||||||
#include <iostream>
|
#include <libslic3r/libslic3r.h>
|
||||||
#include "boost/nowide/convert.hpp"
|
|
||||||
|
#include <boost/nowide/convert.hpp>
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -9,11 +11,9 @@
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
|
||||||
#include <Dbt.h>
|
#include <Dbt.h>
|
||||||
GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72,
|
|
||||||
0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//linux includes
|
// unix, linux & OSX includes
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -26,124 +26,173 @@ GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72,
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
wxDEFINE_EVENT(EVT_REMOVABLE_DRIVE_EJECTED, RemovableDriveEjectEvent);
|
||||||
|
wxDEFINE_EVENT(EVT_REMOVABLE_DRIVES_CHANGED, RemovableDrivesChangedEvent);
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
/* currently not used, left for possible future use
|
std::vector<DriveData> RemovableDriveManager::search_for_removable_drives() const
|
||||||
INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
||||||
*/
|
|
||||||
void RemovableDriveManager::search_for_drives()
|
|
||||||
{
|
{
|
||||||
m_current_drives.clear();
|
|
||||||
//get logical drives flags by letter in alphabetical order
|
//get logical drives flags by letter in alphabetical order
|
||||||
DWORD drives_mask = GetLogicalDrives();
|
DWORD drives_mask = ::GetLogicalDrives();
|
||||||
for (size_t i = 0; i < 26; i++)
|
|
||||||
{
|
// Allocate the buffers before the loop.
|
||||||
if(drives_mask & (1 << i))
|
std::wstring volume_name;
|
||||||
{
|
std::wstring file_system_name;
|
||||||
std::string path (1,(char)('A' + i));
|
// Iterate the Windows drives from 'A' to 'Z'
|
||||||
path+=":";
|
std::vector<DriveData> current_drives;
|
||||||
UINT drive_type = GetDriveTypeA(path.c_str());
|
for (size_t i = 0; i < 26; ++ i)
|
||||||
|
if (drives_mask & (1 << i)) {
|
||||||
|
std::string path { char('A' + i), ':' };
|
||||||
|
UINT drive_type = ::GetDriveTypeA(path.c_str());
|
||||||
// DRIVE_REMOVABLE on W are sd cards and usb thumbnails (not usb harddrives)
|
// DRIVE_REMOVABLE on W are sd cards and usb thumbnails (not usb harddrives)
|
||||||
if (drive_type == DRIVE_REMOVABLE)
|
if (drive_type == DRIVE_REMOVABLE) {
|
||||||
{
|
|
||||||
// get name of drive
|
// get name of drive
|
||||||
std::wstring wpath = boost::nowide::widen(path);
|
std::wstring wpath = boost::nowide::widen(path);
|
||||||
std::wstring volume_name;
|
volume_name.resize(MAX_PATH + 1);
|
||||||
volume_name.resize(1024);
|
file_system_name.resize(MAX_PATH + 1);
|
||||||
std::wstring file_system_name;
|
BOOL error = ::GetVolumeInformationW(wpath.c_str(), volume_name.data(), sizeof(volume_name), nullptr, nullptr, nullptr, file_system_name.data(), sizeof(file_system_name));
|
||||||
file_system_name.resize(1024);
|
if (error != 0) {
|
||||||
LPWSTR lp_volume_name_buffer = new wchar_t;
|
volume_name.erase(volume_name.begin() + wcslen(volume_name.c_str()), volume_name.end());
|
||||||
BOOL error = GetVolumeInformationW(wpath.c_str(), &volume_name[0], sizeof(volume_name), NULL, NULL, NULL, &file_system_name[0], sizeof(file_system_name));
|
if (! file_system_name.empty()) {
|
||||||
if(error != 0)
|
|
||||||
{
|
|
||||||
volume_name.erase(std::find(volume_name.begin(), volume_name.end(), '\0'), volume_name.end());
|
|
||||||
if (file_system_name != L"")
|
|
||||||
{
|
|
||||||
ULARGE_INTEGER free_space;
|
ULARGE_INTEGER free_space;
|
||||||
GetDiskFreeSpaceExA(path.c_str(), &free_space, NULL, NULL);
|
::GetDiskFreeSpaceExA(path.c_str(), &free_space, nullptr, nullptr);
|
||||||
if (free_space.QuadPart > 0)
|
if (free_space.QuadPart > 0) {
|
||||||
{
|
|
||||||
path += "\\";
|
path += "\\";
|
||||||
m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path));
|
current_drives.emplace_back(DriveData{ boost::nowide::narrow(volume_name), path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return current_drives;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
void RemovableDriveManager::eject_drive(const std::string &path)
|
// Called from UI therefore it blocks the UI thread.
|
||||||
|
// It also blocks updates at the worker thread.
|
||||||
|
// Win32 implementation.
|
||||||
|
void RemovableDriveManager::eject_drive()
|
||||||
{
|
{
|
||||||
if(m_current_drives.empty())
|
if (m_last_save_path.empty())
|
||||||
return;
|
return;
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
|
||||||
{
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
if ((*it).path == path)
|
this->update();
|
||||||
{
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
|
auto it_drive_data = this->find_last_save_path_drive_data();
|
||||||
|
if (it_drive_data != m_current_drives.end()) {
|
||||||
// get handle to device
|
// get handle to device
|
||||||
std::string mpath = "\\\\.\\" + path;
|
std::string mpath = "\\\\.\\" + m_last_save_path;
|
||||||
mpath = mpath.substr(0, mpath.size() - 1);
|
mpath = mpath.substr(0, mpath.size() - 1);
|
||||||
HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
|
HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
{
|
|
||||||
std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n";
|
std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DWORD deviceControlRetVal(0);
|
DWORD deviceControlRetVal(0);
|
||||||
//these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger.
|
//these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger.
|
||||||
//sd cards does trigger WM_DEVICECHANGE messege, usb drives dont
|
//sd cards does trigger WM_DEVICECHANGE messege, usb drives dont
|
||||||
|
|
||||||
DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
||||||
DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
||||||
// some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here but it returns error to me
|
// some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here but it returns error to me
|
||||||
BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
||||||
if (error == 0)
|
if (error == 0) {
|
||||||
{
|
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n";
|
BOOST_LOG_TRIVIAL(error) << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
m_did_eject = true;
|
assert(m_callback_evt_handler);
|
||||||
m_current_drives.erase(it);
|
if (m_callback_evt_handler)
|
||||||
m_ejected_path = m_last_save_path;
|
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::move(*it_drive_data)));
|
||||||
m_ejected_name = m_last_save_name;
|
m_current_drives.erase(it_drive_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RemovableDriveManager::get_removable_drive_path(const std::string &path)
|
||||||
|
{
|
||||||
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
this->update();
|
||||||
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
|
if (m_current_drives.empty())
|
||||||
|
return std::string();
|
||||||
|
std::size_t found = path.find_last_of("\\");
|
||||||
|
std::string new_path = path.substr(0, found);
|
||||||
|
int letter = PathGetDriveNumberA(new_path.c_str());
|
||||||
|
for (const DriveData &drive_data : m_current_drives) {
|
||||||
|
char drive = drive_data.path[0];
|
||||||
|
if (drive == 'A' + letter)
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
return m_current_drives.front().path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RemovableDriveManager::get_removable_drive_from_path(const std::string& path)
|
||||||
|
{
|
||||||
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
|
std::size_t found = path.find_last_of("\\");
|
||||||
|
std::string new_path = path.substr(0, found);
|
||||||
|
int letter = PathGetDriveNumberA(new_path.c_str());
|
||||||
|
for (const DriveData &drive_data : m_current_drives) {
|
||||||
|
assert(! drive_data.path.empty());
|
||||||
|
if (drive_data.path.front() == 'A' + letter)
|
||||||
|
return drive_data.path;
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// currently not used, left for possible future use
|
||||||
|
INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
// here we need to catch messeges about device removal
|
||||||
|
// problem is that when ejecting usb (how is it implemented above) there is no messege dispached. Only after physical removal of the device.
|
||||||
|
//uncomment register_window() in init() to register and comment update() in GUI_App.cpp (only for windows!) to stop recieving periodical updates
|
||||||
|
|
||||||
|
LRESULT lRet = 1;
|
||||||
|
static HDEVNOTIFY hDeviceNotify;
|
||||||
|
static constexpr GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_CREATE:
|
||||||
|
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
|
||||||
|
|
||||||
|
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
|
||||||
|
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
||||||
|
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||||
|
NotificationFilter.dbcc_classguid = WceusbshGUID;
|
||||||
|
|
||||||
|
hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_DEVICECHANGE:
|
||||||
|
{
|
||||||
|
// here is the important
|
||||||
|
if(wParam == DBT_DEVICEREMOVECOMPLETE)
|
||||||
|
{
|
||||||
|
RemovableDriveManager::get_instance().update(0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Send all other messages on to the default windows handler.
|
||||||
|
lRet = DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return lRet;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path)
|
|
||||||
{
|
|
||||||
if (m_current_drives.empty())
|
|
||||||
return false;
|
|
||||||
std::size_t found = path.find_last_of("\\");
|
|
||||||
std::string new_path = path.substr(0, found);
|
|
||||||
int letter = PathGetDriveNumberA(new_path.c_str());
|
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
|
||||||
{
|
|
||||||
char drive = (*it).path[0];
|
|
||||||
if (drive == ('A' + letter))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string RemovableDriveManager::get_drive_from_path(const std::string& path)
|
|
||||||
{
|
|
||||||
std::size_t found = path.find_last_of("\\");
|
|
||||||
std::string new_path = path.substr(0, found);
|
|
||||||
int letter = PathGetDriveNumberA(new_path.c_str());
|
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
|
||||||
{
|
|
||||||
char drive = (*it).path[0];
|
|
||||||
if (drive == ('A' + letter))
|
|
||||||
return (*it).path;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::register_window()
|
void RemovableDriveManager::register_window()
|
||||||
{
|
{
|
||||||
//creates new unvisible window that is recieving callbacks from system
|
//creates new unvisible window that is recieving callbacks from system
|
||||||
// structure to register
|
// structure to register
|
||||||
/* currently not used, left for possible future use
|
// currently not used, left for possible future use
|
||||||
WNDCLASSEX wndClass;
|
WNDCLASSEX wndClass;
|
||||||
wndClass.cbSize = sizeof(WNDCLASSEX);
|
wndClass.cbSize = sizeof(WNDCLASSEX);
|
||||||
wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
||||||
|
@ -179,129 +228,14 @@ void RemovableDriveManager::register_window()
|
||||||
}
|
}
|
||||||
//ShowWindow(hWnd, SW_SHOWNORMAL);
|
//ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||||
UpdateWindow(hWnd);
|
UpdateWindow(hWnd);
|
||||||
*/
|
|
||||||
}
|
|
||||||
/* currently not used, left for possible future use
|
|
||||||
INT_PTR WINAPI WinProcCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
// here we need to catch messeges about device removal
|
|
||||||
// problem is that when ejecting usb (how is it implemented above) there is no messege dispached. Only after physical removal of the device.
|
|
||||||
//uncomment register_window() in init() to register and comment update() in GUI_App.cpp (only for windows!) to stop recieving periodical updates
|
|
||||||
|
|
||||||
LRESULT lRet = 1;
|
|
||||||
static HDEVNOTIFY hDeviceNotify;
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case WM_CREATE:
|
|
||||||
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
|
|
||||||
|
|
||||||
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
|
|
||||||
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
|
||||||
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
|
||||||
NotificationFilter.dbcc_classguid = WceusbshGUID;
|
|
||||||
|
|
||||||
hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_DEVICECHANGE:
|
|
||||||
{
|
|
||||||
// here is the important
|
|
||||||
if(wParam == DBT_DEVICEREMOVECOMPLETE)
|
|
||||||
{
|
|
||||||
- RemovableDriveManager::get_instance().update(0, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Send all other messages on to the default windows handler.
|
|
||||||
lRet = DefWindowProc(hWnd, message, wParam, lParam);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return lRet;
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#else
|
|
||||||
void RemovableDriveManager::search_for_drives()
|
|
||||||
{
|
|
||||||
|
|
||||||
m_current_drives.clear();
|
|
||||||
|
|
||||||
#if __APPLE__
|
|
||||||
// if on macos obj-c class will enumerate
|
|
||||||
if(m_rdmmm)
|
|
||||||
{
|
|
||||||
m_rdmmm->list_devices();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
//search /media/* folder
|
|
||||||
search_path("/media/*", "/media");
|
|
||||||
|
|
||||||
//search_path("/Volumes/*", "/Volumes");
|
|
||||||
std::string path(std::getenv("USER"));
|
|
||||||
std::string pp(path);
|
|
||||||
|
|
||||||
{
|
|
||||||
//search /media/USERNAME/* folder
|
|
||||||
pp = "/media/"+pp;
|
|
||||||
path = "/media/" + path + "/*";
|
|
||||||
search_path(path, pp);
|
|
||||||
|
|
||||||
//search /run/media/USERNAME/* folder
|
|
||||||
path = "/run" + path;
|
|
||||||
pp = "/run"+pp;
|
|
||||||
search_path(path, pp);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
void RemovableDriveManager::search_path(const std::string &path,const std::string &parent_path)
|
|
||||||
{
|
|
||||||
glob_t globbuf;
|
|
||||||
globbuf.gl_offs = 2;
|
|
||||||
int error = glob(path.c_str(), GLOB_TILDE, NULL, &globbuf);
|
|
||||||
if(error == 0)
|
|
||||||
{
|
|
||||||
for(size_t i = 0; i < globbuf.gl_pathc; i++)
|
|
||||||
{
|
|
||||||
inspect_file(globbuf.gl_pathv[i], parent_path);
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
//if error - path probably doesnt exists so function just exits
|
|
||||||
//std::cout<<"glob error "<< error<< "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
globfree(&globbuf);
|
#else
|
||||||
}
|
|
||||||
void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path)
|
|
||||||
{
|
|
||||||
//confirms if the file is removable drive and adds it to vector
|
|
||||||
|
|
||||||
//if not same file system - could be removable drive
|
namespace search_for_drives_internal
|
||||||
if(!compare_filesystem_id(path, parent_path))
|
|
||||||
{
|
{
|
||||||
//free space
|
static bool compare_filesystem_id(const std::string &path_a, const std::string &path_b)
|
||||||
boost::filesystem::space_info si = boost::filesystem::space(path);
|
|
||||||
if(si.available != 0)
|
|
||||||
{
|
|
||||||
//user id
|
|
||||||
struct stat buf;
|
|
||||||
stat(path.c_str(), &buf);
|
|
||||||
uid_t uid = buf.st_uid;
|
|
||||||
std::string username(std::getenv("USER"));
|
|
||||||
struct passwd *pw = getpwuid(uid);
|
|
||||||
if (pw != 0 && pw->pw_name == username)
|
|
||||||
m_current_drives.push_back(DriveData(boost::filesystem::basename(boost::filesystem::path(path)), path));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool RemovableDriveManager::compare_filesystem_id(const std::string &path_a, const std::string &path_b)
|
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
stat(path_a.c_str() ,&buf);
|
stat(path_a.c_str() ,&buf);
|
||||||
|
@ -310,301 +244,272 @@ bool RemovableDriveManager::compare_filesystem_id(const std::string &path_a, con
|
||||||
dev_t id_b = buf.st_dev;
|
dev_t id_b = buf.st_dev;
|
||||||
return id_a == id_b;
|
return id_a == id_b;
|
||||||
}
|
}
|
||||||
void RemovableDriveManager::eject_drive(const std::string &path)
|
|
||||||
|
void inspect_file(const std::string &path, const std::string &parent_path, std::vector<DriveData> &out)
|
||||||
{
|
{
|
||||||
if (m_current_drives.empty())
|
//confirms if the file is removable drive and adds it to vector
|
||||||
|
|
||||||
|
//if not same file system - could be removable drive
|
||||||
|
if (! compare_filesystem_id(path, parent_path)) {
|
||||||
|
//free space
|
||||||
|
boost::filesystem::space_info si = boost::filesystem::space(path);
|
||||||
|
if (si.available != 0) {
|
||||||
|
//user id
|
||||||
|
struct stat buf;
|
||||||
|
stat(path.c_str(), &buf);
|
||||||
|
uid_t uid = buf.st_uid;
|
||||||
|
std::string username(std::getenv("USER"));
|
||||||
|
struct passwd *pw = getpwuid(uid);
|
||||||
|
if (pw != 0 && pw->pw_name == username)
|
||||||
|
out.emplace_back(DriveData{ boost::filesystem::basename(boost::filesystem::path(path)), path });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void search_path(const std::string &path, const std::string &parent_path, std::vector<DriveData> &out)
|
||||||
|
{
|
||||||
|
glob_t globbuf;
|
||||||
|
globbuf.gl_offs = 2;
|
||||||
|
int error = glob(path.c_str(), GLOB_TILDE, NULL, &globbuf);
|
||||||
|
if (error == 0) {
|
||||||
|
for (size_t i = 0; i < globbuf.gl_pathc; ++ i)
|
||||||
|
inspect_file(globbuf.gl_pathv[i], parent_path, out);
|
||||||
|
} else {
|
||||||
|
//if error - path probably doesnt exists so function just exits
|
||||||
|
//std::cout<<"glob error "<< error<< "\n";
|
||||||
|
}
|
||||||
|
globfree(&globbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DriveData> RemovableDriveManager::search_for_removable_drives() const
|
||||||
|
{
|
||||||
|
std::vector<DriveData> current_drives;
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
|
||||||
|
this->list_devices(current_drives);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
//search /media/* folder
|
||||||
|
search_for_drives_internal::search_path("/media/*", "/media", current_drives);
|
||||||
|
|
||||||
|
//search_path("/Volumes/*", "/Volumes");
|
||||||
|
std::string path(std::getenv("USER"));
|
||||||
|
std::string pp(path);
|
||||||
|
|
||||||
|
//search /media/USERNAME/* folder
|
||||||
|
pp = "/media/"+pp;
|
||||||
|
path = "/media/" + path + "/*";
|
||||||
|
search_for_drives_internal::search_path(path, pp, current_drives);
|
||||||
|
|
||||||
|
//search /run/media/USERNAME/* folder
|
||||||
|
path = "/run" + path;
|
||||||
|
pp = "/run"+pp;
|
||||||
|
search_for_drives_internal::search_path(path, pp, current_drives);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return current_drives;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from UI therefore it blocks the UI thread.
|
||||||
|
// It also blocks updates at the worker thread.
|
||||||
|
// Unix & OSX implementation.
|
||||||
|
void RemovableDriveManager::eject_drive()
|
||||||
|
{
|
||||||
|
if (m_last_save_path.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
{
|
this->update();
|
||||||
if((*it).path == path)
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
{
|
|
||||||
|
|
||||||
std::string correct_path(path);
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
|
auto it_drive_data = this->find_last_save_path_drive_data();
|
||||||
|
if (it_drive_data != m_current_drives.end()) {
|
||||||
|
std::string correct_path(m_last_save_path);
|
||||||
for (size_t i = 0; i < correct_path.size(); ++i)
|
for (size_t i = 0; i < correct_path.size(); ++i)
|
||||||
{
|
if (correct_path[i]==' ') {
|
||||||
if(correct_path[i]==' ')
|
|
||||||
{
|
|
||||||
correct_path = correct_path.insert(i,1,'\\');
|
correct_path = correct_path.insert(i,1,'\\');
|
||||||
i++;
|
++ i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n";
|
//std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n";
|
||||||
// there is no usable command in c++ so terminal command is used instead
|
// there is no usable command in c++ so terminal command is used instead
|
||||||
// but neither triggers "succesful safe removal messege"
|
// but neither triggers "succesful safe removal messege"
|
||||||
std::string command = "";
|
std::string command =
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
//m_rdmmm->eject_device(path);
|
//this->eject_device(m_last_save_path);
|
||||||
command = "diskutil unmount ";
|
"diskutil unmount ";
|
||||||
#else
|
#else
|
||||||
command = "umount ";
|
"umount ";
|
||||||
#endif
|
#endif
|
||||||
command += correct_path;
|
command += correct_path;
|
||||||
int err = system(command.c_str());
|
int err = system(command.c_str());
|
||||||
if(err)
|
if (err) {
|
||||||
{
|
BOOST_LOG_TRIVIAL(error) << "Ejecting " << m_last_save_path << " failed";
|
||||||
std::cerr<<"Ejecting failed\n";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_did_eject = true;
|
assert(m_callback_evt_handler);
|
||||||
m_current_drives.erase(it);
|
if (m_callback_evt_handler)
|
||||||
m_ejected_path = m_last_save_path;
|
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::move(*it_drive_data)));
|
||||||
m_ejected_name = m_last_save_name;
|
m_current_drives.erase(it_drive_data);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
std::string RemovableDriveManager::get_removable_drive_path(const std::string &path)
|
||||||
|
{
|
||||||
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
this->update();
|
||||||
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
}
|
|
||||||
bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path)
|
|
||||||
{
|
|
||||||
if (m_current_drives.empty())
|
|
||||||
return false;
|
|
||||||
std::size_t found = path.find_last_of("/");
|
|
||||||
std::string new_path = found == path.size() - 1 ? path.substr(0, found) : path;
|
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
|
||||||
{
|
|
||||||
if(compare_filesystem_id(new_path, (*it).path))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string RemovableDriveManager::get_drive_from_path(const std::string& path)
|
|
||||||
{
|
|
||||||
std::size_t found = path.find_last_of("/");
|
std::size_t found = path.find_last_of("/");
|
||||||
std::string new_path = found == path.size() - 1 ? path.substr(0, found) : path;
|
std::string new_path = found == path.size() - 1 ? path.substr(0, found) : path;
|
||||||
|
|
||||||
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
|
for (const DriveData &data : m_current_drives)
|
||||||
|
if (search_for_drives_internal::compare_filesystem_id(new_path, data.path))
|
||||||
|
return path;
|
||||||
|
return m_current_drives.empty() ? std::string() : m_current_drives.front().path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RemovableDriveManager::get_removable_drive_from_path(const std::string& path)
|
||||||
|
{
|
||||||
|
std::size_t found = path.find_last_of("/");
|
||||||
|
std::string new_path = found == path.size() - 1 ? path.substr(0, found) : path;
|
||||||
// trim the filename
|
// trim the filename
|
||||||
found = new_path.find_last_of("/");
|
found = new_path.find_last_of("/");
|
||||||
new_path = new_path.substr(0, found);
|
new_path = new_path.substr(0, found);
|
||||||
|
|
||||||
// check if same filesystem
|
// check if same filesystem
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
{
|
for (const DriveData &drive_data : m_current_drives)
|
||||||
if (compare_filesystem_id(new_path, (*it).path))
|
if (search_for_drives_internal::compare_filesystem_id(new_path, drive_data.path))
|
||||||
return (*it).path;
|
return drive_data.path;
|
||||||
}
|
return std::string();
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RemovableDriveManager::RemovableDriveManager():
|
void RemovableDriveManager::init(wxEvtHandler *callback_evt_handler)
|
||||||
m_drives_count(0),
|
|
||||||
m_last_update(0),
|
|
||||||
m_last_save_path(""),
|
|
||||||
m_last_save_name(""),
|
|
||||||
m_last_save_path_verified(false),
|
|
||||||
m_is_writing(false),
|
|
||||||
m_did_eject(false),
|
|
||||||
m_plater_ready_to_slice(true),
|
|
||||||
m_ejected_path(""),
|
|
||||||
m_ejected_name("")
|
|
||||||
#if __APPLE__
|
|
||||||
, m_rdmmm(new RDMMMWrapper())
|
|
||||||
#endif
|
|
||||||
{}
|
|
||||||
RemovableDriveManager::~RemovableDriveManager()
|
|
||||||
{
|
{
|
||||||
#if __APPLE__
|
assert(! m_initialized);
|
||||||
delete m_rdmmm;
|
assert(m_callback_evt_handler == nullptr);
|
||||||
#endif
|
|
||||||
}
|
if (m_initialized)
|
||||||
void RemovableDriveManager::init()
|
return;
|
||||||
{
|
|
||||||
//add_callback([](void) { RemovableDriveManager::get_instance().print(); });
|
m_initialized = true;
|
||||||
|
m_callback_evt_handler = callback_evt_handler;
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
//register_window();
|
//this->register_window_msw();
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
m_rdmmm->register_window();
|
this->register_window_osx();
|
||||||
#endif
|
#endif
|
||||||
update(0, true);
|
|
||||||
}
|
#ifdef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
bool RemovableDriveManager::update(const long time,const bool check)
|
this->update();
|
||||||
{
|
#else // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
if(time != 0) //time = 0 is forced update
|
// Don't call update() manually, as the UI triggered APIs call this->update() anyways.
|
||||||
{
|
m_thread = boost::thread((boost::bind(&RemovableDriveManager::thread_proc, this)));
|
||||||
long diff = m_last_update - time;
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
if(diff <= -2)
|
|
||||||
{
|
|
||||||
m_last_update = time;
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
return false; // return value shouldnt matter if update didnt run
|
|
||||||
}
|
|
||||||
}
|
|
||||||
search_for_drives();
|
|
||||||
if (m_drives_count != m_current_drives.size())
|
|
||||||
{
|
|
||||||
if (check)
|
|
||||||
{
|
|
||||||
check_and_notify();
|
|
||||||
}
|
|
||||||
m_drives_count = m_current_drives.size();
|
|
||||||
}
|
|
||||||
return !m_current_drives.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RemovableDriveManager::is_drive_mounted(const std::string &path) const
|
void RemovableDriveManager::shutdown()
|
||||||
{
|
{
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
if (m_thread.joinable()) {
|
||||||
|
// Stop the worker thread, if running.
|
||||||
{
|
{
|
||||||
if ((*it).path == path)
|
// Notify the worker thread to cancel wait on detection polling.
|
||||||
|
std::lock_guard<std::mutex> lck(m_thread_stop_mutex);
|
||||||
|
m_stop = true;
|
||||||
|
}
|
||||||
|
m_thread_stop_condition.notify_all();
|
||||||
|
// Wait for the worker thread to stop.
|
||||||
|
m_thread.join();
|
||||||
|
m_stop = false;
|
||||||
|
}
|
||||||
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
//this->unregister_window_msw();
|
||||||
|
#elif __APPLE__
|
||||||
|
this->unregister_window_osx();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_initialized = false;
|
||||||
|
m_callback_evt_handler = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RemovableDriveManager::set_and_verify_last_save_path(const std::string &path)
|
||||||
{
|
{
|
||||||
return true;
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
this->update();
|
||||||
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
m_last_save_path = this->get_removable_drive_from_path(path);
|
||||||
|
return ! m_last_save_path.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
RemovableDriveManager::RemovableDrivesStatus RemovableDriveManager::status()
|
||||||
|
{
|
||||||
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
this->update();
|
||||||
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
RemovableDriveManager::RemovableDrivesStatus out;
|
||||||
|
{
|
||||||
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
|
out.has_eject = this->find_last_save_path_drive_data() != m_current_drives.end();
|
||||||
|
out.has_removable_drives = ! m_current_drives.empty();
|
||||||
|
}
|
||||||
|
if (! out.has_eject)
|
||||||
|
m_last_save_path.clear();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called from thread_proc() and from most of the public methods on demand.
|
||||||
|
void RemovableDriveManager::update()
|
||||||
|
{
|
||||||
|
std::vector<DriveData> current_drives = this->search_for_removable_drives();
|
||||||
|
|
||||||
|
// Post update events.
|
||||||
|
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||||
|
std::sort(current_drives.begin(), current_drives.end());
|
||||||
|
if (current_drives != m_current_drives) {
|
||||||
|
assert(m_callback_evt_handler);
|
||||||
|
if (m_callback_evt_handler)
|
||||||
|
wxPostEvent(m_callback_evt_handler, RemovableDrivesChangedEvent(EVT_REMOVABLE_DRIVES_CHANGED));
|
||||||
|
}
|
||||||
|
m_current_drives = std::move(current_drives);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
void RemovableDriveManager::thread_proc()
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
// Wait for 2 seconds before running the disk enumeration.
|
||||||
|
// Cancellable.
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(m_thread_stop_mutex);
|
||||||
|
m_thread_stop_condition.wait_for(lck, std::chrono::seconds(2), [this]{ return m_stop; });
|
||||||
|
}
|
||||||
|
if (m_stop)
|
||||||
|
// Stop the worker thread.
|
||||||
|
break;
|
||||||
|
// Update m_current drives and send out update events.
|
||||||
|
this->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
std::vector<DriveData>::const_iterator RemovableDriveManager::find_last_save_path_drive_data() const
|
||||||
|
{
|
||||||
|
return Slic3r::binary_find_by_predicate(m_current_drives.begin(), m_current_drives.end(),
|
||||||
|
[this](const DriveData &data){ return data.path < m_last_save_path; },
|
||||||
|
[this](const DriveData &data){ return data.path == m_last_save_path; });
|
||||||
}
|
}
|
||||||
std::string RemovableDriveManager::get_drive_path()
|
|
||||||
{
|
}} // namespace Slic3r::GUI
|
||||||
if (m_current_drives.size() == 0)
|
|
||||||
{
|
|
||||||
reset_last_save_path();
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (m_last_save_path_verified)
|
|
||||||
return m_last_save_path;
|
|
||||||
return m_current_drives.back().path;
|
|
||||||
}
|
|
||||||
std::string RemovableDriveManager::get_last_save_path() const
|
|
||||||
{
|
|
||||||
if (!m_last_save_path_verified)
|
|
||||||
return "";
|
|
||||||
return m_last_save_path;
|
|
||||||
}
|
|
||||||
std::string RemovableDriveManager::get_last_save_name() const
|
|
||||||
{
|
|
||||||
return m_last_save_name;
|
|
||||||
}
|
|
||||||
std::vector<DriveData> RemovableDriveManager::get_all_drives() const
|
|
||||||
{
|
|
||||||
return m_current_drives;
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::check_and_notify()
|
|
||||||
{
|
|
||||||
if(m_drive_count_changed_callback)
|
|
||||||
{
|
|
||||||
m_drive_count_changed_callback(m_plater_ready_to_slice);
|
|
||||||
}
|
|
||||||
if(m_callbacks.size() != 0 && m_drives_count > m_current_drives.size() && !is_drive_mounted(m_last_save_path))
|
|
||||||
{
|
|
||||||
for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
|
|
||||||
{
|
|
||||||
(*it)();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::add_remove_callback(std::function<void()> callback)
|
|
||||||
{
|
|
||||||
m_callbacks.push_back(callback);
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::erase_callbacks()
|
|
||||||
{
|
|
||||||
m_callbacks.clear();
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::set_drive_count_changed_callback(std::function<void(const bool)> callback)
|
|
||||||
{
|
|
||||||
m_drive_count_changed_callback = callback;
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::set_plater_ready_to_slice(bool b)
|
|
||||||
{
|
|
||||||
m_plater_ready_to_slice = b;
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::set_last_save_path(const std::string& path)
|
|
||||||
{
|
|
||||||
if(m_last_save_path_verified)// if old path is on drive
|
|
||||||
{
|
|
||||||
if(get_drive_from_path(path) != "") //and new is too, rewrite the path
|
|
||||||
{
|
|
||||||
m_last_save_path_verified = false;
|
|
||||||
m_last_save_path = path;
|
|
||||||
}//else do nothing
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
m_last_save_path = path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::verify_last_save_path()
|
|
||||||
{
|
|
||||||
std::string last_drive = get_drive_from_path(m_last_save_path);
|
|
||||||
if (last_drive != "")
|
|
||||||
{
|
|
||||||
m_last_save_path_verified = true;
|
|
||||||
m_last_save_path = last_drive;
|
|
||||||
m_last_save_name = get_drive_name(last_drive);
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
reset_last_save_path();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string RemovableDriveManager::get_drive_name(const std::string& path) const
|
|
||||||
{
|
|
||||||
if (m_current_drives.size() == 0)
|
|
||||||
return "";
|
|
||||||
for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
|
|
||||||
{
|
|
||||||
if ((*it).path == path)
|
|
||||||
{
|
|
||||||
return (*it).name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
bool RemovableDriveManager::is_last_drive_removed()
|
|
||||||
{
|
|
||||||
if(!m_last_save_path_verified)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool r = !is_drive_mounted(m_last_save_path);
|
|
||||||
if (r)
|
|
||||||
{
|
|
||||||
reset_last_save_path();
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
bool RemovableDriveManager::is_last_drive_removed_with_update(const long time)
|
|
||||||
{
|
|
||||||
update(time, false);
|
|
||||||
return is_last_drive_removed();
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::reset_last_save_path()
|
|
||||||
{
|
|
||||||
m_last_save_path_verified = false;
|
|
||||||
m_last_save_path = "";
|
|
||||||
m_last_save_name = "";
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::set_is_writing(const bool b)
|
|
||||||
{
|
|
||||||
m_is_writing = b;
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
m_did_eject = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool RemovableDriveManager::get_is_writing() const
|
|
||||||
{
|
|
||||||
return m_is_writing;
|
|
||||||
}
|
|
||||||
bool RemovableDriveManager::get_did_eject() const
|
|
||||||
{
|
|
||||||
return m_did_eject;
|
|
||||||
}
|
|
||||||
void RemovableDriveManager::set_did_eject(const bool b)
|
|
||||||
{
|
|
||||||
m_did_eject = b;
|
|
||||||
}
|
|
||||||
size_t RemovableDriveManager::get_drives_count() const
|
|
||||||
{
|
|
||||||
return m_current_drives.size();
|
|
||||||
}
|
|
||||||
std::string RemovableDriveManager::get_ejected_path() const
|
|
||||||
{
|
|
||||||
return m_ejected_path;
|
|
||||||
}
|
|
||||||
std::string RemovableDriveManager::get_ejected_name() const
|
|
||||||
{
|
|
||||||
return m_ejected_name;
|
|
||||||
}
|
|
||||||
}}//namespace Slicer::Gui
|
|
||||||
|
|
|
@ -3,119 +3,127 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include <tbb/mutex.h>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
// Custom wxWidget events
|
||||||
|
#include "Event.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
#if __APPLE__
|
|
||||||
class RDMMMWrapper;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct DriveData
|
struct DriveData
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string path;
|
std::string path;
|
||||||
DriveData(std::string n, std::string p):name(n),path(p){}
|
|
||||||
|
void clear() {
|
||||||
|
name.clear();
|
||||||
|
path.clear();
|
||||||
|
}
|
||||||
|
bool empty() const {
|
||||||
|
return path.empty();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator< (const DriveData &lhs, const DriveData &rhs) { return lhs.path < rhs.path; }
|
||||||
|
inline bool operator> (const DriveData &lhs, const DriveData &rhs) { return lhs.path > rhs.path; }
|
||||||
|
inline bool operator==(const DriveData &lhs, const DriveData &rhs) { return lhs.path == rhs.path; }
|
||||||
|
|
||||||
|
using RemovableDriveEjectEvent = Event<DriveData>;
|
||||||
|
wxDECLARE_EVENT(EVT_REMOVABLE_DRIVE_EJECTED, RemovableDriveEjectEvent);
|
||||||
|
|
||||||
|
using RemovableDrivesChangedEvent = SimpleEvent;
|
||||||
|
wxDECLARE_EVENT(EVT_REMOVABLE_DRIVES_CHANGED, RemovableDrivesChangedEvent);
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
// Callbacks on device plug / unplug work reliably on OSX.
|
||||||
|
#define REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
class RemovableDriveManager
|
class RemovableDriveManager
|
||||||
{
|
{
|
||||||
#if __APPLE__
|
|
||||||
friend class RDMMMWrapper;
|
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
static RemovableDriveManager& get_instance()
|
RemovableDriveManager() = default;
|
||||||
{
|
|
||||||
static RemovableDriveManager instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
RemovableDriveManager(RemovableDriveManager const&) = delete;
|
RemovableDriveManager(RemovableDriveManager const&) = delete;
|
||||||
void operator=(RemovableDriveManager const&) = delete;
|
void operator=(RemovableDriveManager const&) = delete;
|
||||||
~RemovableDriveManager();
|
~RemovableDriveManager() { assert(! m_initialized); }
|
||||||
//call only once. on apple register for unmnount callbacks. on windows register for device notification is prepared but not called (eject usb drive on widnows doesnt trigger the callback, sdc ard does), also enumerates devices for first time so init shoud be called on linux too.
|
|
||||||
void init();
|
|
||||||
//update() searches for removable devices, returns false if empty. /time = 0 is forced update, time expects wxGetLocalTime()
|
|
||||||
bool update(const long time = 0,const bool check = false);
|
|
||||||
bool is_drive_mounted(const std::string &path) const;
|
|
||||||
void eject_drive(const std::string &path);
|
|
||||||
//returns path to last drive which was used, if none was used, returns device that was enumerated last
|
|
||||||
std::string get_last_save_path() const;
|
|
||||||
std::string get_last_save_name() const;
|
|
||||||
//returns path to last drive which was used, if none was used, returns empty string
|
|
||||||
std::string get_drive_path();
|
|
||||||
std::vector<DriveData> get_all_drives() const;
|
|
||||||
bool is_path_on_removable_drive(const std::string &path);
|
|
||||||
// callback will notify only if device with last save path was removed
|
|
||||||
void add_remove_callback(std::function<void()> callback);
|
|
||||||
// erases all remove callbacks added by add_remove_callback()
|
|
||||||
void erase_callbacks();
|
|
||||||
//drive_count_changed callback is called on every added or removed device
|
|
||||||
void set_drive_count_changed_callback(std::function<void(const bool)> callback);
|
|
||||||
//thi serves to set correct value for drive_count_changed callback
|
|
||||||
void set_plater_ready_to_slice(bool b);
|
|
||||||
// marks one of the eveices in vector as last used
|
|
||||||
void set_last_save_path(const std::string &path);
|
|
||||||
void verify_last_save_path();
|
|
||||||
bool is_last_drive_removed();
|
|
||||||
// param as update()
|
|
||||||
bool is_last_drive_removed_with_update(const long time = 0);
|
|
||||||
void set_is_writing(const bool b);
|
|
||||||
bool get_is_writing() const;
|
|
||||||
bool get_did_eject() const;
|
|
||||||
void set_did_eject(const bool b);
|
|
||||||
std::string get_drive_name(const std::string& path) const;
|
|
||||||
size_t get_drives_count() const;
|
|
||||||
std::string get_ejected_path() const;
|
|
||||||
std::string get_ejected_name() const;
|
|
||||||
private:
|
|
||||||
RemovableDriveManager();
|
|
||||||
void search_for_drives();
|
|
||||||
//triggers callbacks if last used drive was removed
|
|
||||||
void check_and_notify();
|
|
||||||
//returns drive path (same as path in DriveData) if exists otherwise empty string ""
|
|
||||||
std::string get_drive_from_path(const std::string& path);
|
|
||||||
void reset_last_save_path();
|
|
||||||
|
|
||||||
|
// Start the background thread and register this window as a target for update events.
|
||||||
|
// Register for OSX notifications.
|
||||||
|
void init(wxEvtHandler *callback_evt_handler);
|
||||||
|
// Stop the background thread of the removable drive manager, so that no new updates will be sent out.
|
||||||
|
// Deregister OSX notifications.
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
// Returns path to a removable media if it exists, prefering the input path.
|
||||||
|
std::string get_removable_drive_path(const std::string &path);
|
||||||
|
bool is_path_on_removable_drive(const std::string &path) { return this->get_removable_drive_path(path) == path; }
|
||||||
|
|
||||||
|
// Verify whether the path provided is on removable media. If so, save the path for further eject and return true, otherwise return false.
|
||||||
|
bool set_and_verify_last_save_path(const std::string &path);
|
||||||
|
// Eject drive of a file set by set_and_verify_last_save_path().
|
||||||
|
// On Unix / OSX, the function blocks and sends out the EVT_REMOVABLE_DRIVE_EJECTED event on success.
|
||||||
|
// On Windows, the function does not block, and the eject is detected in the background thread.
|
||||||
|
void eject_drive();
|
||||||
|
|
||||||
|
struct RemovableDrivesStatus {
|
||||||
|
bool has_removable_drives { false };
|
||||||
|
bool has_eject { false };
|
||||||
|
};
|
||||||
|
RemovableDrivesStatus status();
|
||||||
|
|
||||||
|
// Enumerates current drives and sends out wxWidget events on change or eject.
|
||||||
|
// Called by each public method, by the background thread and from RemovableDriveManagerMM::on_device_unmount OSX notification handler.
|
||||||
|
// Not to be called manually.
|
||||||
|
// Public to be accessible from RemovableDriveManagerMM::on_device_unmount OSX notification handler.
|
||||||
|
// It would be better to make this method private and friend to RemovableDriveManagerMM, but RemovableDriveManagerMM is an ObjectiveC class.
|
||||||
|
void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_initialized { false };
|
||||||
|
wxEvtHandler* m_callback_evt_handler { nullptr };
|
||||||
|
|
||||||
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
// Worker thread, worker thread synchronization and callbacks to the UI thread.
|
||||||
|
void thread_proc();
|
||||||
|
boost::thread m_thread;
|
||||||
|
std::condition_variable m_thread_stop_condition;
|
||||||
|
mutable std::mutex m_thread_stop_mutex;
|
||||||
|
bool m_stop { false };
|
||||||
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
// Called from update() to enumerate removable drives.
|
||||||
|
std::vector<DriveData> search_for_removable_drives() const;
|
||||||
|
|
||||||
|
// m_current_drives is guarded by m_drives_mutex
|
||||||
|
// sorted ascending by path
|
||||||
std::vector<DriveData> m_current_drives;
|
std::vector<DriveData> m_current_drives;
|
||||||
std::vector<std::function<void()>> m_callbacks;
|
mutable tbb::mutex m_drives_mutex;
|
||||||
std::function<void(const bool)> m_drive_count_changed_callback;
|
|
||||||
size_t m_drives_count;
|
// Returns drive path (same as path in DriveData) if exists otherwise empty string.
|
||||||
long m_last_update;
|
std::string get_removable_drive_from_path(const std::string& path);
|
||||||
|
// Returns iterator to a drive in m_current_drives with path equal to m_last_save_path or end().
|
||||||
|
std::vector<DriveData>::const_iterator find_last_save_path_drive_data() const;
|
||||||
|
// Set with set_and_verify_last_save_path() to a removable drive path to be ejected.
|
||||||
std::string m_last_save_path;
|
std::string m_last_save_path;
|
||||||
bool m_last_save_path_verified;
|
|
||||||
std::string m_last_save_name;
|
|
||||||
bool m_is_writing;//on device
|
|
||||||
bool m_did_eject;
|
|
||||||
bool m_plater_ready_to_slice;
|
|
||||||
std::string m_ejected_path;
|
|
||||||
std::string m_ejected_name;
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
//registers for notifications by creating invisible window
|
//registers for notifications by creating invisible window
|
||||||
void register_window();
|
//void register_window_msw();
|
||||||
#else
|
#elif __APPLE__
|
||||||
#if __APPLE__
|
void register_window_osx();
|
||||||
RDMMMWrapper * m_rdmmm;
|
void unregister_window_osx();
|
||||||
#endif
|
void list_devices(std::vector<DriveData> &out) const;
|
||||||
void search_path(const std::string &path, const std::string &parent_path);
|
// not used as of now
|
||||||
bool compare_filesystem_id(const std::string &path_a, const std::string &path_b);
|
|
||||||
void inspect_file(const std::string &path, const std::string &parent_path);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
// apple wrapper for RemovableDriveManagerMM which searches for drives and/or ejects them
|
|
||||||
#if __APPLE__
|
|
||||||
class RDMMMWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RDMMMWrapper();
|
|
||||||
~RDMMMWrapper();
|
|
||||||
void register_window();
|
|
||||||
void list_devices();
|
|
||||||
void eject_device(const std::string &path);
|
void eject_device(const std::string &path);
|
||||||
void log(const std::string &msg);
|
// Opaque pointer to RemovableDriveManagerMM
|
||||||
protected:
|
void *m_impl_osx;
|
||||||
void *m_imp;
|
#endif
|
||||||
//friend void RemovableDriveManager::inspect_file(const std::string &path, const std::string &parent_path);
|
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
}}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // slic3r_GUI_RemovableDriveManager_hpp_
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#import "RemovableDriveManager.hpp"
|
#import "RemovableDriveManager.hpp"
|
||||||
#import "RemovableDriveManagerMM.h"
|
#import "RemovableDriveManagerMM.h"
|
||||||
|
#import "GUI_App.hpp"
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
#import <DiskArbitration/DiskArbitration.h>
|
#import <DiskArbitration/DiskArbitration.h>
|
||||||
|
|
||||||
|
@ -10,22 +11,23 @@
|
||||||
-(instancetype) init
|
-(instancetype) init
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self)
|
//if(self){}
|
||||||
{
|
|
||||||
}
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) on_device_unmount: (NSNotification*) notification
|
-(void) on_device_unmount: (NSNotification*) notification
|
||||||
{
|
{
|
||||||
NSLog(@"on device change");
|
//NSLog(@"on device change");
|
||||||
Slic3r::GUI::RemovableDriveManager::get_instance().update(0,true);
|
Slic3r::GUI::wxGetApp().removable_drive_manager()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) add_unmount_observer
|
-(void) add_unmount_observer
|
||||||
{
|
{
|
||||||
NSLog(@"add unmount observer");
|
//NSLog(@"add unmount observer");
|
||||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil];
|
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidUnmountNotification object:nil];
|
||||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidMountNotification object:nil];
|
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(on_device_unmount:) name:NSWorkspaceDidMountNotification object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(NSArray*) list_dev
|
-(NSArray*) list_dev
|
||||||
{
|
{
|
||||||
// DEPRICATED:
|
// DEPRICATED:
|
||||||
|
@ -40,118 +42,99 @@
|
||||||
DADiskRef disk;
|
DADiskRef disk;
|
||||||
DASessionRef session;
|
DASessionRef session;
|
||||||
CFDictionaryRef descDict;
|
CFDictionaryRef descDict;
|
||||||
session = DASessionCreate(NULL);
|
session = DASessionCreate(nullptr);
|
||||||
if (session == NULL) {
|
if (session == nullptr)
|
||||||
err = EINVAL;
|
err = EINVAL;
|
||||||
}
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
disk = DADiskCreateFromVolumePath(NULL,session,(CFURLRef)volURL);
|
disk = DADiskCreateFromVolumePath(nullptr,session,(CFURLRef)volURL);
|
||||||
if (session == NULL) {
|
if (session == nullptr)
|
||||||
err = EINVAL;
|
err = EINVAL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
descDict = DADiskCopyDescription(disk);
|
descDict = DADiskCopyDescription(disk);
|
||||||
if (descDict == NULL) {
|
if (descDict == nullptr)
|
||||||
err = EINVAL;
|
err = EINVAL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
CFTypeRef mediaEjectableKey = CFDictionaryGetValue(descDict,kDADiskDescriptionMediaEjectableKey);
|
CFTypeRef mediaEjectableKey = CFDictionaryGetValue(descDict,kDADiskDescriptionMediaEjectableKey);
|
||||||
BOOL ejectable = [mediaEjectableKey boolValue];
|
BOOL ejectable = [mediaEjectableKey boolValue];
|
||||||
CFTypeRef deviceProtocolName = CFDictionaryGetValue(descDict,kDADiskDescriptionDeviceProtocolKey);
|
CFTypeRef deviceProtocolName = CFDictionaryGetValue(descDict,kDADiskDescriptionDeviceProtocolKey);
|
||||||
CFTypeRef deviceModelKey = CFDictionaryGetValue(descDict, kDADiskDescriptionDeviceModelKey);
|
CFTypeRef deviceModelKey = CFDictionaryGetValue(descDict, kDADiskDescriptionDeviceModelKey);
|
||||||
if (mediaEjectableKey != NULL)
|
if (mediaEjectableKey != nullptr) {
|
||||||
{
|
|
||||||
BOOL op = ejectable && (CFEqual(deviceProtocolName, CFSTR("USB")) || CFEqual(deviceModelKey, CFSTR("SD Card Reader")));
|
BOOL op = ejectable && (CFEqual(deviceProtocolName, CFSTR("USB")) || CFEqual(deviceModelKey, CFSTR("SD Card Reader")));
|
||||||
//!CFEqual(deviceModelKey, CFSTR("Disk Image"));
|
//!CFEqual(deviceModelKey, CFSTR("Disk Image"));
|
||||||
//
|
if (op)
|
||||||
if (op) {
|
|
||||||
[result addObject:volURL.path];
|
[result addObject:volURL.path];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (descDict != nullptr)
|
||||||
if (descDict != NULL) {
|
|
||||||
CFRelease(descDict);
|
CFRelease(descDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this eject drive is not used now
|
||||||
-(void)eject_drive:(NSString *)path
|
-(void)eject_drive:(NSString *)path
|
||||||
{
|
{
|
||||||
DADiskRef disk;
|
DADiskRef disk;
|
||||||
DASessionRef session;
|
DASessionRef session;
|
||||||
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
|
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
|
||||||
int err = 0;
|
int err = 0;
|
||||||
session = DASessionCreate(NULL);
|
session = DASessionCreate(nullptr);
|
||||||
if (session == NULL) {
|
if (session == nullptr)
|
||||||
err = EINVAL;
|
err = EINVAL;
|
||||||
}
|
|
||||||
if (err == 0) {
|
|
||||||
disk = DADiskCreateFromVolumePath(NULL,session,(CFURLRef)url);
|
|
||||||
}
|
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
{
|
disk = DADiskCreateFromVolumePath(nullptr,session,(CFURLRef)url);
|
||||||
DADiskUnmount(disk, kDADiskUnmountOptionDefault,
|
if( err == 0)
|
||||||
NULL, NULL);
|
DADiskUnmount(disk, kDADiskUnmountOptionDefault, nullptr, nullptr);
|
||||||
}
|
if (disk != nullptr)
|
||||||
if (disk != NULL) {
|
|
||||||
CFRelease(disk);
|
CFRelease(disk);
|
||||||
}
|
if (session != nullptr)
|
||||||
if (session != NULL) {
|
|
||||||
CFRelease(session);
|
CFRelease(session);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
namespace Slic3r {
|
|
||||||
namespace GUI {
|
|
||||||
RDMMMWrapper::RDMMMWrapper():m_imp(nullptr){
|
|
||||||
m_imp = [[RemovableDriveManagerMM alloc] init];
|
|
||||||
}
|
|
||||||
RDMMMWrapper::~RDMMMWrapper()
|
|
||||||
{
|
|
||||||
if(m_imp)
|
|
||||||
{
|
|
||||||
[m_imp release];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void RDMMMWrapper::register_window()
|
|
||||||
{
|
|
||||||
if(m_imp)
|
|
||||||
{
|
|
||||||
[m_imp add_unmount_observer];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void RDMMMWrapper::list_devices()
|
|
||||||
{
|
|
||||||
if(m_imp)
|
|
||||||
{
|
|
||||||
NSArray* devices = [m_imp list_dev];
|
|
||||||
for (NSString* volumePath in devices)
|
|
||||||
{
|
|
||||||
NSLog(@"%@", volumePath);
|
|
||||||
Slic3r::GUI::RemovableDriveManager::get_instance().inspect_file(std::string([volumePath UTF8String]), "/Volumes");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void RDMMMWrapper::log(const std::string &msg)
|
|
||||||
{
|
|
||||||
NSLog(@"%s", msg.c_str());
|
|
||||||
}
|
|
||||||
void RDMMMWrapper::eject_device(const std::string &path)
|
|
||||||
{
|
|
||||||
if(m_imp)
|
|
||||||
{
|
|
||||||
NSString * pth = [NSString stringWithCString:path.c_str()
|
|
||||||
encoding:[NSString defaultCStringEncoding]];
|
|
||||||
[m_imp eject_drive:pth];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}//namespace Slicer::GUI
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
void RemovableDriveManager::register_window_osx()
|
||||||
|
{
|
||||||
|
assert(m_impl_osx == nullptr);
|
||||||
|
m_impl_osx = [[RemovableDriveManagerMM alloc] init];
|
||||||
|
if (m_impl_osx)
|
||||||
|
[m_impl_osx add_unmount_observer];
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemovableDriveManager::unregister_window_osx()
|
||||||
|
{
|
||||||
|
if (m_impl_osx)
|
||||||
|
[m_impl_osx release];
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace search_for_drives_internal
|
||||||
|
{
|
||||||
|
void inspect_file(const std::string &path, const std::string &parent_path, std::vector<DriveData> &out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemovableDriveManager::list_devices(std::vector<DriveData> &out) const
|
||||||
|
{
|
||||||
|
assert(m_impl_osx != nullptr);
|
||||||
|
if (m_impl_osx) {
|
||||||
|
NSArray* devices = [m_impl_osx list_dev];
|
||||||
|
for (NSString* volumePath in devices)
|
||||||
|
search_for_drives_internal::inspect_file(std::string([volumePath UTF8String]), "/Volumes", out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not used as of now
|
||||||
|
void RemovableDriveManager::eject_device(const std::string &path)
|
||||||
|
{
|
||||||
|
assert(m_impl_osx != nullptr);
|
||||||
|
if (m_impl_osx) {
|
||||||
|
NSString * pth = [NSString stringWithCString:path.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||||
|
[m_impl_osx eject_drive:pth];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}}//namespace Slicer::GUI
|
||||||
|
|
|
@ -359,9 +359,10 @@ void Tab::update_labels_colour()
|
||||||
color = &m_modified_label_clr;
|
color = &m_modified_label_clr;
|
||||||
}
|
}
|
||||||
if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") {
|
if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") {
|
||||||
if (m_colored_Label != nullptr) {
|
wxStaticText* label = (m_colored_Labels.find(opt.first) == m_colored_Labels.end()) ? nullptr : m_colored_Labels.at(opt.first);
|
||||||
m_colored_Label->SetForegroundColour(*color);
|
if (label) {
|
||||||
m_colored_Label->Refresh(true);
|
label->SetForegroundColour(*color);
|
||||||
|
label->Refresh(true);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -449,9 +450,10 @@ void Tab::update_changed_ui()
|
||||||
tt = &m_tt_white_bullet;
|
tt = &m_tt_white_bullet;
|
||||||
}
|
}
|
||||||
if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") {
|
if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") {
|
||||||
if (m_colored_Label != nullptr) {
|
wxStaticText* label = (m_colored_Labels.find(opt.first) == m_colored_Labels.end()) ? nullptr : m_colored_Labels.at(opt.first);
|
||||||
m_colored_Label->SetForegroundColour(*color);
|
if (label) {
|
||||||
m_colored_Label->Refresh(true);
|
label->SetForegroundColour(*color);
|
||||||
|
label->Refresh(true);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -668,7 +670,8 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
|
||||||
|
|
||||||
}
|
}
|
||||||
if (group->title == _("Profile dependencies")) {
|
if (group->title == _("Profile dependencies")) {
|
||||||
if (m_type != Slic3r::Preset::TYPE_PRINTER && (m_options_list["compatible_printers"] & os) == 0) {
|
// "compatible_printers" option doesn't exists in Printer Settimgs Tab
|
||||||
|
if (m_type != Preset::TYPE_PRINTER && (m_options_list["compatible_printers"] & os) == 0) {
|
||||||
to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers");
|
to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers");
|
||||||
load_key_value("compatible_printers", true/*some value*/, true);
|
load_key_value("compatible_printers", true/*some value*/, true);
|
||||||
|
|
||||||
|
@ -676,7 +679,8 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
|
||||||
m_compatible_printers.checkbox->SetValue(is_empty);
|
m_compatible_printers.checkbox->SetValue(is_empty);
|
||||||
is_empty ? m_compatible_printers.btn->Disable() : m_compatible_printers.btn->Enable();
|
is_empty ? m_compatible_printers.btn->Disable() : m_compatible_printers.btn->Enable();
|
||||||
}
|
}
|
||||||
if ((m_type == Slic3r::Preset::TYPE_PRINT || m_type == Slic3r::Preset::TYPE_SLA_PRINT) && (m_options_list["compatible_prints"] & os) == 0) {
|
// "compatible_prints" option exists only in Filament Settimgs and Materials Tabs
|
||||||
|
if ((m_type == Preset::TYPE_FILAMENT || m_type == Preset::TYPE_SLA_MATERIAL) && (m_options_list["compatible_prints"] & os) == 0) {
|
||||||
to_sys ? group->back_to_sys_value("compatible_prints") : group->back_to_initial_value("compatible_prints");
|
to_sys ? group->back_to_sys_value("compatible_prints") : group->back_to_initial_value("compatible_prints");
|
||||||
load_key_value("compatible_prints", true/*some value*/, true);
|
load_key_value("compatible_prints", true/*some value*/, true);
|
||||||
|
|
||||||
|
@ -754,10 +758,17 @@ void Tab::update_visibility()
|
||||||
{
|
{
|
||||||
Freeze(); // There is needed Freeze/Thaw to avoid a flashing after Show/Layout
|
Freeze(); // There is needed Freeze/Thaw to avoid a flashing after Show/Layout
|
||||||
|
|
||||||
|
// m_detach_preset_btn will be shown always after call page->update_visibility()
|
||||||
|
// So let save a "show state" of m_detach_preset_btn before update_visibility
|
||||||
|
bool was_shown = m_detach_preset_btn->IsShown();
|
||||||
|
|
||||||
for (auto page : m_pages)
|
for (auto page : m_pages)
|
||||||
page->update_visibility(m_mode);
|
page->update_visibility(m_mode);
|
||||||
update_page_tree_visibility();
|
update_page_tree_visibility();
|
||||||
|
|
||||||
|
// update visibility for detach_preset_btn
|
||||||
|
m_detach_preset_btn->Show(was_shown);
|
||||||
|
|
||||||
Layout();
|
Layout();
|
||||||
Thaw();
|
Thaw();
|
||||||
}
|
}
|
||||||
|
@ -942,6 +953,52 @@ void Tab::on_presets_changed()
|
||||||
m_dependent_tabs.clear();
|
m_dependent_tabs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tab::build_preset_description_line(ConfigOptionsGroup* optgroup)
|
||||||
|
{
|
||||||
|
auto description_line = [this](wxWindow* parent) {
|
||||||
|
return description_line_widget(parent, &m_parent_preset_description_line);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto detach_preset_btn = [this](wxWindow* parent) {
|
||||||
|
add_scaled_button(parent, &m_detach_preset_btn, "lock_open_sys", _(L("Detach from system preset")), wxBU_LEFT | wxBU_EXACTFIT);
|
||||||
|
ScalableButton* btn = m_detach_preset_btn;
|
||||||
|
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||||
|
|
||||||
|
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
sizer->Add(btn);
|
||||||
|
|
||||||
|
btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent&)
|
||||||
|
{
|
||||||
|
bool system = m_presets->get_edited_preset().is_system;
|
||||||
|
bool dirty = m_presets->get_edited_preset().is_dirty;
|
||||||
|
wxString msg_text = system ?
|
||||||
|
_(L("A copy of the current system preset will be created, which will be detached from the system preset.")) :
|
||||||
|
_(L("The current custom preset will be detached from the parent system preset."));
|
||||||
|
if (dirty) {
|
||||||
|
msg_text += "\n\n";
|
||||||
|
msg_text += _(L("Modifications to the current profile will be saved."));
|
||||||
|
}
|
||||||
|
msg_text += "\n\n";
|
||||||
|
msg_text += _(L("This action is not revertable.\nDo you want to proceed?"));
|
||||||
|
|
||||||
|
wxMessageDialog dialog(parent, msg_text, _(L("Detach preset")), wxICON_WARNING | wxYES_NO | wxCANCEL);
|
||||||
|
if (dialog.ShowModal() == wxID_YES)
|
||||||
|
save_preset(m_presets->get_edited_preset().is_system ? std::string() : m_presets->get_edited_preset().name, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
btn->Hide();
|
||||||
|
|
||||||
|
return sizer;
|
||||||
|
};
|
||||||
|
|
||||||
|
Line line = Line{ "", "" };
|
||||||
|
line.full_width = 1;
|
||||||
|
|
||||||
|
line.append_widget(description_line);
|
||||||
|
line.append_widget(detach_preset_btn);
|
||||||
|
optgroup->append_line(line);
|
||||||
|
}
|
||||||
|
|
||||||
void Tab::update_preset_description_line()
|
void Tab::update_preset_description_line()
|
||||||
{
|
{
|
||||||
const Preset* parent = m_presets->get_selected_preset_parent();
|
const Preset* parent = m_presets->get_selected_preset_parent();
|
||||||
|
@ -1007,14 +1064,18 @@ void Tab::update_preset_description_line()
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!preset.alias.empty())
|
||||||
{
|
{
|
||||||
description_line += "\n\n\t" + _(L("full profile name")) + ": \n\t\t" + parent->name;
|
description_line += "\n\n\t" + _(L("full profile name")) + ": \n\t\t" + preset.name;
|
||||||
description_line += "\n\t" + _(L("symbolic profile name")) + ": \n\t\t" + parent->alias;
|
description_line += "\n\t" + _(L("symbolic profile name")) + ": \n\t\t" + preset.alias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_parent_preset_description_line->SetText(description_line, false);
|
m_parent_preset_description_line->SetText(description_line, false);
|
||||||
|
|
||||||
|
if (m_detach_preset_btn)
|
||||||
|
m_detach_preset_btn->Show(parent && parent->is_system && !preset.is_default);
|
||||||
|
Layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tab::update_frequently_changed_parameters()
|
void Tab::update_frequently_changed_parameters()
|
||||||
|
@ -1256,21 +1317,16 @@ void TabPrint::build()
|
||||||
|
|
||||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||||
line = optgroup->create_single_option_line("compatible_printers");
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
|
||||||
return compatible_widget_create(parent, m_compatible_printers);
|
return compatible_widget_create(parent, m_compatible_printers);
|
||||||
};
|
});
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
option = optgroup->get_option("compatible_printers_condition");
|
option = optgroup->get_option("compatible_printers_condition");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
optgroup->append_single_option_line(option);
|
optgroup->append_single_option_line(option);
|
||||||
|
|
||||||
line = Line{ "", "" };
|
build_preset_description_line(optgroup.get());
|
||||||
line.full_width = 1;
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return description_line_widget(parent, &m_parent_preset_description_line);
|
|
||||||
};
|
|
||||||
optgroup->append_line(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
||||||
|
@ -1546,31 +1602,23 @@ void TabFilament::build()
|
||||||
|
|
||||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||||
|
create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
|
||||||
line = optgroup->create_single_option_line("compatible_printers");
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return compatible_widget_create(parent, m_compatible_printers);
|
return compatible_widget_create(parent, m_compatible_printers);
|
||||||
};
|
});
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
option = optgroup->get_option("compatible_printers_condition");
|
option = optgroup->get_option("compatible_printers_condition");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
optgroup->append_single_option_line(option);
|
optgroup->append_single_option_line(option);
|
||||||
|
|
||||||
line = optgroup->create_single_option_line("compatible_prints");
|
create_line_with_widget(optgroup.get(), "compatible_prints", [this](wxWindow* parent) {
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return compatible_widget_create(parent, m_compatible_prints);
|
return compatible_widget_create(parent, m_compatible_prints);
|
||||||
};
|
});
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
option = optgroup->get_option("compatible_prints_condition");
|
option = optgroup->get_option("compatible_prints_condition");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
optgroup->append_single_option_line(option);
|
optgroup->append_single_option_line(option);
|
||||||
|
|
||||||
line = Line{ "", "" };
|
build_preset_description_line(optgroup.get());
|
||||||
line.full_width = 1;
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return description_line_widget(parent, &m_parent_preset_description_line);
|
|
||||||
};
|
|
||||||
optgroup->append_line(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
||||||
|
@ -1798,38 +1846,10 @@ void TabPrinter::build_fff()
|
||||||
auto page = add_options_page(_(L("General")), "printer");
|
auto page = add_options_page(_(L("General")), "printer");
|
||||||
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
|
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
|
||||||
|
|
||||||
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
|
create_line_with_widget(optgroup.get(), "bed_shape", [this](wxWindow* parent) {
|
||||||
line.widget = [this](wxWindow* parent) {
|
return create_bed_shape_widget(parent);
|
||||||
ScalableButton* btn;
|
});
|
||||||
add_scaled_button(parent, &btn, "printer_white", " " + _(L("Set")) + " " + dots, wxBU_LEFT | wxBU_EXACTFIT);
|
|
||||||
btn->SetFont(wxGetApp().normal_font());
|
|
||||||
|
|
||||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
||||||
sizer->Add(btn);
|
|
||||||
|
|
||||||
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
|
|
||||||
{
|
|
||||||
BedShapeDialog dlg(this);
|
|
||||||
dlg.build_dialog(*m_config->option<ConfigOptionPoints>("bed_shape"),
|
|
||||||
*m_config->option<ConfigOptionString>("bed_custom_texture"),
|
|
||||||
*m_config->option<ConfigOptionString>("bed_custom_model"));
|
|
||||||
if (dlg.ShowModal() == wxID_OK) {
|
|
||||||
const std::vector<Vec2d>& shape = dlg.get_shape();
|
|
||||||
const std::string& custom_texture = dlg.get_custom_texture();
|
|
||||||
const std::string& custom_model = dlg.get_custom_model();
|
|
||||||
if (!shape.empty())
|
|
||||||
{
|
|
||||||
load_key_value("bed_shape", shape);
|
|
||||||
load_key_value("bed_custom_texture", custom_texture);
|
|
||||||
load_key_value("bed_custom_model", custom_model);
|
|
||||||
update_changed_ui();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
return sizer;
|
|
||||||
};
|
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
optgroup->append_single_option_line("max_print_height");
|
optgroup->append_single_option_line("max_print_height");
|
||||||
optgroup->append_single_option_line("z_offset");
|
optgroup->append_single_option_line("z_offset");
|
||||||
|
|
||||||
|
@ -2020,12 +2040,8 @@ void TabPrinter::build_fff()
|
||||||
|
|
||||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||||
line = Line{ "", "" };
|
|
||||||
line.full_width = 1;
|
build_preset_description_line(optgroup.get());
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return description_line_widget(parent, &m_parent_preset_description_line);
|
|
||||||
};
|
|
||||||
optgroup->append_line(line);
|
|
||||||
|
|
||||||
build_unregular_pages();
|
build_unregular_pages();
|
||||||
|
|
||||||
|
@ -2042,39 +2058,9 @@ void TabPrinter::build_sla()
|
||||||
auto page = add_options_page(_(L("General")), "printer");
|
auto page = add_options_page(_(L("General")), "printer");
|
||||||
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
|
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
|
||||||
|
|
||||||
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
|
create_line_with_widget(optgroup.get(), "bed_shape", [this](wxWindow* parent) {
|
||||||
line.widget = [this](wxWindow* parent) {
|
return create_bed_shape_widget(parent);
|
||||||
ScalableButton* btn;
|
});
|
||||||
add_scaled_button(parent, &btn, "printer_white", " " + _(L("Set")) + " " + dots, wxBU_LEFT | wxBU_EXACTFIT);
|
|
||||||
btn->SetFont(wxGetApp().normal_font());
|
|
||||||
|
|
||||||
|
|
||||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
||||||
sizer->Add(btn);
|
|
||||||
|
|
||||||
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
|
|
||||||
{
|
|
||||||
BedShapeDialog dlg(this);
|
|
||||||
dlg.build_dialog(*m_config->option<ConfigOptionPoints>("bed_shape"),
|
|
||||||
*m_config->option<ConfigOptionString>("bed_custom_texture"),
|
|
||||||
*m_config->option<ConfigOptionString>("bed_custom_model"));
|
|
||||||
if (dlg.ShowModal() == wxID_OK) {
|
|
||||||
const std::vector<Vec2d>& shape = dlg.get_shape();
|
|
||||||
const std::string& custom_texture = dlg.get_custom_texture();
|
|
||||||
const std::string& custom_model = dlg.get_custom_model();
|
|
||||||
if (!shape.empty())
|
|
||||||
{
|
|
||||||
load_key_value("bed_shape", shape);
|
|
||||||
load_key_value("bed_custom_texture", custom_texture);
|
|
||||||
load_key_value("bed_custom_model", custom_model);
|
|
||||||
update_changed_ui();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
return sizer;
|
|
||||||
};
|
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
optgroup->append_single_option_line("max_print_height");
|
optgroup->append_single_option_line("max_print_height");
|
||||||
|
|
||||||
optgroup = page->new_optgroup(_(L("Display")));
|
optgroup = page->new_optgroup(_(L("Display")));
|
||||||
|
@ -2082,7 +2068,7 @@ void TabPrinter::build_sla()
|
||||||
optgroup->append_single_option_line("display_height");
|
optgroup->append_single_option_line("display_height");
|
||||||
|
|
||||||
auto option = optgroup->get_option("display_pixels_x");
|
auto option = optgroup->get_option("display_pixels_x");
|
||||||
line = { _(option.opt.full_label), "" };
|
Line line = { _(option.opt.full_label), "" };
|
||||||
line.append_option(option);
|
line.append_option(option);
|
||||||
line.append_option(optgroup->get_option("display_pixels_y"));
|
line.append_option(optgroup->get_option("display_pixels_y"));
|
||||||
optgroup->append_line(line);
|
optgroup->append_line(line);
|
||||||
|
@ -2136,12 +2122,8 @@ void TabPrinter::build_sla()
|
||||||
|
|
||||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||||
line = Line{ "", "" };
|
|
||||||
line.full_width = 1;
|
build_preset_description_line(optgroup.get());
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return description_line_widget(parent, &m_parent_preset_description_line);
|
|
||||||
};
|
|
||||||
optgroup->append_line(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabPrinter::update_serial_ports()
|
void TabPrinter::update_serial_ports()
|
||||||
|
@ -2604,6 +2586,15 @@ void TabPrinter::update_fff()
|
||||||
void TabPrinter::update_sla()
|
void TabPrinter::update_sla()
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
void Tab::update_ui_items_related_on_parent_preset(const Preset* selected_preset_parent)
|
||||||
|
{
|
||||||
|
m_is_default_preset = selected_preset_parent != nullptr && selected_preset_parent->is_default;
|
||||||
|
|
||||||
|
m_bmp_non_system = selected_preset_parent ? &m_bmp_value_unlock : &m_bmp_white_bullet;
|
||||||
|
m_ttg_non_system = selected_preset_parent ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns;
|
||||||
|
m_tt_non_system = selected_preset_parent ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the UI from the current preset
|
// Initialize the UI from the current preset
|
||||||
void Tab::load_current_preset()
|
void Tab::load_current_preset()
|
||||||
{
|
{
|
||||||
|
@ -2622,12 +2613,7 @@ void Tab::load_current_preset()
|
||||||
// Reload preset pages with the new configuration values.
|
// Reload preset pages with the new configuration values.
|
||||||
reload_config();
|
reload_config();
|
||||||
|
|
||||||
const Preset* selected_preset_parent = m_presets->get_selected_preset_parent();
|
update_ui_items_related_on_parent_preset(m_presets->get_selected_preset_parent());
|
||||||
m_is_default_preset = selected_preset_parent != nullptr && selected_preset_parent->is_default;
|
|
||||||
|
|
||||||
m_bmp_non_system = selected_preset_parent ? &m_bmp_value_unlock : &m_bmp_white_bullet;
|
|
||||||
m_ttg_non_system = selected_preset_parent ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns;
|
|
||||||
m_tt_non_system = selected_preset_parent ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
|
|
||||||
|
|
||||||
// m_undo_to_sys_btn->Enable(!preset.is_default);
|
// m_undo_to_sys_btn->Enable(!preset.is_default);
|
||||||
|
|
||||||
|
@ -2779,7 +2765,7 @@ void Tab::select_preset(std::string preset_name, bool delete_current)
|
||||||
bool printer_tab = m_presets->type() == Preset::TYPE_PRINTER;
|
bool printer_tab = m_presets->type() == Preset::TYPE_PRINTER;
|
||||||
bool canceled = false;
|
bool canceled = false;
|
||||||
bool technology_changed = false;
|
bool technology_changed = false;
|
||||||
m_dependent_tabs = {};
|
m_dependent_tabs.clear();
|
||||||
if (current_dirty && ! may_discard_current_dirty_preset()) {
|
if (current_dirty && ! may_discard_current_dirty_preset()) {
|
||||||
canceled = true;
|
canceled = true;
|
||||||
} else if (print_tab) {
|
} else if (print_tab) {
|
||||||
|
@ -2875,10 +2861,10 @@ void Tab::select_preset(std::string preset_name, bool delete_current)
|
||||||
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
||||||
// The following method should not discard changes of current print or filament presets on change of a printer profile,
|
// The following method should not discard changes of current print or filament presets on change of a printer profile,
|
||||||
// if they are compatible with the current printer.
|
// if they are compatible with the current printer.
|
||||||
auto update_compatible_type = [](bool technology_changed, bool on_page, bool show_incompatible_presets) {
|
auto update_compatible_type = [delete_current](bool technology_changed, bool on_page, bool show_incompatible_presets) {
|
||||||
return technology_changed ? PresetSelectCompatibleType::Always :
|
return (delete_current || technology_changed) ? PresetSelectCompatibleType::Always :
|
||||||
on_page ? PresetSelectCompatibleType::Never :
|
on_page ? PresetSelectCompatibleType::Never :
|
||||||
(show_incompatible_presets ? PresetSelectCompatibleType::OnlyIfWasCompatible : PresetSelectCompatibleType::Always);
|
show_incompatible_presets ? PresetSelectCompatibleType::OnlyIfWasCompatible : PresetSelectCompatibleType::Always;
|
||||||
};
|
};
|
||||||
if (current_dirty || delete_current || print_tab || printer_tab)
|
if (current_dirty || delete_current || print_tab || printer_tab)
|
||||||
m_preset_bundle->update_compatible(
|
m_preset_bundle->update_compatible(
|
||||||
|
@ -3033,18 +3019,20 @@ void Tab::OnKeyDown(wxKeyEvent& event)
|
||||||
// and activates the new preset.
|
// and activates the new preset.
|
||||||
// Wizard calls save_preset with a name "My Settings", otherwise no name is provided and this method
|
// Wizard calls save_preset with a name "My Settings", otherwise no name is provided and this method
|
||||||
// opens a Slic3r::GUI::SavePresetWindow dialog.
|
// opens a Slic3r::GUI::SavePresetWindow dialog.
|
||||||
void Tab::save_preset(std::string name /*= ""*/)
|
void Tab::save_preset(std::string name /*= ""*/, bool detach)
|
||||||
{
|
{
|
||||||
// since buttons(and choices too) don't get focus on Mac, we set focus manually
|
// since buttons(and choices too) don't get focus on Mac, we set focus manually
|
||||||
// to the treectrl so that the EVT_* events are fired for the input field having
|
// to the treectrl so that the EVT_* events are fired for the input field having
|
||||||
// focus currently.is there anything better than this ?
|
// focus currently.is there anything better than this ?
|
||||||
//! m_treectrl->OnSetFocus();
|
//! m_treectrl->OnSetFocus();
|
||||||
|
|
||||||
|
std::string suffix = detach ? _utf8(L("Detached")) : _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName");
|
||||||
|
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
const Preset &preset = m_presets->get_selected_preset();
|
const Preset &preset = m_presets->get_selected_preset();
|
||||||
auto default_name = preset.is_default ? "Untitled" :
|
auto default_name = preset.is_default ? "Untitled" :
|
||||||
// preset.is_system ? (boost::format(_utf8(L("%1% - Copy"))) % preset.name).str() :
|
// preset.is_system ? (boost::format(_CTX_utf8(L_CONTEXT("%1% - Copy", "PresetName"), "PresetName")) % preset.name).str() :
|
||||||
preset.is_system ? (boost::format(_CTX_utf8(L_CONTEXT("%1% - Copy", "PresetName"), "PresetName")) % preset.name).str() :
|
preset.is_system ? (boost::format(("%1% - %2%")) % preset.name % suffix).str() :
|
||||||
preset.name;
|
preset.name;
|
||||||
|
|
||||||
bool have_extention = boost::iends_with(default_name, ".ini");
|
bool have_extention = boost::iends_with(default_name, ".ini");
|
||||||
|
@ -3094,8 +3082,9 @@ void Tab::save_preset(std::string name /*= ""*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
|
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
|
||||||
m_presets->save_current_preset(name);
|
m_presets->save_current_preset(name, detach);
|
||||||
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
||||||
|
// If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible.
|
||||||
m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
|
m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
|
||||||
// Add the new item into the UI component, remove dirty flags and activate the saved item.
|
// Add the new item into the UI component, remove dirty flags and activate the saved item.
|
||||||
update_tab_ui();
|
update_tab_ui();
|
||||||
|
@ -3106,6 +3095,11 @@ void Tab::save_preset(std::string name /*= ""*/)
|
||||||
|
|
||||||
if (m_type == Preset::TYPE_PRINTER)
|
if (m_type == Preset::TYPE_PRINTER)
|
||||||
static_cast<TabPrinter*>(this)->m_initial_extruders_count = static_cast<TabPrinter*>(this)->m_extruders_count;
|
static_cast<TabPrinter*>(this)->m_initial_extruders_count = static_cast<TabPrinter*>(this)->m_extruders_count;
|
||||||
|
|
||||||
|
// Parent preset is "default" after detaching, so we should to update UI values, related on parent preset
|
||||||
|
if (detach)
|
||||||
|
update_ui_items_related_on_parent_preset(m_presets->get_selected_preset_parent());
|
||||||
|
|
||||||
update_changed_ui();
|
update_changed_ui();
|
||||||
|
|
||||||
/* If filament preset is saved for multi-material printer preset,
|
/* If filament preset is saved for multi-material printer preset,
|
||||||
|
@ -3113,6 +3107,30 @@ void Tab::save_preset(std::string name /*= ""*/)
|
||||||
* but in full_config a filament_colors option aren't.*/
|
* but in full_config a filament_colors option aren't.*/
|
||||||
if (m_type == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1)
|
if (m_type == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1)
|
||||||
wxGetApp().plater()->force_filament_colors_update();
|
wxGetApp().plater()->force_filament_colors_update();
|
||||||
|
|
||||||
|
{
|
||||||
|
// Profile compatiblity is updated first when the profile is saved.
|
||||||
|
// Update profile selection combo boxes at the depending tabs to reflect modifications in profile compatibility.
|
||||||
|
std::vector<Preset::Type> dependent;
|
||||||
|
switch (m_type) {
|
||||||
|
case Preset::TYPE_PRINT:
|
||||||
|
dependent = { Preset::TYPE_FILAMENT };
|
||||||
|
break;
|
||||||
|
case Preset::TYPE_SLA_PRINT:
|
||||||
|
dependent = { Preset::TYPE_SLA_MATERIAL };
|
||||||
|
break;
|
||||||
|
case Preset::TYPE_PRINTER:
|
||||||
|
if (static_cast<const TabPrinter*>(this)->m_printer_technology == ptFFF)
|
||||||
|
dependent = { Preset::TYPE_PRINT, Preset::TYPE_FILAMENT };
|
||||||
|
else
|
||||||
|
dependent = { Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL };
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (Preset::Type preset_type : dependent)
|
||||||
|
wxGetApp().get_tab(preset_type)->update_tab_ui();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called for a currently selected preset.
|
// Called for a currently selected preset.
|
||||||
|
@ -3170,6 +3188,15 @@ void Tab::update_ui_from_settings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tab::create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, widget_t widget)
|
||||||
|
{
|
||||||
|
Line line = optgroup->create_single_option_line(opt_key);
|
||||||
|
line.widget = widget;
|
||||||
|
|
||||||
|
m_colored_Labels[opt_key] = nullptr;
|
||||||
|
optgroup->append_line(line, &m_colored_Labels[opt_key]);
|
||||||
|
}
|
||||||
|
|
||||||
// Return a callback to create a Tab widget to mark the preferences as compatible / incompatible to the current printer.
|
// Return a callback to create a Tab widget to mark the preferences as compatible / incompatible to the current printer.
|
||||||
wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &deps)
|
wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &deps)
|
||||||
{
|
{
|
||||||
|
@ -3241,6 +3268,39 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
|
||||||
return sizer;
|
return sizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return a callback to create a TabPrinter widget to edit bed shape
|
||||||
|
wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
|
||||||
|
{
|
||||||
|
ScalableButton* btn;
|
||||||
|
add_scaled_button(parent, &btn, "printer_white", " " + _(L("Set")) + " " + dots, wxBU_LEFT | wxBU_EXACTFIT);
|
||||||
|
btn->SetFont(wxGetApp().normal_font());
|
||||||
|
|
||||||
|
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
sizer->Add(btn);
|
||||||
|
|
||||||
|
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
|
||||||
|
{
|
||||||
|
BedShapeDialog dlg(this);
|
||||||
|
dlg.build_dialog(*m_config->option<ConfigOptionPoints>("bed_shape"),
|
||||||
|
*m_config->option<ConfigOptionString>("bed_custom_texture"),
|
||||||
|
*m_config->option<ConfigOptionString>("bed_custom_model"));
|
||||||
|
if (dlg.ShowModal() == wxID_OK) {
|
||||||
|
const std::vector<Vec2d>& shape = dlg.get_shape();
|
||||||
|
const std::string& custom_texture = dlg.get_custom_texture();
|
||||||
|
const std::string& custom_model = dlg.get_custom_model();
|
||||||
|
if (!shape.empty())
|
||||||
|
{
|
||||||
|
load_key_value("bed_shape", shape);
|
||||||
|
load_key_value("bed_custom_texture", custom_texture);
|
||||||
|
load_key_value("bed_custom_model", custom_model);
|
||||||
|
update_changed_ui();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return sizer;
|
||||||
|
}
|
||||||
|
|
||||||
void Tab::compatible_widget_reload(PresetDependencies &deps)
|
void Tab::compatible_widget_reload(PresetDependencies &deps)
|
||||||
{
|
{
|
||||||
bool has_any = ! m_config->option<ConfigOptionStrings>(deps.key_list)->values.empty();
|
bool has_any = ! m_config->option<ConfigOptionStrings>(deps.key_list)->values.empty();
|
||||||
|
@ -3416,7 +3476,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
|
||||||
void SavePresetWindow::build(const wxString& title, const std::string& default_name, std::vector<std::string> &values)
|
void SavePresetWindow::build(const wxString& title, const std::string& default_name, std::vector<std::string> &values)
|
||||||
{
|
{
|
||||||
// TRN Preset
|
// TRN Preset
|
||||||
auto text = new wxStaticText(this, wxID_ANY, from_u8((boost::format(_utf8(L("Save %s as:"))) % title).str()),
|
auto text = new wxStaticText(this, wxID_ANY, from_u8((boost::format(_utf8(L("Save %s as:"))) % into_u8(title)).str()),
|
||||||
wxDefaultPosition, wxDefaultSize);
|
wxDefaultPosition, wxDefaultSize);
|
||||||
m_combo = new wxComboBox(this, wxID_ANY, from_u8(default_name),
|
m_combo = new wxComboBox(this, wxID_ANY, from_u8(default_name),
|
||||||
wxDefaultPosition, wxDefaultSize, 0, 0, wxTE_PROCESS_ENTER);
|
wxDefaultPosition, wxDefaultSize, 0, 0, wxTE_PROCESS_ENTER);
|
||||||
|
@ -3544,30 +3604,24 @@ void TabSLAMaterial::build()
|
||||||
|
|
||||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||||
Line line = optgroup->create_single_option_line("compatible_printers");
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
|
||||||
return compatible_widget_create(parent, m_compatible_printers);
|
return compatible_widget_create(parent, m_compatible_printers);
|
||||||
};
|
});
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
option = optgroup->get_option("compatible_printers_condition");
|
option = optgroup->get_option("compatible_printers_condition");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
optgroup->append_single_option_line(option);
|
optgroup->append_single_option_line(option);
|
||||||
|
|
||||||
line = optgroup->create_single_option_line("compatible_prints");
|
create_line_with_widget(optgroup.get(), "compatible_prints", [this](wxWindow* parent) {
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return compatible_widget_create(parent, m_compatible_prints);
|
return compatible_widget_create(parent, m_compatible_prints);
|
||||||
};
|
});
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
option = optgroup->get_option("compatible_prints_condition");
|
option = optgroup->get_option("compatible_prints_condition");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
optgroup->append_single_option_line(option);
|
optgroup->append_single_option_line(option);
|
||||||
|
|
||||||
line = Line{ "", "" };
|
build_preset_description_line(optgroup.get());
|
||||||
line.full_width = 1;
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return description_line_widget(parent, &m_parent_preset_description_line);
|
|
||||||
};
|
|
||||||
optgroup->append_line(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
||||||
|
@ -3674,22 +3728,16 @@ void TabSLAPrint::build()
|
||||||
|
|
||||||
page = add_options_page(_(L("Dependencies")), "wrench");
|
page = add_options_page(_(L("Dependencies")), "wrench");
|
||||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||||
Line line = optgroup->create_single_option_line("compatible_printers");//Line { _(L("Compatible printers")), "" };
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
|
||||||
return compatible_widget_create(parent, m_compatible_printers);
|
return compatible_widget_create(parent, m_compatible_printers);
|
||||||
};
|
});
|
||||||
optgroup->append_line(line, &m_colored_Label);
|
|
||||||
|
|
||||||
option = optgroup->get_option("compatible_printers_condition");
|
option = optgroup->get_option("compatible_printers_condition");
|
||||||
option.opt.full_width = true;
|
option.opt.full_width = true;
|
||||||
optgroup->append_single_option_line(option);
|
optgroup->append_single_option_line(option);
|
||||||
|
|
||||||
line = Line{ "", "" };
|
build_preset_description_line(optgroup.get());
|
||||||
line.full_width = 1;
|
|
||||||
line.widget = [this](wxWindow* parent) {
|
|
||||||
return description_line_widget(parent, &m_parent_preset_description_line);
|
|
||||||
};
|
|
||||||
optgroup->append_line(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
||||||
|
|
|
@ -201,7 +201,7 @@ protected:
|
||||||
bool m_disable_tree_sel_changed_event;
|
bool m_disable_tree_sel_changed_event;
|
||||||
bool m_show_incompatible_presets;
|
bool m_show_incompatible_presets;
|
||||||
|
|
||||||
std::vector<Preset::Type> m_dependent_tabs = {};
|
std::vector<Preset::Type> m_dependent_tabs;
|
||||||
enum OptStatus { osSystemValue = 1, osInitValue = 2 };
|
enum OptStatus { osSystemValue = 1, osInitValue = 2 };
|
||||||
std::map<std::string, int> m_options_list;
|
std::map<std::string, int> m_options_list;
|
||||||
int m_opt_status_value = 0;
|
int m_opt_status_value = 0;
|
||||||
|
@ -227,7 +227,12 @@ public:
|
||||||
PresetCollection* m_presets;
|
PresetCollection* m_presets;
|
||||||
DynamicPrintConfig* m_config;
|
DynamicPrintConfig* m_config;
|
||||||
ogStaticText* m_parent_preset_description_line;
|
ogStaticText* m_parent_preset_description_line;
|
||||||
wxStaticText* m_colored_Label = nullptr;
|
ScalableButton* m_detach_preset_btn = nullptr;
|
||||||
|
|
||||||
|
// map of option name -> wxStaticText (colored label, associated with option)
|
||||||
|
// Used for options which don't have corresponded field
|
||||||
|
std::map<std::string, wxStaticText*> m_colored_Labels;
|
||||||
|
|
||||||
// Counter for the updating (because of an update() function can have a recursive behavior):
|
// Counter for the updating (because of an update() function can have a recursive behavior):
|
||||||
// 1. increase value from the very beginning of an update() function
|
// 1. increase value from the very beginning of an update() function
|
||||||
// 2. decrease value at the end of an update() function
|
// 2. decrease value at the end of an update() function
|
||||||
|
@ -253,6 +258,7 @@ public:
|
||||||
const wxString& label = wxEmptyString,
|
const wxString& label = wxEmptyString,
|
||||||
long style = wxBU_EXACTFIT | wxNO_BORDER);
|
long style = wxBU_EXACTFIT | wxNO_BORDER);
|
||||||
void add_scaled_bitmap(wxWindow* parent, ScalableBitmap& btn, const std::string& icon_name);
|
void add_scaled_bitmap(wxWindow* parent, ScalableBitmap& btn, const std::string& icon_name);
|
||||||
|
void update_ui_items_related_on_parent_preset(const Preset* selected_preset_parent);
|
||||||
void load_current_preset();
|
void load_current_preset();
|
||||||
void rebuild_page_tree();
|
void rebuild_page_tree();
|
||||||
void update_page_tree_visibility();
|
void update_page_tree_visibility();
|
||||||
|
@ -264,7 +270,7 @@ public:
|
||||||
void OnTreeSelChange(wxTreeEvent& event);
|
void OnTreeSelChange(wxTreeEvent& event);
|
||||||
void OnKeyDown(wxKeyEvent& event);
|
void OnKeyDown(wxKeyEvent& event);
|
||||||
|
|
||||||
void save_preset(std::string name = "");
|
void save_preset(std::string name = std::string(), bool detach = false);
|
||||||
void delete_preset();
|
void delete_preset();
|
||||||
void toggle_show_hide_incompatible();
|
void toggle_show_hide_incompatible();
|
||||||
void update_show_hide_incompatible_button();
|
void update_show_hide_incompatible_button();
|
||||||
|
@ -306,11 +312,13 @@ public:
|
||||||
void update_wiping_button_visibility();
|
void update_wiping_button_visibility();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, widget_t widget);
|
||||||
wxSizer* compatible_widget_create(wxWindow* parent, PresetDependencies &deps);
|
wxSizer* compatible_widget_create(wxWindow* parent, PresetDependencies &deps);
|
||||||
void compatible_widget_reload(PresetDependencies &deps);
|
void compatible_widget_reload(PresetDependencies &deps);
|
||||||
void load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value = false);
|
void load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value = false);
|
||||||
|
|
||||||
void on_presets_changed();
|
void on_presets_changed();
|
||||||
|
void build_preset_description_line(ConfigOptionsGroup* optgroup);
|
||||||
void update_preset_description_line();
|
void update_preset_description_line();
|
||||||
void update_frequently_changed_parameters();
|
void update_frequently_changed_parameters();
|
||||||
void fill_icon_descriptions();
|
void fill_icon_descriptions();
|
||||||
|
@ -406,6 +414,8 @@ public:
|
||||||
void init_options_list() override;
|
void init_options_list() override;
|
||||||
void msw_rescale() override;
|
void msw_rescale() override;
|
||||||
bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; }
|
bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; }
|
||||||
|
|
||||||
|
wxSizer* create_bed_shape_widget(wxWindow* parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
class TabSLAMaterial : public Tab
|
class TabSLAMaterial : public Tab
|
||||||
|
|
|
@ -29,7 +29,7 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
add_subdirectory(libnest2d)
|
add_subdirectory(libnest2d)
|
||||||
add_subdirectory(libslic3r)
|
add_subdirectory(libslic3r)
|
||||||
add_subdirectory(timeutils)
|
add_subdirectory(slic3rutils)
|
||||||
add_subdirectory(fff_print)
|
add_subdirectory(fff_print)
|
||||||
add_subdirectory(sla_print)
|
add_subdirectory(sla_print)
|
||||||
add_subdirectory(cpp17 EXCLUDE_FROM_ALL) # does not have to be built all the time
|
add_subdirectory(cpp17 EXCLUDE_FROM_ALL) # does not have to be built all the time
|
||||||
|
|
|
@ -13,6 +13,7 @@ add_executable(${_TEST_NAME}_tests
|
||||||
test_stl.cpp
|
test_stl.cpp
|
||||||
test_meshsimplify.cpp
|
test_meshsimplify.cpp
|
||||||
test_meshboolean.cpp
|
test_meshboolean.cpp
|
||||||
|
test_timeutils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (TARGET OpenVDB::openvdb)
|
if (TARGET OpenVDB::openvdb)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <catch_main.hpp>
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
#include "libslic3r/Time.hpp"
|
#include "libslic3r/Time.hpp"
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
namespace {
|
using namespace Slic3r;
|
||||||
|
|
||||||
void test_time_fmt(Slic3r::Utils::TimeFormat fmt) {
|
static void test_time_fmt(Slic3r::Utils::TimeFormat fmt) {
|
||||||
using namespace Slic3r::Utils;
|
using namespace Slic3r::Utils;
|
||||||
time_t t = get_current_time_utc();
|
time_t t = get_current_time_utc();
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ void test_time_fmt(Slic3r::Utils::TimeFormat fmt) {
|
||||||
parsedtime = str2time("not valid string", TimeZone::utc, fmt);
|
parsedtime = str2time("not valid string", TimeZone::utc, fmt);
|
||||||
REQUIRE(parsedtime == time_t(-1));
|
REQUIRE(parsedtime == time_t(-1));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("ISO8601Z", "[Timeutils]") {
|
TEST_CASE("ISO8601Z", "[Timeutils]") {
|
||||||
test_time_fmt(Slic3r::Utils::TimeFormat::iso8601Z);
|
test_time_fmt(Slic3r::Utils::TimeFormat::iso8601Z);
|
|
@ -1,11 +1,10 @@
|
||||||
get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
|
get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
|
||||||
add_executable(${_TEST_NAME}_tests
|
add_executable(${_TEST_NAME}_tests
|
||||||
${_TEST_NAME}_tests_main.cpp
|
${_TEST_NAME}_tests_main.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/libslic3r/Time.cpp
|
|
||||||
${PROJECT_SOURCE_DIR}/src/libslic3r/Time.hpp
|
|
||||||
)
|
)
|
||||||
target_link_libraries(${_TEST_NAME}_tests test_common)
|
|
||||||
|
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r_gui)
|
||||||
set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests")
|
set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests")
|
||||||
|
|
||||||
# catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ")
|
# catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ")
|
||||||
add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS})
|
add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "${CATCH_EXTRA_ARGS} exclude:[NotWorking]")
|
22
tests/slic3rutils/slic3rutils_tests_main.cpp
Normal file
22
tests/slic3rutils/slic3rutils_tests_main.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include <catch_main.hpp>
|
||||||
|
|
||||||
|
#include "slic3r/Utils/Http.hpp"
|
||||||
|
|
||||||
|
TEST_CASE("Http", "[Http][NotWorking]") {
|
||||||
|
|
||||||
|
Slic3r::Http g = Slic3r::Http::get("https://github.com/");
|
||||||
|
|
||||||
|
unsigned status = 0;
|
||||||
|
g.on_error([&status](std::string, std::string, unsigned http_status) {
|
||||||
|
status = http_status;
|
||||||
|
});
|
||||||
|
|
||||||
|
g.on_complete([&status](std::string /* body */, unsigned http_status){
|
||||||
|
status = http_status;
|
||||||
|
});
|
||||||
|
|
||||||
|
g.perform_sync();
|
||||||
|
|
||||||
|
REQUIRE(status == 200);
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
set(SLIC3R_APP_NAME "PrusaSlicer")
|
set(SLIC3R_APP_NAME "PrusaSlicer")
|
||||||
set(SLIC3R_APP_KEY "PrusaSlicer")
|
set(SLIC3R_APP_KEY "PrusaSlicer")
|
||||||
set(SLIC3R_VERSION "2.2.0-rc")
|
set(SLIC3R_VERSION "2.2.0-rc2")
|
||||||
set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN")
|
set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN")
|
||||||
set(SLIC3R_RC_VERSION "2,2,0,0")
|
set(SLIC3R_RC_VERSION "2,2,0,0")
|
||||||
set(SLIC3R_RC_VERSION_DOTS "2.2.0.0")
|
set(SLIC3R_RC_VERSION_DOTS "2.2.0.0")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue