From 1b85cda62682d084ea7bc335713131334955d497 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 4 Mar 2018 11:59:18 +0100 Subject: [PATCH 01/57] Added open logs folder to open folder toolbar dropdown. --- src/mainwindow.cpp | 25 +++++++++++++++++++++---- src/mainwindow.h | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fe93b546..71df8acf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3035,6 +3035,12 @@ void MainWindow::openInstanceFolder() ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.settings().getBaseDirectory()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } +void MainWindow::openLogsFolder() +{ + QString logsPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()); + ::ShellExecuteW(nullptr, L"explore", ToWString(logsPath).c_str(), nullptr, nullptr, SW_SHOWNORMAL); +} + void MainWindow::openInstallFolder() { ::ShellExecuteW(nullptr, L"explore", ToWString(qApp->applicationDirPath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); @@ -3231,6 +3237,11 @@ QMenu *MainWindow::openFolderMenu() QMenu *FolderMenu = new QMenu(this); + FolderMenu->addAction(tr("Open Game folder"), this, SLOT(openGameFolder())); + + FolderMenu->addAction(tr("Open MyGames folder"), this, SLOT(openMyGamesFolder())); + + FolderMenu->addSeparator(); FolderMenu->addAction(tr("Open Instance folder"), this, SLOT(openInstanceFolder())); @@ -3238,13 +3249,19 @@ QMenu *MainWindow::openFolderMenu() FolderMenu->addAction(tr("Open Downloads folder"), this, SLOT(openDownloadsFolder())); - FolderMenu->addAction(tr("Open MO Install folder"), this, SLOT(openInstallFolder())); - FolderMenu->addSeparator(); - FolderMenu->addAction(tr("Open Game folder"), this, SLOT(openGameFolder())); + FolderMenu->addAction(tr("Open MO2 Install folder"), this, SLOT(openInstallFolder())); - FolderMenu->addAction(tr("Open MyGames folder"), this, SLOT(openMyGamesFolder())); + FolderMenu->addAction(tr("Open MO2 Logs folder"), this, SLOT(openLogsFolder())); + + + + + + + + return FolderMenu; diff --git a/src/mainwindow.h b/src/mainwindow.h index 2c2e2723..f84931ca 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -487,6 +487,7 @@ private slots: void disableVisibleMods(); void exportModListCSV(); void openInstanceFolder(); + void openLogsFolder(); void openInstallFolder(); void openDownloadsFolder(); void openProfileFolder(); From a873f7cfe2581716fd908062831d5d5c8f56392f Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 4 Mar 2018 12:52:28 +0100 Subject: [PATCH 02/57] Removed "Repace category" menu option from the modlist as it was redundant and cluttering the menu. --- src/mainwindow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 71df8acf..eb612b6b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3326,10 +3326,13 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) connect(addRemoveCategoriesMenu, SIGNAL(aboutToHide()), this, SLOT(addRemoveCategories_MenuHandler())); addMenuAsPushButton(menu, addRemoveCategoriesMenu); + //Removed as it was redundant, just making the categories look more complicated. + /* QMenu *replaceCategoriesMenu = new QMenu(tr("Replace Categories")); populateMenuCategories(replaceCategoriesMenu, 0); connect(replaceCategoriesMenu, SIGNAL(aboutToHide()), this, SLOT(replaceCategories_MenuHandler())); addMenuAsPushButton(menu, replaceCategoriesMenu); + */ QMenu *primaryCategoryMenu = new QMenu(tr("Primary Category")); connect(primaryCategoryMenu, SIGNAL(aboutToShow()), this, SLOT(addPrimaryCategoryCandidates())); From 7cf0c1a29b463885e37a49691daffb98afdf58db Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 4 Mar 2018 19:12:52 +0100 Subject: [PATCH 03/57] Changed tooltip of Open Folder menu. --- src/mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 31522c03..451e3c87 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -253,7 +253,7 @@ p, li { white-space: pre-wrap; } - Quickly open in Explorer relevant Folders... + Show Open Folders menu... From 513c0629323c066a7b1d5df5ce81f3b9beac85bd Mon Sep 17 00:00:00 2001 From: Al12rs Date: Mon, 5 Mar 2018 15:16:55 +0100 Subject: [PATCH 04/57] Inverted position of reinstall and remove mod, as per user request. --- src/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index eb612b6b..ddd7ef92 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3352,8 +3352,8 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) menu->addSeparator(); menu->addAction(tr("Rename Mod..."), this, SLOT(renameMod_clicked())); - menu->addAction(tr("Remove Mod..."), this, SLOT(removeMod_clicked())); menu->addAction(tr("Reinstall Mod"), this, SLOT(reinstallMod_clicked())); + menu->addAction(tr("Remove Mod..."), this, SLOT(removeMod_clicked())); menu->addSeparator(); From 52501e73c9c205c08b1a8a288c88b5c3362a1381 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 4 Mar 2018 21:05:31 +0100 Subject: [PATCH 05/57] Updated Open Folder icon as it was not very distinguishable. --- src/resources/open-Folder-Icon.png | Bin 17646 -> 16927 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/resources/open-Folder-Icon.png b/src/resources/open-Folder-Icon.png index 345671f754d2e201d4c512c6e0edb140e35b2e20..c363be0fdef80bc854db9df8126941461e394d10 100644 GIT binary patch delta 1604 zcmaFY$vD4-ae@Vt<>QT3X3PS{x&|g8h9*`<=2ixVx(23`8<DUKbJb20n&gjK3H_ zK;b1DLvzjxhIO3Z7?hTCF#Hhv%D{9}iI45ILN?P+0Ye6czn{NJK3d7db#vE0&2J3P zVi*{tq9QguUAEj0q@QK7qpeIm<3A<_2JXKMf4(v@aGZ5nEF{Gp&7tv=k>URj28J)( z3=E(3lRn?kdHvwi0SVDh5)%!$ZG1txL6`+Z{Qu9uz{vQYfraTW0|MAa*_C8?S~C=U?&L4F6dFGO)|MXW%ou$iVhpfPwv4y_Tr(qNu-$jK3Jz!tR0e zf-%@+b`A!H-=DrS+u9rBlkxJ-Rc_*0z#Y&50|Ne^@0en!Qb97Fr0s#^uXNGqh9X&_cy;m zGJgbF|NmO^m;KM@gYTF!dw5*GGcZW-aWVX7Vqkd0_if41Lu!gY`vdQp)!$ggFwB&_vg=fL{o*#KQM6fu`)2Tu`&n>urYk(1Dl61*~!t}-P(FP!{;YI8JJiY z!4m)e{%26sWn{>Ax3)NT*!2HThu;j0{}~y?g#R#1nJ&)oT;Ml@jPz}W^BWWySQt4O zje=k3=DY;3<5ll7#J9CGjQ>IXZZd8Cj%oh6G)Qb$2|rH10x0oBL@}+ zhCg5-1_qWt3~~wr442MuGH_gHVqjo;#~{f6li~1kC5G9%F0NacmjzY`c09}PXABGs zM;Rv1Nn`lSpwGa;_Gz-Ct)#>6-;4|rqQ4o$B>yt}`VI2Re+CAQKMayOLJWm$YE}zt z+djlMR|$X(;o*44@czrXxg1C_T73|~RP z{&%vWvyn2$+>fjbpWc1_s3`sF8d&YaXZ#F2LhKA0iq9B+|NJ{y(aBVWjrA|X<7c7_ z-#&f2t0VgnV)xC5q70T2KNuKtMhX3E@O7@ocO&%pHS+nztaSs?0OycS{*=RLu|@cuKyzn_06JKCD6 zF#rC<@aQ4af0n<0w!MAN3sLy{4+n#sI3L5m52_5me=&o+BF(_S!1|Vv;q5E-Z%UGn zzp=71GJpeIL;2%mM_X5!?;rm>kl=sM!1(_k#1H|lzYLFFNHDy3!v?ZRgq!m(!-YGN z44h0Cj`Q#{F#P_;z%W_gHgfVqTe-;-T&yJ-85sWmkNlnYP1`=h0~BYTu6{1-oD!M< D&V}m- delta 1918 zcmbQ=!uYO}ae@Vt&8Cf3X3PRcx<(cuh9*{qCRV0K+6IP`8<ibDg_)fa(RP0kr0FImr6lVbnI>6Snx!S18>U*==vU+x`1)FTPFCa)nS7r`LnS%U z!onie*jU#vImtrT&@k0P*U}^c47hqQ~Ty9j^l z(;hH~Ztpxdgz5mDX@9RGXUVcsn9!@?6)<5iwD)CD7a*~(C4$BJ5G5lx! z12PnhnZP8&e}>;belz`MU|{(L#lIOC7{2}a%fKkZe*K#;3*XV|hYRnndmeqv)1u+rqJ18#Dd=!N9=4!N|bM z%m$JMW3b7JN)pGcvuoAa`S}QJ{I;**35vB;rmaJ7$}k;Gz$a6`&SPcZk~Sj zkCB;`fe{qm3=B*=K0W!jNR*RFQ&5_L^)DL(D-*Tg-w+w&(8!#y98#4U=^9htjCo|efI)D`Z z|IYyPH`qWXCPoG>v1bgg&Rqc;3^oL$=+}2X1}?sz3~UU?8Gioy&cMjP2r`6`aq>Yc zVeS8a85kJ8K!ORR53KF)zrPGWezG%gaC0&+GJt%>#K6EfInYi|8VX{QL8pfpPLi2V-@xQkI_#hpv8m;0iPP&sQb}79JJ`R@UzfzkmK_U<5fsU+X^u z12Ypd1H-Fd3{t%RFT-8_;|B`^hae*ZBl9-~X2!oDS8sGMmS;9jufXKQlai^aY;%z#jYgn}dOsU5MfTZzhKSeo zDKm#C!{_&RKI*VCGFiR|LZc(rD;fGtSS M)78&qol`;+0P%M`3;+NC From 7c87e9a64556c588a66482ea9acace52c76af7cd Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 4 Mar 2018 19:12:06 +0100 Subject: [PATCH 06/57] Edited "Add/Remove category" menu entry text to "Change Category". --- src/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ddd7ef92..f5be22f0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3321,7 +3321,7 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) { // nop, nothing to do with this mod } else { - QMenu *addRemoveCategoriesMenu = new QMenu(tr("Add/Remove Categories")); + QMenu *addRemoveCategoriesMenu = new QMenu(tr("Change Categories")); populateMenuCategories(addRemoveCategoriesMenu, 0); connect(addRemoveCategoriesMenu, SIGNAL(aboutToHide()), this, SLOT(addRemoveCategories_MenuHandler())); addMenuAsPushButton(menu, addRemoveCategoriesMenu); From 673a5034f0eb9fb12befdbb52ea8dd5d72ac302e Mon Sep 17 00:00:00 2001 From: Al12rs Date: Wed, 7 Mar 2018 13:49:25 +0100 Subject: [PATCH 07/57] Added check for mod rename to ensure the new name is not already used by another mod. --- src/modlist.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modlist.cpp b/src/modlist.cpp index 4002a424..7b2ad1f9 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -424,6 +424,11 @@ bool ModList::renameMod(int index, const QString &newName) return false; } + if (ModList::allMods().contains(newName,Qt::CaseInsensitive)) { + MessageDialog::showMessage(tr("Name is already in use by another mod"), nullptr); + return false; + } + ModInfo::Ptr modInfo = ModInfo::getByIndex(index); QString oldName = modInfo->name(); if (newName != oldName) { From c7f660e061f92901b80558c2bfe7640944fc1840 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Thu, 8 Mar 2018 15:55:24 -0600 Subject: [PATCH 08/57] Remove outdated namespacing and correct the PATH setting to appends dlls --- src/categories.cpp | 2 +- src/categories.h | 2 +- src/main.cpp | 10 +++++----- src/mainwindow.cpp | 10 +++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/categories.cpp b/src/categories.cpp index d8cd49fb..4d89eff9 100644 --- a/src/categories.cpp +++ b/src/categories.cpp @@ -167,7 +167,7 @@ void CategoryFactory::saveCategories() } -unsigned int CategoryFactory::countCategories(std::tr1::function filter) +unsigned int CategoryFactory::countCategories(std::function filter) { unsigned int result = 0; for (const Category &cat : m_Categories) { diff --git a/src/categories.h b/src/categories.h index 66299c30..474a1440 100644 --- a/src/categories.h +++ b/src/categories.h @@ -99,7 +99,7 @@ public: * @param filter the filter to test * @return number of matching categories */ - unsigned int countCategories(std::tr1::function filter); + unsigned int countCategories(std::function filter); /** * @brief get the id of the parent category diff --git a/src/main.cpp b/src/main.cpp index 935b7404..0464ca9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -402,6 +402,8 @@ void setupPath() qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators( QCoreApplication::applicationDirPath()))); + QCoreApplication::setLibraryPaths(QStringList(QCoreApplication::applicationDirPath() + "/dlls") + QCoreApplication::libraryPaths()); + boost::scoped_array oldPath(new TCHAR[BUFSIZE]); DWORD offset = ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), BUFSIZE); if (offset > BUFSIZE) { @@ -409,12 +411,10 @@ void setupPath() ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), offset); } - std::wstring newPath(oldPath.get()); + std::wstring newPath(ToWString(QDir::toNativeSeparators( + QCoreApplication::applicationDirPath())) + L"\\dlls"); newPath += L";"; - newPath += ToWString(QDir::toNativeSeparators( - QCoreApplication::applicationDirPath())) - .c_str(); - newPath += L"\\dlls"; + newPath += oldPath.get(); ::SetEnvironmentVariableW(L"PATH", newPath.c_str()); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f5be22f0..83a12437 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4596,8 +4596,8 @@ void MainWindow::processLOOTOut(const std::string &lootOut, std::string &errorMe std::vector lines; boost::split(lines, lootOut, boost::is_any_of("\r\n")); - std::tr1::regex exRequires("\"([^\"]*)\" requires \"([^\"]*)\", but it is missing\\."); - std::tr1::regex exIncompatible("\"([^\"]*)\" is incompatible with \"([^\"]*)\", but both are present\\."); + std::regex exRequires("\"([^\"]*)\" requires \"([^\"]*)\", but it is missing\\."); + std::regex exIncompatible("\"([^\"]*)\" is incompatible with \"([^\"]*)\", but both are present\\."); for (const std::string &line : lines) { if (line.length() > 0) { @@ -4609,12 +4609,12 @@ void MainWindow::processLOOTOut(const std::string &lootOut, std::string &errorMe qWarning("%s", line.c_str()); errorMessages.append(boost::algorithm::trim_copy(line.substr(erroridx + 8)) + "\n"); } else { - std::tr1::smatch match; - if (std::tr1::regex_match(line, match, exRequires)) { + std::smatch match; + if (std::regex_match(line, match, exRequires)) { std::string modName(match[1].first, match[1].second); std::string dependency(match[2].first, match[2].second); m_OrganizerCore.pluginList()->addInformation(modName.c_str(), tr("depends on missing \"%1\"").arg(dependency.c_str())); - } else if (std::tr1::regex_match(line, match, exIncompatible)) { + } else if (std::regex_match(line, match, exIncompatible)) { std::string modName(match[1].first, match[1].second); std::string dependency(match[2].first, match[2].second); m_OrganizerCore.pluginList()->addInformation(modName.c_str(), tr("incompatible with \"%1\"").arg(dependency.c_str())); From d7e6adb3def695daf56d6243d08845c49b63e197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Fri, 9 Mar 2018 18:25:48 +0100 Subject: [PATCH 09/57] Don't set zlib_root --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 245626aa..9c6351f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,4 @@ LIST(APPEND CMAKE_PREFIX_PATH ${QT_ROOT}/lib/cmake) FILE(GLOB_RECURSE BOOST_ROOT ${DEPENDENCIES_DIR}/boost*/project-config.jam) GET_FILENAME_COMPONENT(BOOST_ROOT ${BOOST_ROOT} DIRECTORY) -SET(ZLIB_ROOT ${DEPENDENCIES_DIR}/zlib) - ADD_SUBDIRECTORY(src) From f7ab05767c88dd04dc60fc3a687ffe6d4328e444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Fri, 9 Mar 2018 18:32:07 +0100 Subject: [PATCH 10/57] Update readme.md --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index fd7f3e53..f7ca93f3 100644 --- a/readme.md +++ b/readme.md @@ -59,7 +59,6 @@ Here is a complete list: * https://github.com/LePresidente/modorganizer-game_oblivion * https://github.com/LePresidente/modorganizer-game_skyrim * https://github.com/LePresidente/modorganizer-game_skyrimSE -* https://github.com/LePresidente/modorganizer-hookdll * https://github.com/LePresidente/modorganizer-installer_bain * https://github.com/LePresidente/modorganizer-installer_bundle * https://github.com/LePresidente/modorganizer-installer_fomod @@ -75,5 +74,8 @@ Here is a complete list: * https://github.com/LePresidente/modorganizer-tool_inibakery * https://github.com/LePresidente/modorganizer-uibase * https://github.com/LePresidente/usvfs + +### Unused Repositories +* https://github.com/LePresidente/modorganizer-hookdll * https://github.com/TanninOne/modorganizer-tool_nmmimport From 9ee2831c59c379e01bd73ced25ce02270dba48df Mon Sep 17 00:00:00 2001 From: LePresidente Date: Sun, 11 Mar 2018 16:21:06 +0200 Subject: [PATCH 11/57] Fix library include for zlibstatic --- src/CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c94aa689..60b36683 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -277,6 +277,7 @@ SET(default_project_path "${CMAKE_SOURCE_DIR}/..") GET_FILENAME_COMPONENT(${default_project_path} ${default_project_path} REALPATH) SET(project_path "${default_project_path}" CACHE PATH "path to the other mo projects") +#TODO this should not be a hardcoded path SET(lib_path "${project_path}/../../install/libs") @@ -289,11 +290,9 @@ INCLUDE_DIRECTORIES(${project_path}/uibase/src ${project_path}/game_features/src ${project_path}/githubpp/src) - INCLUDE_DIRECTORIES(shared ${ZLIB_INCLUDE_DIRS}) LINK_DIRECTORIES(${lib_path} - ${project_path}/../zlib/lib) - + ${ZLIB_ROOT}/lib) EXECUTE_PROCESS( COMMAND git log -1 --format=%h WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} From 0983c88c17ec7d3ca42438d9ae07b6a0def3cf3b Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sun, 11 Mar 2018 23:15:07 +0000 Subject: [PATCH 12/57] Deploy the qtdds.dll as part of the MO install --- src/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60b36683..ab7b4836 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -368,6 +368,9 @@ INSTALL( file(REMOVE_RECURSE ${CMAKE_INSTALL_PREFIX}/bin/qtplugins)" ) +# qdds.dll needs installing manually as Qt no longer ships with it by default. +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../qdds.dll DESTINATION bin/dlls/imageformats) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/stylesheets ${CMAKE_CURRENT_SOURCE_DIR}/tutorials DESTINATION bin) From 8f8beea427af1eb71ba7f7f210279fff70f8d9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Mon, 12 Mar 2018 16:30:45 +0100 Subject: [PATCH 13/57] Updated Repository links --- readme.md | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/readme.md b/readme.md index f7ca93f3..edd3609b 100644 --- a/readme.md +++ b/readme.md @@ -12,7 +12,7 @@ Mod Organizer 2 is an open project in the hands of the community, there are prob To have more information, please join the open MO2 Development discord server :* [ModOrganizerDevs](https://discord.gg/vD2ZbfX) If you want to help translate MO2 to your language you should join the discord server too and head to the #translation channel. -To setup a development environment on your machine, there is the [umbrella project](https://github.com/LePresidente/modorganizer-umbrella) that handles that. +To setup a development environment on your machine, there is the [umbrella project](https://github.com/Modorganizer2/modorganizer-umbrella) that handles that. If you want to submit your code changes, please use a good formating style like the default one in Visual Studio. Through the work of a few people of the community MO2 has come quite far, now it needs some more of those people to go further. @@ -24,7 +24,7 @@ Credits to Tannin, LePresidente, Silarn, erasmux, AL12 and many others for the d ## Download Location -* on [GitHub.com](https://github.com/LePresidente/modorganizer/releases) +* on [GitHub.com](https://github.com/Modorganizer2/modorganizer/releases) * on [NexusMods.com](https://www.nexusmods.com/skyrimspecialedition/mods/6194) ## Old Download Location @@ -33,7 +33,7 @@ Credits to Tannin, LePresidente, Silarn, erasmux, AL12 and many others for the d ## Building -Please refer to [LePresidente/modorganizer-umbrella](https://github.com/LePresidente/modorganizer-umbrella) for build instructions. +Please refer to [LePresidente/modorganizer-umbrella](https://github.com/Modorganizer2/modorganizer-umbrella) for build instructions. ## Other Repositories @@ -41,41 +41,41 @@ MO2 consists of multiple repositories on github. The Umbrella project will downl Here is a complete list: * https://github.com/LePresidente/cpython-1 -* https://github.com/LePresidente/githubpp -* https://github.com/LePresidente/modorganizer -* https://github.com/LePresidente/modorganizer-archive -* https://github.com/LePresidente/modorganizer-bsatk -* https://github.com/LePresidente/modorganizer-bsa_extractor -* https://github.com/LePresidente/modorganizer-check_fnis -* https://github.com/LePresidente/modorganizer-diagnose_basic -* https://github.com/LePresidente/modorganizer-esptk -* https://github.com/LePresidente/modorganizer-helper -* https://github.com/LePresidente/modorganizer-game_fallout3 -* https://github.com/LePresidente/modorganizer-game_fallout4 -* https://github.com/LePresidente/modorganizer-game_fallout4vr -* https://github.com/LePresidente/modorganizer-game_falloutnv -* https://github.com/LePresidente/modorganizer-game_features -* https://github.com/LePresidente/modorganizer-game_gamebryo -* https://github.com/LePresidente/modorganizer-game_oblivion -* https://github.com/LePresidente/modorganizer-game_skyrim -* https://github.com/LePresidente/modorganizer-game_skyrimSE -* https://github.com/LePresidente/modorganizer-installer_bain -* https://github.com/LePresidente/modorganizer-installer_bundle -* https://github.com/LePresidente/modorganizer-installer_fomod -* https://github.com/LePresidente/modorganizer-installer_manual -* https://github.com/LePresidente/modorganizer-installer_ncc -* https://github.com/LePresidente/modorganizer-installer_quick -* https://github.com/LePresidente/modorganizer-lootcli -* https://github.com/LePresidente/modorganizer-NCC -* https://github.com/LePresidente/modorganizer-nxmhandler -* https://github.com/LePresidente/modorganizer-plugin_python -* https://github.com/LePresidente/modorganizer-preview_base -* https://github.com/LePresidente/modorganizer-tool_configurator -* https://github.com/LePresidente/modorganizer-tool_inibakery -* https://github.com/LePresidente/modorganizer-uibase -* https://github.com/LePresidente/usvfs +* https://github.com/Modorganizer2/githubpp +* https://github.com/Modorganizer2/modorganizer +* https://github.com/Modorganizer2/modorganizer-archive +* https://github.com/Modorganizer2/modorganizer-bsatk +* https://github.com/Modorganizer2/modorganizer-bsa_extractor +* https://github.com/Modorganizer2/modorganizer-check_fnis +* https://github.com/Modorganizer2/modorganizer-diagnose_basic +* https://github.com/Modorganizer2/modorganizer-esptk +* https://github.com/Modorganizer2/modorganizer-helper +* https://github.com/Modorganizer2/modorganizer-game_fallout3 +* https://github.com/Modorganizer2/modorganizer-game_fallout4 +* https://github.com/Modorganizer2/modorganizer-game_fallout4vr +* https://github.com/Modorganizer2/modorganizer-game_falloutnv +* https://github.com/Modorganizer2/modorganizer-game_features +* https://github.com/Modorganizer2/modorganizer-game_gamebryo +* https://github.com/Modorganizer2/modorganizer-game_oblivion +* https://github.com/Modorganizer2/modorganizer-game_skyrim +* https://github.com/Modorganizer2/modorganizer-game_skyrimSE +* https://github.com/Modorganizer2/modorganizer-installer_bain +* https://github.com/Modorganizer2/modorganizer-installer_bundle +* https://github.com/Modorganizer2/modorganizer-installer_fomod +* https://github.com/Modorganizer2/modorganizer-installer_manual +* https://github.com/Modorganizer2/modorganizer-installer_ncc +* https://github.com/Modorganizer2/modorganizer-installer_quick +* https://github.com/Modorganizer2/modorganizer-lootcli +* https://github.com/Modorganizer2/modorganizer-NCC +* https://github.com/Modorganizer2/modorganizer-nxmhandler +* https://github.com/Modorganizer2/modorganizer-plugin_python +* https://github.com/Modorganizer2/modorganizer-preview_base +* https://github.com/Modorganizer2/modorganizer-tool_configurator +* https://github.com/Modorganizer2/modorganizer-tool_inibakery +* https://github.com/Modorganizer2/modorganizer-uibase +* https://github.com/Modorganizer2/usvfs ### Unused Repositories -* https://github.com/LePresidente/modorganizer-hookdll +* https://github.com/Modorganizer2/modorganizer-hookdll * https://github.com/TanninOne/modorganizer-tool_nmmimport From 0d4a59fd91a33bf62de6850d654623dd99828f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Mon, 12 Mar 2018 17:10:49 +0100 Subject: [PATCH 14/57] Missed one --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index edd3609b..42a41360 100644 --- a/readme.md +++ b/readme.md @@ -33,7 +33,7 @@ Credits to Tannin, LePresidente, Silarn, erasmux, AL12 and many others for the d ## Building -Please refer to [LePresidente/modorganizer-umbrella](https://github.com/Modorganizer2/modorganizer-umbrella) for build instructions. +Please refer to [Modorganizer2/modorganizer-umbrella](https://github.com/Modorganizer2/modorganizer-umbrella) for build instructions. ## Other Repositories From 9f61ef5c9e6c8884a14b7d6f1507199f61a64377 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Mon, 12 Mar 2018 19:53:43 +0100 Subject: [PATCH 15/57] Added a check to the preview function to handle tha case of the file beeing from the actual data folder instead of a mod. --- src/mainwindow.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 83a12437..bdf79bd5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3929,10 +3929,22 @@ void MainWindow::previewDataFile() // what we have is an absolute path to the file in its actual location (for the primary origin) // what we want is the path relative to the virtual data directory - // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative directory - int offset = m_OrganizerCore.settings().getModDirectory().size() + 1; - offset = fileName.indexOf("/", offset); - fileName = fileName.mid(offset + 1); + // we need to look in the virtual directory for the file to make sure the info is up to date. + + // check if the file comes from the actual data folder instead of a mod + QDir gameDirectory = m_OrganizerCore.managedGame()->dataDirectory().absolutePath(); + QString relativePath = gameDirectory.relativeFilePath(fileName); + if (!relativePath.startsWith("..")) { + fileName = relativePath; + } + else { + // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative directory + int offset = m_OrganizerCore.settings().getModDirectory().size() + 1; + offset = fileName.indexOf("/", offset); + fileName = fileName.mid(offset + 1); + } + + const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), nullptr); From 8305d9215725a49dd9c61c2609fa750a20315af9 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Mon, 12 Mar 2018 12:33:05 +0100 Subject: [PATCH 16/57] Reverted some changes added by Qt configurator that caused some wird stretching of the mainwindow. I suspect this is caused by the fact that the archive tab was not disabled in a way that Configurator liked and it is messing with it. --- src/mainwindow.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 451e3c87..0c0ac6c6 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -176,7 +176,7 @@ 2 - + @@ -463,7 +463,7 @@ p, li { white-space: pre-wrap; } - + From ccb5ad53e22e54f416c4cc3f33c2b57d0b1b672a Mon Sep 17 00:00:00 2001 From: Al12rs Date: Mon, 12 Mar 2018 23:18:03 +0100 Subject: [PATCH 17/57] Fixed wrong Nexus page url in CSV export. --- src/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bdf79bd5..5be5cef3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3201,7 +3201,7 @@ void MainWindow::exportModListCSV() if (nexus_ID->isChecked()) builder.setRowField("#Nexus_ID", info->getNexusID()); if (mod_Nexus_URL->isChecked()) - builder.setRowField("#Mod_Nexus_URL", info->getURL()); + builder.setRowField("#Mod_Nexus_URL",(info->getNexusID()>0)? NexusInterface::instance()->getModURL(info->getNexusID()) : ""); if (mod_Version->isChecked()) builder.setRowField("#Mod_Version", info->getVersion().canonicalString()); if (install_Date->isChecked()) From 8dee1d108b4098a587f3a827c187b3c9c2559d12 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Thu, 15 Mar 2018 15:21:37 +0100 Subject: [PATCH 18/57] Fixed default size and positioning of some ui elements to accomodate the new ones. Fixed incorrect settings for the layout stretching. --- src/mainwindow.ui | 61 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 0c0ac6c6..e0aa6f36 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -176,7 +176,7 @@ 2 - + @@ -194,7 +194,7 @@ - + Pick a module collection @@ -463,7 +463,7 @@ p, li { white-space: pre-wrap; } - + @@ -507,15 +507,25 @@ p, li { white-space: pre-wrap; } true - - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + - + 0 0 @@ -523,9 +533,15 @@ p, li { white-space: pre-wrap; } 0 - 25 + 22 + + + 95 + 0 + + false @@ -551,7 +567,26 @@ p, li { white-space: pre-wrap; } - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 220 + 0 + + Qt::ClickFocus @@ -573,7 +608,13 @@ p, li { white-space: pre-wrap; } - + + + + 220 + 0 + + Namefilter From 2fa1b04cd430315f3abf45dcdd4975c0117ac98a Mon Sep 17 00:00:00 2001 From: Al12rs Date: Fri, 16 Mar 2018 18:02:57 +0100 Subject: [PATCH 19/57] Various text and ui changes: Added description to CSV export. Added line to delete instance error message. Changed delete instance icon for the list of instances. Added red X in the resources, thanks to twizz0r. --- src/instancemanager.cpp | 4 ++-- src/mainwindow.cpp | 4 ++++ src/resources.qrc | 1 + src/resources/multiply-red.png | Bin 0 -> 16018 bytes 4 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 src/resources/multiply-red.png diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp index d12ec119..43ae152b 100644 --- a/src/instancemanager.cpp +++ b/src/instancemanager.cpp @@ -105,7 +105,7 @@ QString InstanceManager::manageInstances(const QStringList &instanceList) const nullptr); for (const QString &instance : instanceList) { - selection.addChoice(instance, "", instance); + selection.addChoice(QIcon(":/MO/gui/multiply_red"), instance, "", instance); } if (selection.exec() == QDialog::Rejected) { @@ -120,7 +120,7 @@ QString InstanceManager::manageInstances(const QStringList &instanceList) const if (!deleteLocalInstance(choice)) { QMessageBox::warning(nullptr, QObject::tr("Failed to delete Instance"), - QObject::tr("Could not delete Instance \"%1\"").arg(choice), QMessageBox::Ok); + QObject::tr("Could not delete Instance \"%1\". \nIf the folder was still in use, restart MO and try again.").arg(choice), QMessageBox::Ok); } } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5be5cef3..2bf25b05 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3079,6 +3079,10 @@ void MainWindow::exportModListCSV() QGridLayout *grid = new QGridLayout; selection.setWindowTitle(tr("Export to csv")); + QLabel *csvDescription = new QLabel(); + csvDescription->setText(tr("CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet.\nYou can also use online editors and converters instead.")); + grid->addWidget(csvDescription); + QGroupBox *groupBoxRows = new QGroupBox(tr("Select what mods you want export:")); QRadioButton *all = new QRadioButton(tr("All installed mods")); QRadioButton *active = new QRadioButton(tr("Only active (checked) mods from your current profile")); diff --git a/src/resources.qrc b/src/resources.qrc index 618d3cfc..1cfc58a3 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -72,6 +72,7 @@ resources/package.png resources/switch-instance-icon.png resources/open-Folder-Icon.png + resources/multiply-red.png resources/contents/jigsaw-piece.png diff --git a/src/resources/multiply-red.png b/src/resources/multiply-red.png new file mode 100644 index 0000000000000000000000000000000000000000..c238f07f5f2e8e854bb308356770d79cf728a5ae GIT binary patch literal 16018 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7I14-?iy0WWg+Z8+Vb&Z8 z1_sMFnIRD+5xzcF$@#f@i7EL>sd^Q;1q>iyV_#8_n4FzjqL7rDo|$K>^nUk#C56ls zTcvPQUjyF)=hTc$kE){7;3~h6MhJ1(0FtBTx$+|-gpg^Jvqyke^gTP3i$ zR(Zu%AYpwa1+bEmY+EHqkcA2nz5xo(`9-M;rg~<&$%e)j3g(u2hNhMlMkYE6Mh1pv z`UaNzh9_{ffi_eM3D1eQcUilHqy^N{e#9PD@GFPt8fq zP0cGQ);H8M#Hz0#BfliSI3pj2m2hdC7FXmJ`1-=_#_HbOT&z|Xm$;Ud;MZ9kQdy9y zACy|0Us{x$>ROhXSE7u~_a&KWh{!>414ss^+fyqtacBd{K(v9A0wjiPDsl^~oQqNu zOY)0C^7C`-AgL?>7K94U&Y)CfuAmW~nU|7ZUaV=OkFEs~-w4xET@p)D?TiczEp!cx zbq&oz3@oiojjfE0bPY_b3=EJAfv7|?!#6)AGp!Pv875Z7rpRU>sYEv;wInemu_Tcw zQ;^jnnUj)im6l(Wn^iE z3tdZN^Az1=LlYx&3xia{L<Ap6e}b1R0Fd#14~_F zOVc!6Gjo$PUCU$(3*97R^JI%8Lo?$PLsOU)Sd782$|JM5B)_NrJF&R|0*(HOrM{0_VK8h&9Sr9!Ss~`$8 zF{6{XAi&U$+m7;#)I5CI3t|*l6>dX{^V3So6N^$E(^K`iDi^U197hs=)z_R>~olP!OZQs&E^E8lFTHzz|bWwc$2CIU_MI zJvGHnAC`b&0_a+>#~efyHD|$cD`rl#0aZ>`{zaLoc_oS9++%2?k0FMz8KOP{lpAwO z!RpP83=9km^bJ8IR4cMHy4FbiT9KvEwIXze=4F=H89{AB6GqYnszD*edvHNwa;lw~ zsj0E4jXt_Cx{iR%iqxD4m(1MMyyDFKJUc@(s2+3)tQsS6X+)BMYJ@};QnL)42O*+C zE^c;QHu~V!B&cNxmV%dDv|>OVMl0hX=8jqd2?rv{(cmI7pdiXdg9{Q4M3SSyMPxuh zl#K=#Bpiq&M}v#VfPyF+4K7GH5J`>(7m)!4Q8pS}kZ>T991Sia0}7&SG`Jw)KqNUD zTto&GMA>L?LBfGZax}Pz3@C`Q(cprF1Ciuta1j|$5M`sm1qlZt$NOCl|hzux*veDpzgaeV}XmAl3P!MIK!37BiBFWL< zA~K*L%0`0=5)MR?qrpXFKtYs^1{Wk8h$KgYi^zb2C>sqfNH`El;teh?#1_ufycAod zawU7arQ0VQV_;xVNcITwWnidMWngG%W?=aFpMjy_B?CjL0RzLU1O^7H84L{K`IF+0 zx-l@YD0sR!hEy;z2(Y~W&G`TSf6(SovM~!-XRIrTYG7bssAphcaAaU$H~3uu zm_WAt`SYh9B*F0eHv@?N^XJe0UtxA24IpU-5E~>0l0#AhHUu07-vcc{iuZGRfW5-N zz{Ab(ea!}tW{`J4^nT8e00xFHUqNh!?>lybXh+WV#}9yA@cY-V1HXU$a{RPuD+9xi z9}Em{-ZFqR{QmW8KL~@^ATf{}NDW9WNDs&qunXR~>M{uJzRd8>RTu0MA+UED7#QSa zKx!Bm9z6lm?;yeAD75?X0hk_$3x56tD*#FS{`u4K<@TKn4Bx&nFxZ#Rc~bB^`eM{JCEyHROkRhI~elF{r5}E* Date: Sat, 17 Mar 2018 00:58:55 +0100 Subject: [PATCH 20/57] Added archive-conflict icons to resources. --- src/resources.qrc | 4 ++++ src/resources/archive-conflict-loser.png | Bin 0 -> 18052 bytes src/resources/archive-conflict-mixed.png | Bin 0 -> 18052 bytes src/resources/archive-conflict-neutral.png | Bin 0 -> 18052 bytes src/resources/archive-conflict-winner.png | Bin 0 -> 18052 bytes 5 files changed, 4 insertions(+) create mode 100644 src/resources/archive-conflict-loser.png create mode 100644 src/resources/archive-conflict-mixed.png create mode 100644 src/resources/archive-conflict-neutral.png create mode 100644 src/resources/archive-conflict-winner.png diff --git a/src/resources.qrc b/src/resources.qrc index 1cfc58a3..0197b606 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -73,6 +73,10 @@ resources/switch-instance-icon.png resources/open-Folder-Icon.png resources/multiply-red.png + resources/archive-conflict-looser.png + resources/archive-conflict-mixed.png + resources/archive-conflict-neutral.png + resources/archive-conflict-winner.png resources/contents/jigsaw-piece.png diff --git a/src/resources/archive-conflict-loser.png b/src/resources/archive-conflict-loser.png new file mode 100644 index 0000000000000000000000000000000000000000..77d2e0fafb987ca139f7fad3cb6ad767fe2ea4f0 GIT binary patch literal 18052 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 Wb!YEZU6|7dGSt)6&t;ucLK6Tg7d`_3 literal 0 HcmV?d00001 diff --git a/src/resources/archive-conflict-winner.png b/src/resources/archive-conflict-winner.png new file mode 100644 index 0000000000000000000000000000000000000000..f62605753eec260bd9438279c8bdeeb6ffba54fa GIT binary patch literal 18052 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7I14-?iy0WWg+Z8+Vb&Z8 z1_sA_nIRD+5xzcF$@#f@i7EL>sd^Q;1q>iyV_#8_n4FzjqL7rDo|$K>^nUk#C56ls zTcvPQUjyF)=hTc$kE){7;3~h6MhJ1(0FtBTx$+|-gpg^Jvqyke^gTP3i$ zR(Zu%AYpwa1+bEmY+EHqkcA2nz5xo(`9-M;rg~<&$%e)j3g(u2hNhMlMkYE6Mh1pv z`UaNzh9_{ffi_eM3D1eQcUilHqy^N{e#9PD@GFPt8fq zP0cGQ);H8M#Hz0#BfliSI3pj2m2hdC7FXmJ`1-=_#_HbOT&z|Xm$;Ud;MZ9kQdy9y zACy|0Us{x$>ROhXSE7u~_r)basfgIY>IhV$f>P748dQ>*hQl0?49-AEt;oco4I~56 z22N9usJ5xdEwFMfN=+=uFAB-e&#{9f*8o^tC^$QVlBccGcvO>x#LN`7)?iWMS!4J=a(Eews4bd4-c zOmqzmQ!R8Yjm=YZlMPLb%qspwmCF>?786{d;BpRm~TNuKuz+w!BRUVn3n65;N22k7trxv1$B4Qd` zW)~zD6{mtqBwHm|kpwT~AsHJ&+JH+otHfkbX>XSd%IB#mHu@-{2xmd`fUJTj$i$3J zQ=){)@Rbt~qrj?g8&aH~R#Ki=lI7v5c~4u(UKxu}rZ{)ip9QOVu?^Hc8Y?GEXwrH8VFzGEX!~H8wCyghew_ zETVf6#*7WPS7n71>YyeWsCh|jaT=7GhO8YW zFG5XEfwsVLwlIw?EsRY}Q!I6jEG*L?EzBfCOEcXx3j-4~BNKy^l;l)U(G9W-$uMko z_d!ouPS|C3Z$o+t7rObb-3MkbYQjL1J>Motder zv8jzdx-hzqfXs^2oCuf9+|<0{%=|n%Lo=uzbP22)BXMa&l7MQ2WE-S`7;wZuM1x%1 z?6_?7!Q)4uu_Uk*B)8F!ggT6dHYg}4j9Nlc_>KnGXmF7f0wgIOOTqK16Ns32P*JyB&6apkE9!*`N!9`LCkfeAtb&UoWNg+Uz;?dMK z8eAlW07;5RQ`cy4krV}Hl z;pq~;|I&(o7+yVOWVm_fJxGjk?V*nhV#2HpOpFW+P-P62D=&cL;Ftx>+UEXW+Leoe z;VlD$m^34Un2r#`n@fNG2ZJRU7}p;8#2_ie!T_-fA_yayHl*qQXE5SoV0iG8f#K61 z28I{E85sWkXArUFV6Y7oVz4#h{%>Jr_y6YOpA7Fm|AXm+(~SR*d;Mn+W?^7>^P7Qz z2`!>iv6$M^qXICq3=BuTFnq!E{wF8H+5LL-RiHRY3_D!&^AHV*812L{%y~+)unHcz(85myvVqlPF zWe|Or&!EUYlR@2(nSq6!mqAQel)>2K2ZO%XACOuGp0t+?R`sty=aGQbUnjtP)BX37AG zLNP3=KwOZY1z8ywL_vYgz`y{L!)pLYBQm~q`xnFgyC4xB5CO*EoZi;-Vfo*9+gBhF MPgg&ebxsLQ0Abc&*Z=?k literal 0 HcmV?d00001 From 90165b02ab8686015d41c1fee79e5c6314a65357 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sat, 17 Mar 2018 01:08:02 +0100 Subject: [PATCH 21/57] Disabled iniTweaks part of modinfodialog until it is not fixed. --- src/modinfodialog.ui | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 25822fd0..b5331424 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -110,13 +110,19 @@ + + false + - Ini Tweaks + Ini Tweaks *This feature is non-functional* + + false + 228 From 2def87a143cae7521bc8da898fddda73f213d473 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sat, 17 Mar 2018 12:42:15 +0100 Subject: [PATCH 22/57] Fixed a typo of the added resource. --- src/resources.qrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources.qrc b/src/resources.qrc index 0197b606..1c7c92e1 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -73,7 +73,7 @@ resources/switch-instance-icon.png resources/open-Folder-Icon.png resources/multiply-red.png - resources/archive-conflict-looser.png + resources/archive-conflict-loser.png resources/archive-conflict-mixed.png resources/archive-conflict-neutral.png resources/archive-conflict-winner.png From bbce6506cdf15b5965e12ca2b10063fa8d3b85c0 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sat, 17 Mar 2018 14:41:43 +0100 Subject: [PATCH 23/57] Fixed another typo in the same resource --- src/resources.qrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources.qrc b/src/resources.qrc index 1c7c92e1..14c8e533 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -73,7 +73,7 @@ resources/switch-instance-icon.png resources/open-Folder-Icon.png resources/multiply-red.png - resources/archive-conflict-loser.png + resources/archive-conflict-loser.png resources/archive-conflict-mixed.png resources/archive-conflict-neutral.png resources/archive-conflict-winner.png From 336216ba9a7e07aad972708c862c1e7306f1c67d Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 20 Mar 2018 01:29:31 -0500 Subject: [PATCH 24/57] Various save game improvements related to script extender files * Improve handling of SE save transfers and deletes with main save * Add indicator in save popup dialog if SE save file is present --- src/mainwindow.cpp | 12 ++++++++---- src/transfersavesdialog.cpp | 30 ++++++++++-------------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2bf25b05..8bb40072 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4667,9 +4667,13 @@ void MainWindow::on_bossButton_clicked() QStringList parameters; parameters << "--game" << m_OrganizerCore.managedGame()->gameShortName() - << "--gamePath" << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath()) - << "--pluginListPath" << QString("\"%1/loadorder.txt\"").arg(m_OrganizerCore.profilePath()) - << "--out" << QString("\"%1\"").arg(outPath); + << "--gamePath" << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath()) + << "--out" << QString("\"%1\"").arg(outPath); + + if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) + parameters << "--pluginListPath" << QString("\"%1/loadorder.txt\"").arg(m_OrganizerCore.profilePath()); + else + parameters << "--pluginListPath" << QString("\"%1/plugins.txt\"").arg(m_OrganizerCore.profilePath()); if (m_DidUpdateMasterList) { parameters << "--skipUpdateMasterlist"; @@ -4802,7 +4806,7 @@ void MainWindow::on_bossButton_clicked() // if the game specifies load order by file time, our own load order file needs to be removed because it's outdated. // refreshESPList will then use the file time as the load order. - if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) { + if (m_OrganizerCore.managedGame()->loadOrderMechanism() != IPluginGame::LoadOrderMechanism::FileTime) { qDebug("removing loadorder.txt"); QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName()); } diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index b8dda056..61dab6e5 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -74,6 +74,11 @@ public: return { m_File }; } + virtual bool hasScriptExtenderFile() const override + { + return false; + } + private: QString m_File; }; @@ -95,6 +100,11 @@ public: { return nullptr; } + + virtual bool hasScriptExtenderSave(QString const &file) const override + { + return false; + } }; } //end anonymous namespace @@ -334,26 +344,6 @@ bool TransferSavesDialog::transferCharacters( sourceFile.absoluteFilePath().toUtf8().constData(), destinationFile.toUtf8().constData()); } - - QFileInfo sourceFileSE(sourceFile.absolutePath() + "/" + sourceFile.completeBaseName() + "." + m_GamePlugin->savegameSEExtension()); - if (sourceFileSE.exists()) { - QString destinationFileSE(destination.absoluteFilePath(sourceFileSE.fileName())); - - //If the file is already there, let them skip (or not). - if (QFile::exists(destinationFileSE)) { - if (!testOverwrite(overwriteMode, destinationFileSE)) { - continue; - } - //OK, they want to remove it. - QFile::remove(destinationFileSE); - } - - if (!method(sourceFileSE.absoluteFilePath(), destinationFileSE)) { - qCritical(errmsg, - sourceFileSE.absoluteFilePath().toUtf8().constData(), - destinationFileSE.toUtf8().constData()); - } - } } } return true; From 0c792d548f44f71cdd358b5811f5ed06196430d9 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 20 Mar 2018 17:10:35 -0500 Subject: [PATCH 25/57] Fix lootcli destroying loadorder on newer games --- src/mainwindow.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8bb40072..e562b2f2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4668,13 +4668,9 @@ void MainWindow::on_bossButton_clicked() QStringList parameters; parameters << "--game" << m_OrganizerCore.managedGame()->gameShortName() << "--gamePath" << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath()) + << "--pluginListPath" << QString("\"%1/loadorder.txt\"").arg(m_OrganizerCore.profilePath()) << "--out" << QString("\"%1\"").arg(outPath); - if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) - parameters << "--pluginListPath" << QString("\"%1/loadorder.txt\"").arg(m_OrganizerCore.profilePath()); - else - parameters << "--pluginListPath" << QString("\"%1/plugins.txt\"").arg(m_OrganizerCore.profilePath()); - if (m_DidUpdateMasterList) { parameters << "--skipUpdateMasterlist"; } @@ -4793,7 +4789,7 @@ void MainWindow::on_bossButton_clicked() if (success) { m_DidUpdateMasterList = true; - /*if (reportURL.length() > 0) { + if (reportURL.length() > 0) { m_IntegratedBrowser.setWindowTitle("LOOT Report"); QString report(reportURL.c_str()); QStringList temp = report.split("?"); @@ -4802,13 +4798,6 @@ void MainWindow::on_bossButton_clicked() url.setQuery(temp.at(1).toUtf8()); } m_IntegratedBrowser.openUrl(url); - }*/ - - // if the game specifies load order by file time, our own load order file needs to be removed because it's outdated. - // refreshESPList will then use the file time as the load order. - if (m_OrganizerCore.managedGame()->loadOrderMechanism() != IPluginGame::LoadOrderMechanism::FileTime) { - qDebug("removing loadorder.txt"); - QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName()); } m_OrganizerCore.refreshESPList(); m_OrganizerCore.savePluginList(); From 192b0bafa5ade0e8f9f36fe8ce0f1de137d72e3a Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 20 Mar 2018 17:11:00 -0500 Subject: [PATCH 26/57] Update about dialogue and licenses --- src/aboutdialog.cpp | 40 +++++++++++++++++----- src/aboutdialog.h | 15 +++++++-- src/aboutdialog.ui | 82 +++++++++++++++++++++++++++++++++------------ 3 files changed, 105 insertions(+), 32 deletions(-) diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index ed57a217..411ef1cf 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -29,7 +29,7 @@ along with Mod Organizer. If not, see . #include #include #include - +#include AboutDialog::AboutDialog(const QString &version, QWidget *parent) : QDialog(parent) @@ -37,24 +37,44 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) { ui->setupUi(this); - m_LicenseFiles[LICENSE_LGPL3] = "lgpl-3.0.txt"; - m_LicenseFiles[LICENSE_GPL3] = "gpl-3.0.txt"; - m_LicenseFiles[LICENSE_BSD3] = "bsd3.txt"; + m_LicenseFiles[LICENSE_LGPL3] = "LGPL-v3.0.txt"; + m_LicenseFiles[LICENSE_LGPL21] = "GNU-LGPL-v2.1.txt"; + m_LicenseFiles[LICENSE_GPL3] = "GPL-v3.0.txt"; + m_LicenseFiles[LICENSE_GPL2] = "GPL-v2.0.txt"; m_LicenseFiles[LICENSE_BOOST] = "boost.txt"; + m_LicenseFiles[LICENSE_7ZIP] = "7zip.txt"; m_LicenseFiles[LICENSE_CCBY3] = "by-sa3.txt"; m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt"; - m_LicenseFiles[LICENSE_APACHE2] = "apache-license-2.0.txt"; + m_LicenseFiles[LICENSE_PYTHON] = "python.txt"; + m_LicenseFiles[LICENSE_SSL] = "openssl.txt"; + m_LicenseFiles[LICENSE_CPPTOML] = "cpptoml.txt"; + m_LicenseFiles[LICENSE_UDIS] = "udis86.txt"; + m_LicenseFiles[LICENSE_SPDLOG] = "spdlog.txt"; + m_LicenseFiles[LICENSE_FMT] = "fmt.txt"; + m_LicenseFiles[LICENSE_SIP] = "sip.txt"; + m_LicenseFiles[LICENSE_CASTLE] = "Castle.txt"; + m_LicenseFiles[LICENSE_ANTLR] = "AntlrBuildTask.txt"; + m_LicenseFiles[LICENSE_WIX] = "WixToolkit.txt"; addLicense("Qt", LICENSE_LGPL3); addLicense("Qt Json", LICENSE_GPL3); addLicense("Boost Library", LICENSE_BOOST); - addLicense("7-zip", LICENSE_LGPL3); - addLicense("ZLib", LICENSE_ZLIB); + addLicense("7-zip", LICENSE_7ZIP); + addLicense("ZLib", LICENSE_NONE); addLicense("Tango Icon Theme", LICENSE_NONE); addLicense("RRZE Icon Set", LICENSE_CCBY3); addLicense("Icons by Lorc, Delapouite and sbed available on http://game-icons.net", LICENSE_CCBY3); - addLicense("Castle Core", LICENSE_APACHE2); + addLicense("Castle Core", LICENSE_CASTLE); + addLicense("ANTLR", LICENSE_ANTLR); addLicense("LOOT", LICENSE_GPL3); + addLicense("Python", LICENSE_PYTHON); + addLicense("OpenSSL", LICENSE_SSL); + addLicense("cpptoml", LICENSE_CPPTOML); + addLicense("Udis86", LICENSE_UDIS); + addLicense("spdlog", LICENSE_SPDLOG); + addLicense("{fmt}", LICENSE_FMT); + addLicense("SIP", LICENSE_SIP); + addLicense("WiX Toolset", LICENSE_WIX); ui->nameLabel->setText(QString("%1 %2").arg(ui->nameLabel->text()).arg(version)); #if defined(HGID) @@ -64,6 +84,8 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) #else ui->revisionLabel->setText(ui->revisionLabel->text() + " unknown"); #endif + + ui->licenseText->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); } @@ -85,7 +107,7 @@ void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem *current, QL { auto iter = m_LicenseFiles.find(current->data(Qt::UserRole).toInt()); if (iter != m_LicenseFiles.end()) { - QString filePath = qApp->applicationDirPath() + "/license/" + iter->second; + QString filePath = qApp->applicationDirPath() + "/licenses/" + iter->second; QString text = MOBase::readFileText(filePath); ui->licenseText->setText(text); } else { diff --git a/src/aboutdialog.h b/src/aboutdialog.h index 103a0d2f..adf8d2c7 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -45,12 +45,23 @@ private: enum Licenses { LICENSE_NONE, LICENSE_LGPL3, + LICENSE_LGPL21, LICENSE_GPL3, - LICENSE_BSD3, + LICENSE_GPL2, LICENSE_BOOST, LICENSE_CCBY3, + LICENSE_PYTHON, + LICENSE_SSL, + LICENSE_CPPTOML, + LICENSE_7ZIP, LICENSE_ZLIB, - LICENSE_APACHE2 + LICENSE_UDIS, + LICENSE_SPDLOG, + LICENSE_FMT, + LICENSE_SIP, + LICENSE_CASTLE, + LICENSE_ANTLR, + LICENSE_WIX }; private: diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui index 50a9de5f..348a33b0 100644 --- a/src/aboutdialog.ui +++ b/src/aboutdialog.ui @@ -120,14 +120,14 @@ - Copyright 2011-2016 Sebastian Herbord + <html><head/><body><p>Copyright 2011-2016 Sebastian Herbord</p><p>Copyright 2016-2018 Mod Organizer 2 contributors</p></body></html> - <html><head/><body><p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p><p>See the GNU General Public License for more details.</p><p>Source code can be found at <a href="https://github.com/TanninOne/modorganizer"><span style=" text-decoration: underline; color:#007af4;">GitHub</span></a>.</p></body></html> + <html><head/><body><p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p><p>See the GNU General Public License for more details.</p><p>Source code can be found at <a href="https://github.com/Modorganizer2/modorganizer"><span style=" text-decoration: underline; color:#007af4;">GitHub</span></a>.</p></body></html> true @@ -154,7 +154,7 @@ Thanks - + Current Maintainers @@ -167,12 +167,17 @@ - LePresidente + LePresidente (Project Lead) - Silarn + AL12 + + + + + Diana @@ -182,7 +187,7 @@ - Diana + Silarn @@ -203,17 +208,22 @@ - pndrev (German) + Scythe1912 (Chinese) - DaWul (Spanish) + yc0620shen (Chinese) - Fiama (Spanish) + miraclefreak (Czech) + + + + + Cyb3r (Dutch) @@ -233,22 +243,17 @@ - Scythe1912 (Chinese) + Faron (German) - yc0620shen (Chinese) + pndrev (German) - miraclefreak (Czech) - - - - - tokcdk (Russian) + Mordan (Greek) @@ -261,7 +266,37 @@ - ... more (Can't track) + Yoosk (Polish) + + + + + Brgodfx (Portuguese) + + + + + tokcdk (Russian) + + + + + DaWul (Spanish) + + + + + Fiama (Spanish) + + + + + Jax (Swedish) + + + + + ...and all other Transifex contributors! @@ -275,7 +310,7 @@ - Other Supporter + Other Supporters && Contributors @@ -283,9 +318,14 @@ QAbstractItemView::NoSelection - + - Al12 (Discord) + SuperSandro2000 + + + + + AnyOldName3 From 149ce846b52689b70781bf7716a4b480862bc402 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 20 Mar 2018 17:12:25 -0500 Subject: [PATCH 27/57] Installer license not needed for application --- src/aboutdialog.cpp | 2 -- src/aboutdialog.h | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index 411ef1cf..9b909ccb 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -54,7 +54,6 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) m_LicenseFiles[LICENSE_SIP] = "sip.txt"; m_LicenseFiles[LICENSE_CASTLE] = "Castle.txt"; m_LicenseFiles[LICENSE_ANTLR] = "AntlrBuildTask.txt"; - m_LicenseFiles[LICENSE_WIX] = "WixToolkit.txt"; addLicense("Qt", LICENSE_LGPL3); addLicense("Qt Json", LICENSE_GPL3); @@ -74,7 +73,6 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) addLicense("spdlog", LICENSE_SPDLOG); addLicense("{fmt}", LICENSE_FMT); addLicense("SIP", LICENSE_SIP); - addLicense("WiX Toolset", LICENSE_WIX); ui->nameLabel->setText(QString("%1 %2").arg(ui->nameLabel->text()).arg(version)); #if defined(HGID) diff --git a/src/aboutdialog.h b/src/aboutdialog.h index adf8d2c7..a67c9c73 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -60,8 +60,7 @@ private: LICENSE_FMT, LICENSE_SIP, LICENSE_CASTLE, - LICENSE_ANTLR, - LICENSE_WIX + LICENSE_ANTLR }; private: From bcc4c8d6aaab9ca4a641f7fa6b71a9f927d9bb52 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 20 Mar 2018 17:18:57 -0500 Subject: [PATCH 28/57] Update BY SA v3 license file to match others --- src/aboutdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index 9b909ccb..5ac05df7 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -43,7 +43,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) m_LicenseFiles[LICENSE_GPL2] = "GPL-v2.0.txt"; m_LicenseFiles[LICENSE_BOOST] = "boost.txt"; m_LicenseFiles[LICENSE_7ZIP] = "7zip.txt"; - m_LicenseFiles[LICENSE_CCBY3] = "by-sa3.txt"; + m_LicenseFiles[LICENSE_CCBY3] = "BY-SA-v3.0.txt"; m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt"; m_LicenseFiles[LICENSE_PYTHON] = "python.txt"; m_LicenseFiles[LICENSE_SSL] = "openssl.txt"; From 92a8a3dce863c80f540537162e7c7e415cdfd57d Mon Sep 17 00:00:00 2001 From: Al12rs Date: Wed, 21 Mar 2018 00:12:39 +0100 Subject: [PATCH 29/57] Fixed preview "file not found" error if the mod folder containing the file was on a different drive. --- src/mainwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2bf25b05..f38ddf15 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3938,7 +3938,9 @@ void MainWindow::previewDataFile() // check if the file comes from the actual data folder instead of a mod QDir gameDirectory = m_OrganizerCore.managedGame()->dataDirectory().absolutePath(); QString relativePath = gameDirectory.relativeFilePath(fileName); - if (!relativePath.startsWith("..")) { + QDir direRelativePath = gameDirectory.relativeFilePath(fileName); + // if the file is on a different drive the dirRelativePath will actually be an absolute path so we make sure that is not the case + if (!direRelativePath.isAbsolute() && !relativePath.startsWith("..")) { fileName = relativePath; } else { From 82d4742e2814755a4aa812fadb382b2831680692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Wed, 21 Mar 2018 08:23:03 +0100 Subject: [PATCH 30/57] Proper variable naming and fixed Sandros OCD --- src/mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e5eacc41..cae5ee52 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3938,9 +3938,9 @@ void MainWindow::previewDataFile() // check if the file comes from the actual data folder instead of a mod QDir gameDirectory = m_OrganizerCore.managedGame()->dataDirectory().absolutePath(); QString relativePath = gameDirectory.relativeFilePath(fileName); - QDir direRelativePath = gameDirectory.relativeFilePath(fileName); + QDir dirRelativePath = gameDirectory.relativeFilePath(fileName); // if the file is on a different drive the dirRelativePath will actually be an absolute path so we make sure that is not the case - if (!direRelativePath.isAbsolute() && !relativePath.startsWith("..")) { + if (!dirRelativePath.isAbsolute() && !relativePath.startsWith("..")) { fileName = relativePath; } else { From 0e0c72422cd0a77dbf7da53c502558548232b8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Wed, 21 Mar 2018 10:05:37 +0100 Subject: [PATCH 31/57] Added new repos --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 42a41360..0f3d94a6 100644 --- a/readme.md +++ b/readme.md @@ -56,9 +56,11 @@ Here is a complete list: * https://github.com/Modorganizer2/modorganizer-game_falloutnv * https://github.com/Modorganizer2/modorganizer-game_features * https://github.com/Modorganizer2/modorganizer-game_gamebryo +* https://github.com/Modorganizer2/modorganizer-game_morrowind * https://github.com/Modorganizer2/modorganizer-game_oblivion * https://github.com/Modorganizer2/modorganizer-game_skyrim * https://github.com/Modorganizer2/modorganizer-game_skyrimSE +* https://github.com/Modorganizer2/modorganizer-game_ttw * https://github.com/Modorganizer2/modorganizer-installer_bain * https://github.com/Modorganizer2/modorganizer-installer_bundle * https://github.com/Modorganizer2/modorganizer-installer_fomod From ba0a1bd50191fb6387489c6562a2e1fe8e0451d0 Mon Sep 17 00:00:00 2001 From: LePresidente Date: Thu, 22 Mar 2018 09:41:35 +0200 Subject: [PATCH 32/57] Updater and Issue reports now point to Modorganizer2/modorganizer --- src/mainwindow.cpp | 17 ++++++++--------- src/selfupdater.cpp | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e5eacc41..a79e42ba 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1886,7 +1886,7 @@ void MainWindow::wikiTriggered() void MainWindow::issueTriggered() { - ::ShellExecuteW(nullptr, L"open", L"http://github.com/LePresidente/modorganizer/issues", nullptr, nullptr, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", L"http://github.com/Modorganizer2/modorganizer/issues", nullptr, nullptr, SW_SHOWNORMAL); } void MainWindow::tutorialTriggered() @@ -3036,7 +3036,7 @@ void MainWindow::openInstanceFolder() } void MainWindow::openLogsFolder() -{ +{ QString logsPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()); ::ShellExecuteW(nullptr, L"explore", ToWString(logsPath).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } @@ -3237,7 +3237,7 @@ static void addMenuAsPushButton(QMenu *menu, QMenu *subMenu) } QMenu *MainWindow::openFolderMenu() -{ +{ QMenu *FolderMenu = new QMenu(this); @@ -3261,11 +3261,11 @@ QMenu *MainWindow::openFolderMenu() - - - + + + return FolderMenu; @@ -3950,7 +3950,7 @@ void MainWindow::previewDataFile() fileName = fileName.mid(offset + 1); } - + const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), nullptr); @@ -4666,7 +4666,7 @@ void MainWindow::on_bossButton_clicked() dialog.show(); QString outPath = QDir::temp().absoluteFilePath("lootreport.json"); - + QStringList parameters; parameters << "--game" << m_OrganizerCore.managedGame()->gameShortName() << "--gamePath" << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath()) @@ -5076,4 +5076,3 @@ void MainWindow::on_clearFiltersButton_clicked() { deselectFilters(); } - diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 273e9b45..8f962ba4 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -125,7 +125,7 @@ void SelfUpdater::testForUpdate() // TODO: if prereleases are disabled we could just request the latest release // directly try { - m_GitHub.releases(GitHub::Repository("LePresidente", "modorganizer"), + m_GitHub.releases(GitHub::Repository("Modorganizer2", "modorganizer"), [this](const QJsonArray &releases) { QJsonObject newest; for (const QJsonValue &releaseVal : releases) { From 5eb03a687c2cc676a33b2accef1d4dbc46fc9233 Mon Sep 17 00:00:00 2001 From: ImgBotApp Date: Fri, 23 Mar 2018 14:09:58 +0000 Subject: [PATCH 33/57] [ImgBot] optimizes images *Total -- 173.23kb -> 19.45kb (88.77%) /src/resources/multiply-red.png -- 15.64kb -> 0.65kb (95.84%) /src/resources/archive-conflict-neutral.png -- 17.63kb -> 0.83kb (95.31%) /src/resources/archive-conflict-loser.png -- 17.63kb -> 0.87kb (95.09%) /src/resources/archive-conflict-winner.png -- 17.63kb -> 0.92kb (94.8%) /src/resources/archive-conflict-mixed.png -- 17.63kb -> 0.95kb (94.63%) /src/resources/switch-instance-icon.png -- 56.17kb -> 4.23kb (92.47%) /src/resources/open-Folder-Icon.png -- 16.53kb -> 1.40kb (91.53%) /src/resources/contents/conversation.png -- 1.47kb -> 0.81kb (44.75%) /src/resources/contents/breastplate.png -- 1.39kb -> 0.77kb (44.47%) /src/resources/contents/locked-chest.png -- 1.41kb -> 0.78kb (44.38%) /src/resources/contents/lyre.png -- 1.36kb -> 0.76kb (43.59%) /src/resources/contents/usable.png -- 1.31kb -> 0.81kb (37.99%) /src/resources/contents/hand-of-god.png -- 1.08kb -> 0.67kb (37.6%) /src/resources/contents/double-quaver.png -- 0.99kb -> 0.63kb (36.57%) /src/resources/contents/jigsaw-piece.png -- 0.93kb -> 0.66kb (28.78%) /src/resources/contents/tinker.png -- 1.01kb -> 0.72kb (28.52%) /src/resources/contents/empty-chessboard.png -- 0.69kb -> 0.52kb (23.94%) /src/resources/contents/checkbox-tree.png -- 0.64kb -> 0.52kb (19.15%) /src/resources/check.png -- 0.44kb -> 0.39kb (13.19%) /src/resources/contents/config.png -- 0.54kb -> 0.47kb (13.04%) /src/resources/document-save.png -- 1.12kb -> 1.09kb (2.87%) --- src/resources/archive-conflict-loser.png | Bin 18052 -> 886 bytes src/resources/archive-conflict-mixed.png | Bin 18052 -> 969 bytes src/resources/archive-conflict-neutral.png | Bin 18052 -> 846 bytes src/resources/archive-conflict-winner.png | Bin 18052 -> 939 bytes src/resources/check.png | Bin 455 -> 395 bytes src/resources/contents/breastplate.png | Bin 1419 -> 788 bytes src/resources/contents/checkbox-tree.png | Bin 658 -> 532 bytes src/resources/contents/config.png | Bin 552 -> 480 bytes src/resources/contents/conversation.png | Bin 1506 -> 832 bytes src/resources/contents/double-quaver.png | Bin 1009 -> 640 bytes src/resources/contents/empty-chessboard.png | Bin 706 -> 537 bytes src/resources/contents/hand-of-god.png | Bin 1101 -> 687 bytes src/resources/contents/jigsaw-piece.png | Bin 952 -> 678 bytes src/resources/contents/locked-chest.png | Bin 1440 -> 801 bytes src/resources/contents/lyre.png | Bin 1388 -> 783 bytes src/resources/contents/tinker.png | Bin 1038 -> 742 bytes src/resources/contents/usable.png | Bin 1345 -> 834 bytes src/resources/document-save.png | Bin 1150 -> 1117 bytes src/resources/multiply-red.png | Bin 16018 -> 666 bytes src/resources/open-Folder-Icon.png | Bin 16927 -> 1434 bytes src/resources/switch-instance-icon.png | Bin 57516 -> 4333 bytes 21 files changed, 0 insertions(+), 0 deletions(-) diff --git a/src/resources/archive-conflict-loser.png b/src/resources/archive-conflict-loser.png index 77d2e0fafb987ca139f7fad3cb6ad767fe2ea4f0..561e8be865f66baf10760d2886b2dd9db88d2dca 100644 GIT binary patch delta 814 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 JF6*2Ung9Vqb$I{) literal 18052 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 Wb!YEZU6|7dGSt)6&t;ucLK6Tg7d`_3 diff --git a/src/resources/archive-conflict-winner.png b/src/resources/archive-conflict-winner.png index f62605753eec260bd9438279c8bdeeb6ffba54fa..5cc568c87e14faa4b719904b6905ad7f2b454909 100644 GIT binary patch delta 867 zcmZqaWn9fZK~jR5fq_9omp_<+fq^C6(btiIVPik{pG4Nl3Ql_UjFSRUF5m^8Z%1|1SdmU-kWe-|zoL@7Ign*Qe_Je;)Avgy;X`p8wB#{eR&9 z|C0Cr%`VI9Gyfm=`hUysfBiAf|3^LkpYl4^={64Z?^|<&{;qfXf8F=W8@_6;|_PvvvZcKOE+~l{t$^Fcfzzfsr zgN+S!{vY%Df5B^eXY|>rG4|6%Q&)+;Tk8J*X~6$mzNcpR{67@)|CqtsiU8m)`Ps=STi}}C7<x0c6VXuV3qZls3=~~z+U3% z>&pI!S)7m4aQc?X%NQ6K9(lSrhDcmaPDl_C6BJEONlHshO=Vy%Ck~wS|@C?j5^!R#!B!?s>AOzP9G?A7-ZJre;>wojW9)oK!{MK0SQs>C`4= zB}b;fi-zCW@-`OceLTq7sld2U<>QklQ?6|J^5sj9kE5d_Tb|s#H93>#Jh-#xPt&1A zkA&F5%IxYIFKznNb!yeCS+{mov1u@9iREOlWHvJC>FFI@mNsFb2b1nv2S$c9McV9- z8}srPFfcHvmbgZgq$HN4S|t~yCYGc!7#SE^=o%R78X1QenphcFTA5gC8yHv_80fw< f2td)0o1c=IR*73f%$ANfplI-P^>bP0l+XkK?Qwi@ literal 18052 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7I14-?iy0WWg+Z8+Vb&Z8 z1_sA_nIRD+5xzcF$@#f@i7EL>sd^Q;1q>iyV_#8_n4FzjqL7rDo|$K>^nUk#C56ls zTcvPQUjyF)=hTc$kE){7;3~h6MhJ1(0FtBTx$+|-gpg^Jvqyke^gTP3i$ zR(Zu%AYpwa1+bEmY+EHqkcA2nz5xo(`9-M;rg~<&$%e)j3g(u2hNhMlMkYE6Mh1pv z`UaNzh9_{ffi_eM3D1eQcUilHqy^N{e#9PD@GFPt8fq zP0cGQ);H8M#Hz0#BfliSI3pj2m2hdC7FXmJ`1-=_#_HbOT&z|Xm$;Ud;MZ9kQdy9y zACy|0Us{x$>ROhXSE7u~_r)basfgIY>IhV$f>P748dQ>*hQl0?49-AEt;oco4I~56 z22N9usJ5xdEwFMfN=+=uFAB-e&#{9f*8o^tC^$QVlBccGcvO>x#LN`7)?iWMS!4J=a(Eews4bd4-c zOmqzmQ!R8Yjm=YZlMPLb%qspwmCF>?786{d;BpRm~TNuKuz+w!BRUVn3n65;N22k7trxv1$B4Qd` zW)~zD6{mtqBwHm|kpwT~AsHJ&+JH+otHfkbX>XSd%IB#mHu@-{2xmd`fUJTj$i$3J zQ=){)@Rbt~qrj?g8&aH~R#Ki=lI7v5c~4u(UKxu}rZ{)ip9QOVu?^Hc8Y?GEXwrH8VFzGEX!~H8wCyghew_ zETVf6#*7WPS7n71>YyeWsCh|jaT=7GhO8YW zFG5XEfwsVLwlIw?EsRY}Q!I6jEG*L?EzBfCOEcXx3j-4~BNKy^l;l)U(G9W-$uMko z_d!ouPS|C3Z$o+t7rObb-3MkbYQjL1J>Motder zv8jzdx-hzqfXs^2oCuf9+|<0{%=|n%Lo=uzbP22)BXMa&l7MQ2WE-S`7;wZuM1x%1 z?6_?7!Q)4uu_Uk*B)8F!ggT6dHYg}4j9Nlc_>KnGXmF7f0wgIOOTqK16Ns32P*JyB&6apkE9!*`N!9`LCkfeAtb&UoWNg+Uz;?dMK z8eAlW07;5RQ`cy4krV}Hl z;pq~;|I&(o7+yVOWVm_fJxGjk?V*nhV#2HpOpFW+P-P62D=&cL;Ftx>+UEXW+Leoe z;VlD$m^34Un2r#`n@fNG2ZJRU7}p;8#2_ie!T_-fA_yayHl*qQXE5SoV0iG8f#K61 z28I{E85sWkXArUFV6Y7oVz4#h{%>Jr_y6YOpA7Fm|AXm+(~SR*d;Mn+W?^7>^P7Qz z2`!>iv6$M^qXICq3=BuTFnq!E{wF8H+5LL-RiHRY3_D!&^AHV*812L{%y~+)unHcz(85myvVqlPF zWe|Or&!EUYlR@2(nSq6!mqAQel)>2K2ZO%XACOuGp0t+?R`sty=aGQbUnjtP)BX37AG zLNP3=KwOZY1z8ywL_vYgz`y{L!)pLYBQm~q`xnFgyC4xB5CO*EoZi;-Vfo*9+gBhF MPgg&ebxsLQ0Abc&*Z=?k diff --git a/src/resources/check.png b/src/resources/check.png index 0f294a02e2dbcb59d77b3bd752cea05ad1f7b038..5df447552d7325940e0c6b2cbe1131d314a64369 100644 GIT binary patch delta 353 zcmX@k+|4{eGKhtNfnn<}^H&TE3@qu6zK#qG8~eHcB(gFvFeoH@1o<*BRH-pAG_)`< z{9<5WXn4WEP-?)y@G60U!D^%^ma;IUpElc#FLv0F6 z7Crj^Z_9eN&vDN-ACzCuc2sbMR256NbN`~mWd|>9o+4Z`NA5(~g|~X#^WJbROl8{q zXak2=*|PgFb9VhY((KH&jYHNoK=G7U{nRHO;uk{#-~ai&CPbZmiug^rjBmLN3=FCz zt`Q|Ei6yC4$wjG&C8-QX28I^82FAKZ#vz6#RtA<t<8 delta 413 zcmeBXKF&NrQk{)~fkFQB|3n4`2FBtbcPEB*=VV?oFfgzsdAqwX{0G4WdzVk1m@QX- zhe<@(QhffB4;%~(46>Oa5hc#~xw)x%B@7_oT$GwvlA5AWo>`Ki;O^-gkfN8$&cMJZ z=jq}YVsZNDWW&B@0|D3nYc9EJ3WVe>5|L40RlgzA+;uKi&%xO>F-woZS0zs%u$W0@ z!J-4aqMsPkX8TS#+cfR2i1notlb(LBe_m~)mUc}0W1INn>r7rNU(aW~Wb$<1`}>=9 zcHghwEXH?uLVIGvH7SOKo}FHr{;OFYSv)J0S-7?BdF6&&>7Y}Wwb;Eh^KOepW$#$W zt#s&T&9a+vOERk}+g|T#yC&tt@#cHAOQ1`C`U^95M}ZG{+nXO-a2%fS$>#a0RToNS zTLiK{*zgB=Rh8}dxu)c1-u8@HY{w)tmhO1}+q%X=Cheg<-@Lc?!cK3Rpu(y9wL{L` z^0blO=}&z6H{(PY8Z^2pW~s^ayZ_kdZ@Aajf%W_y_fgvAG3ddx&5B@#?J>q Of#~V#=d#Wzp$P!j0j{zD diff --git a/src/resources/contents/breastplate.png b/src/resources/contents/breastplate.png index d3d39407ddb9eb8583037485faa75ac715963b62..f8c787e2960c60dfc050728f9d562d3e5dfdc3dc 100644 GIT binary patch delta 719 zcmeC?p29XkGKhhJfgwy#RfB+ueoXe|!I#{Syr(>e)*?eO=if zF^ltY8cyFbc^Lx(<0DTO#}JFtXD|DEOiq+x|Dd0I+gg2_`NBEpI#^dvY*X|rwmzD% zRBPG@f-~yU&KF6G6plo1IPN*=&gR8)=eJ5oyE0gOJT@ccZ|=TO>F#$t{=R%A zVq&j<-F&Qawpom!zwW7Tfztom-dCd*tPNVe{#$KF)~{w4MACh1t@39#!m6uNKPQwV&rfUs##&^^}J6 z)CJCbIYtkrH3vx=yzz8&G3*o6tXRWv?QYD6*bu)jX?#B(+hjcZ7s7UA5Bt-1+~IXg z4qjh%>-4D@`|}I-n!ozI{{H%^^P)&4bdUUe$(|WbZr4}<^**{u4@!2ZZI+M9_ zH}>#t$?Lz-$5$As%c%NHpnTrkAjXDeKOU-ypYt}e-2U6;gR8~7b;ovGT>JKx)_F$# z6RiEe9_@FpI;L!K=*ef91+{aP_TM=%Wo>cFtEq06T9S1RzVrFm&>6VLVwDm{uG9O1_lPz64!{5l*E!$tK_28#FA77BLhPVT?1oXBjXT56DtEt uD-%m?0|P4q1KpPf0Vo=B^HVa@DsgLw+0yZ5qMJGw1B0ilpUXO@geCx8nKrfn delta 1377 zcmbQj*3CUZQkRW^fuXpn>I(w{152@!X9x!e2S*J@N(Tc2180FpWHAE+!(9+&EC^o2 zKKU_|dOa(Lr;B4qMC;q>u^yM>C64buo4bGSg3Yrp>2|tocWhH!`9x*niRo_-ec+wA zi^I*y$s_S@%fnu_i9)Jz5slN#6_eX$SR4(xGW%3q2ag%69{miwR2c|PYpBf}9puTAq${%5}-i$---l}48mV?kZr zJeA6CZz7o<>@0rnF)2Gc`_G@B#>bBz|M}}{_PRA|3|2HXF)<~Sm6>^7di+s^=Ew)%+^1#K!n zv6z~gdieMpxpPNGgp2ju97|?~4L5U6oIT4s^}*fUW@?maqJp*OsX0FyIt*Kp+k&#=X*4BJ{ z#A++YpK2sId-m*?WxFNi<^6Zx^_w)Oe#VRiK5CC2JyLpqXQ!|ZvlCxwY3Z30Cm#Iz zW#zeP)22zBoSY%6uWq@S^CvoN_0;R@V!5T?zki>elcOUnB$Tl+!edh0`sr$uJE!Z% zt9kPA^5(v4ym&D%!$fMzlqm~#@0Nc0^r-*~V{L8iiPNVKH?#9Exc++koul=uckGaO ze}Dh+`l;IC4+<;_{{5*ua^%Q^%ggZs&)`q$BZ`iP5LpnpC$YS;xvt}JS zcFgU{$>-0WJt*6~nEl7Mx6)PB)r;9)ym`~}LinRuPDXvkfnUFVt()AvsN?td_wQvB z($d(%*T>xrEn0uQyIWkp?bqLV3=9hvFJ`{JKAv6j=httquj_||hW@>n@r@@SB&6l! zNzVu!v6{cXO1oBb@g^%U*9hk zHVgeUx|H(o>^K;_yxwo)_U+SEUKZ_KaWP|CZ|{TDEmP;()y~?wb!&)*NKRhfvg@yx z-hZDS9xi_Q(xnxbU#__PGQ&jb=a-kkzy8*-F)`Xzed#DHEY#7}O)V=cD`61oY>~IG zQ}Nta^K+8b+`g*4^ZMoOpIy2nw0hMlr+rtiUX6*2eE9kK`I$3ko@{34uivzKb+^jT zr>DiemR`EcoUt`Z&bq8eSy_2u_tSTGcl-GHEpt)g{5<_+ijR-aleN*?cWl|>GHK4d zdCyKxR#%>?RP*6Tr|_SjpVg(Mr8PO2)`n@Pr>A>PYHn_hW|NkXQ1H~#(b=$X-@Kxo zbGB~X8WR_n78P~t9Ai{;v~&2YFJDaR&!!nK4buGl`SW49srzRiOjvL;XPE+r$xNS` zudhNi&h4%KUdE>|{q)Uy_s%&e2yht~8z1(buIGB^>eZ`PYd$~o&4^PFNQjP>PBpsu z&cE?w%A*4Z7;5e0JvZ&!XQy=F>}+$-Np|!5|Ni}Z=H$uFe-dnOKRi6VB|_&))>gsV ytx>ufXVZ-NWvxUmiZk%DXnynl{V)HA{N|aDRBs4x>1AMGVDNPHb6Mw<&;$UIAfEaF diff --git a/src/resources/contents/checkbox-tree.png b/src/resources/contents/checkbox-tree.png index a44dd5fd581309fc457c199b69301759f89237ec..f4a63237868a90d74213f6f2e64c89ac13ed285a 100644 GIT binary patch delta 461 zcmbQlI)!C|WDo-b14Edgss;lC153K2uOkD)#(wTUiL49^3<}8}LB0$ORcZ_j4J`}| zzZe)88eT9klo~KFyh>nTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zIPo)U%g(`ns|| zVixD)G@QO=@-hYnhDV+*jv*GO?_O5qW-^pG_R+oj$TlyFnakS}>;mXyhqe@G&^=j$`J3?U~DMP>1Z z>%FCCS;X(k-mvI<%u~zYv9wfEcutc7N7=u_d*}CROe?KqxHlunOY^Nn!p7-AUYh-S z4S7pu*M6In@3>@2(8bmJH|U%Wy5G}r(2GN{<%U|Lmv?v-!^}7Od6z^dG55W>8Fk${ ziGhJZwZt`|BqgyV)hf9tHL)a>!N|bSLf61p*T^`;(8S8X(#phA+rYrez(Dt&(| f-29Zxv`X9>VzzX=ndqj@#lYa{>gTe~DWM4fZq25! delta 610 zcmbQjGKqD9q%Io+14D6D)fWZ^29{zc&kzm{4vrd*lnw?42F?PH$YKTthPxolSP;C3 zeez>Q^?D|LPZ!6Kh}O5$53bfslsG28T{wD@p{KKEs;UsTDtFq_$lj%!CbIheSB|*4`*1vv%LFh&AxfhYwy3me!b>$590yW z{VVME@BGRAfOUcNf!AM^X8OEhsh;s{dTJY$1jGw zlTV8ht>)G-{tnQa&g?mfp=90xThB=?4+~bzQWfevzcr6x_Sv=)tF<52guOoecNgQG zJaet7U56HHcu6~~4RcnTyfb=7gwBCYZ^Yw8T#r01Y&D;Mek)^yj@X(oZIju)R~Ln7 zvF^YB|3d(Sf~Sz(e1Fq=%5H zzUlVc6KR{d^o2TCTyt9-D8bXV`?KEkZZn4V!;MZ07kuDoYS1~o>ae}p4?lipk4Y^N zI?FzE9bNRQ+4HgqN7D}L{M~n*M2>1RI0|sII;}bywN8}bgAISzq5=zKiI7Qz~Wf3Bi{T#-TvbV1_2dIgI+#o$kUvEzIj>ZRUHA21QV&h z)(vI5Yrnr*cRgEYx;H}uqt(A2A2ngk9yevb<(KdGU10yf^Y{Mzr}_=)FJ!kDO%lH& TJ@p0y0|SGntDnm{r-UW|c=Qj- diff --git a/src/resources/contents/config.png b/src/resources/contents/config.png index 3896d8854abaf9052b4d775c36de4bf38db02d0b..3aaa2e5ca9438d0535ba98ff612fb1f170c3e9ea 100644 GIT binary patch delta 409 zcmZ3%@_>1QWDo-b14Edgss;lC153K2uOkD)#(wTUiL49^3<}8}LB0$ORcZ_j4J`}| zzZe)88eT9klo~KFyh>nTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zQKI)U%g(`ns|| zVixD)G@QO=@-hYnhIO7Ujv*GOk4`q^I^-bW8lThBFeA8Q$pns#6JrhuS54Wv)! zag8WRNi0dVN-j!GEJX?_wfUqcuV+-RXYBBFaSVxYe;aPw-RvL`o7>{hVXqiEK}3x)x5@rc z{fzlZla=PSE}dE`z^&N2pxF9#U(6j_y_jp=6KpEpoI5>X?%%34V#z!f@odrC^bZF( zOj6-t_}6M7mUu5ZVA|7wuSGkjtg3v#rIB-6tVx04c;SK1HgU`jvzFbuqrS4Mv_7`^ z{qOQ95!Xc=UE0Mrvfv-neeN zrldm_|2VxueJ>xV+rR&E*y^iyxon)Smu~&lv1-TNyrT(U*xL^??phbz^{cmDuOT9I zss>B+-S=ugJ~Fm!(m4_N$0i}TDVwNif6(3oo{gFE9 zade4Wh)Ao!ywgvW(tJ1Xh+FTqj&aqaw9Sn+=Z`9G$(252AmX~v@#UxaOTth*o@8FxC$cF%qD^}#-cYFjl^rC|O^>?=iC u@4t3D#D7My;Q4a3KG%xx>ywY|W4O0x&IF-ELj?u~1_n=8KbLh*2~7ZM{@30B diff --git a/src/resources/contents/conversation.png b/src/resources/contents/conversation.png index 11030fffa95aaa54de8b33d65295590c9aca305d..76286e33d7c63c5601ed566ec34c6712e9362e76 100644 GIT binary patch delta 764 zcmaFFeSmF(WDo-b14Edgss;lC153K2uOkD)#(wTUiL49^3<}8}LB0$ORcZ_j4J`}| zzZe)88eT9klo~KFyh>nTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zIPo)U%g(`ns|| zVixD)G@QO=@-hYnCO%IW#}JFt$q5Q#9zQ~SWA|i*r8hAOi$$)x^SE9(`0noE#)S&+R@)u2WqN)t zb8-Ey35$R4mN%MT{BQnJvkr*~n$=}j1w!3V{r~?ze$85co-bXe=9j*EzcM4u#DD#t z|NsB5-By~OcYp7O@~l-hZVL?d{`+4)UBPBkl2}a5r$@hT)o|`$di?*t`lbUS&-ef4 zXWhSy!+}-1ZrOn=n{t2rFZ+Jdes}r%dwYN1`Y#=Dd)n>#L%gs5|Np;Y(tmSRRaMoc zUH|`|cjR%4Q2X}TUW>!6c-`^;{{t5;T0``LXPAOHVQh@ zoV4nnqGcho`L-=(4D}0-@KwtNpPR9-?DC;am-7EFe|WxU*7WB&P0}BiomipQ^l!$~ zB^_B8TqDZkN<>qpJ!oz1@~A%}5h5ZrWr~;h+K_8$4_!B(bTV7+XtuqkPW)o@>XOUx z7sU5{nD@Qryyf}IdC%uOS7A70?~E16F7!-8q$B!R--uW}6e13M;rn>%HPg4`q zy?wRZ4)yi+QoU+kZ$4Js*qqMK%*?#wZl2#f8_)dw{3*-!?VH!v$0sBtRPo^fW8C`b zvu4ezr|laA26_T)%nt^?U~&JWyD? zcrn-Ywb93)o}Ml#E4y^<+TPIBVVbq>_5E_8&m^RzoK|1mly-JjW%+!L2VbjBo;ua_ z%A)j@$mY$P8E)j52?^K7NXD(7o_&2?;s1ZNf9mWHCQL{^-p8n+$YLPX>!KuBV|RZK zn+iivV4!1mwzj3ErH`K<)BQO{dxW7 z&6D+ykM}cXWMv)7Fxgc5`&%V%0OOtA<^AF7<1XI3*%`KaZulOFkg%|z$jFmBi=QWD zu};{s#iY+<(E?q9Xhn**xxYj`ZZzNXV0GX`u+HL|Cg^{4NXj1 zjz3nE;1S|#_3-v~UVnY^^y%(}g@$RHXHM6TzjWckfwQyCfByQKZ8P!LUa4u*r@L=m zzI?f)q~yUIv(3fN{leBnG zcdU!cpSt~DzI-{+Ev~O3)al{xe?GtF^RwQLjvaUN45fPO%^n=hD~CzQ{3%?b%#^Y?<%uDM7Ul4lo{ixZ%?Fnx94M;`jUc`ttt%_EuSj@A9QfObsVf z7Oh*y$IyM$DLg#fawabZCX~`pYjF3}&Bw@wG~6B8RK1D??!D$J5jG z57_iyitzCCOw7sY`SPWNfvJ&!uU*+I*+AmN*|SUc@0V{lbH>LLp{@?yfC>hFG;^X+P*F5cf)`}_RzgpD@!|Mr|YdsbKL=bN(K z^-Gp4`6J8x;P&R%FE1}Il-`tkds}Pw#h{6kCp%YGTBdE5Y(D4^6eKix@??v-el9J$ zc3G8J$@=>G&ao&|%6jwvlfxd9nLb7~Had0t<4vT_-se7;wBqv1B|CRUmc6<0F`wth jxixFn?4Qr+ueoXe|!I#{Syr(>e)*?eO=if zF^ltY8cyFbc^Lx(qo1dXV~EA+!C8<`)MX8A;ss0Q`28I^82FAKZ#vz6#RtA<I(w{152@!X9x!e2S*J@N(Tc2180FpWHAE+!(9+&EC^o2 zKG~m1y`DMG)5S3)qV?#sc#Yrj636Eo-qy)(3wzhG_DTFrR`J`tF&BP430}138C#*d zWYKn|w`oUJC%tit>eA3vUA<7`XLPr#m-f%gX^(Qge*71AbNyeleaD{tURV5a&gVJL zE9ZWmbKX*3P_XgeLZdq4$k0&Hr%#_A{i+^T%!ASV?Ohf=g$`}Ud+6D_3DJ4hrfPF1qTN|u;7b~j11iW=~EF8KmXy! zA0NDZ`!=0HRaI3&LZYGm_~S+e4hu`mgD+lW_*^)1#z%sO?Z(@(n7BA48NS0$ixzI* zE&#aU%s^L-fey6+_|R57AI0Rt(YIS`sjrV0`+C(<-&EW zk6Mm@Vm|q_=+(=Yiu0bY+_!JupE`S8eSP8Mg-VVKK%DjuKr+x05>;xMs{|y(?SmkWkH7^)d?q4Qp{#| zKCjHm$ypMh;i9dronkgSv$%Njp@#)V4;Oi@VhIlqpD|~Si?cKHk)*<)^5gyG559bv zqNT09f9t9KDOaKuIGnsDtMg9aTPo|IG;xC0(qFL*y>8BByXV%}$r~Pf@$utCrbY%& zl}Ys$_m}WJ3^y?{atd2*sy8!erHYc$)~LC54Bbba9zT9O|ChnBq&HKhE!e&L_vMd2 ze^wUlzWb8-#_ikQH{^NPP9|*(NKaR1?2z=%z0(Qy}kOJ&x#FROO=`rI=H&J9+6o5=+UG7Of82KXVuS`;UQ)7Ebm%|NkmkXlZw#6 z|D`oGbFSR|fArh@L=&ll65ZZ^)&*!xv18a8)jNIqbpFZA4X2-a$vecx-d%o@pN}sf zAYg(W!^Vi7uV26JIP(1Y^B3>m_y4@^pDMgJc+cuxyJl^P(%rjn-=y=;mDgYQeinTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zIPo)U%g(`ns|| zVixD)G@QO=@-hYnhUcCxjv*GO_fB@~Y6;+Bl^1$p%qgerw8!-^`@;7ZE^VKn;D6#{ zmEZ}Tv~TB}&g^;+$ja#VUbK)wLTM4ZfFO5+nBZM~fl$r^tGpOPL>VhWPue#sf7VtC zPU};eG;?=H&di?zKcgqEDq>ip#ZVs=%BHaTkx+uc>^pyR(^l`Eee=z`vuDh{mvuhV zys)}YB|P-+gpjN1CnH14i*_zQ%sY#F=jvBJpH{9?v0t@ol1%9DYLnT&)6&k~O*bz7 ze)Y_~cXl&*zn8plk(;@*^TfQFN=9kVRFv+YdAy1**2RRu+lAqUauP#<%bs)d|Fb`` zTvuO|?>6@g0|SFRdP{kVo554k%6Iwu7Rt)x7$D3zhSyj(9cFMDDfKNkaor>mdK II;Vst0R7~&!2kdN delta 658 zcmbQqa)@<;q%Io+14D6D)fWZ^29{zc&kzm{4vrd*lnw?42F?PH$YKTthPxolSP;C3 zeew%N^?D|IPZ!6Kh}O5$1HE25h_wChWZ%`U_HI$&l0xpQSyy)S{dgoKa;L3jlG7t8 zucgO)SIk^@u-)^S-4U5*cYdomwcM8XdVao~>+;N>{z9w=k{kpX?%ccg=)(sAh6^UV z=gyzssnDf#=gyrC`*-g?{Q0x-??oCFd*ap?*4Ll6^9`1fub1C!Z*A>-d)t4XLt?Ip z)so3NyFxcIf>`d<4jkLUPfLq0yf8{wg>YfXRO%waqK zd4{cx4a1N7$re9YL>Q_|N{;+qHRaINtD@q2_U`SxW3P&a;vYivt8F~Ywl{$(>o@?a5vYeFIi8b|9FJn^f&d*3Icah z<>lp@GS{-sKmYti)8&nJ_jXJ0X|Wzymf2;%!&s93;N{Cs?wb4QY$duSyYFtYx3zt` z@tRa<=*IazYBjUj8#d|uinnZ(htu={5XQSyPkZ=2EsX zg5%w$?r!db>(;Ml{r~4r%C;E2-8Yy&MM}y}IRAd$^TNrm_MVPSTPu1dO4~xv@cn-F z`%J%nJKf%mdKI;Vst0O{s8@&Et; diff --git a/src/resources/contents/hand-of-god.png b/src/resources/contents/hand-of-god.png index e3a05335e7bc3375790dee07c650e9978fa32941..7cbd0102924aee745098262347521e98499a89d4 100644 GIT binary patch delta 618 zcmX@hv7U8;WDo-b14Edgss;lC153K2uOkD)#(wTUiL49^3<}8}LB0$ORcZ_j4J`}| zzZe)88eT9klo~KFyh>nTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zIPo)U%g(`ns|| zVixD)G@QO=@-hYn##&Do#}JFt$q5SL9l{gRyVMpO*ul}>A~|KAOm}QtrCLkak9EDF zaewPLm_gw6#`@2f=U#cTWJAdwqJLv4O$N^M8N-ZxdicSk35dMrzZa4p!t<|1uxBlI9 z|33)qX9;b5@Vt1lmQhi)`QHEkFTA_>|9?C4#ls0gcXan35{Y3kWcK{XA9HkmJc8#Fo^G%Hr-|NmLfzKm&FJIL(+_Sw(> zZ&%wk|KIlHRT}^P|Gz%}|78pFzx78`|NZ;V;#R`?NB;kF*FXR4`;#Z}GdEv+{r|E- zkH+u+0jeLK%LlW8z+CbFsfHm}{?{+7fBBB<>4~c3kDg!q8JJ$q?M~!iVo=k*f9BPH z<6H&?2GtVRh?11Vl2ohYqSVBaR0bmhLknF4V_hTT5JM9y14}CtOKk%KD+2@Fmj(eS h8glbfGSez?Ylzv>@rGfdyBZe*gQu&X%Q~loCIC5|3FrU- delta 1056 zcmZ3_dX{5?q%Io+14D6D)fWZ^29{zc&kzm{4vrd*lnw?42F?PH$YKTthI=5)c=uIv z*5o=S^?K%0o-U3d5v^~h`)kzXiX7i>oM!Sal;`L69i^>DGz5)RC!h7;J;XFQXp$7C z^vvGY^5agES_5uGL7{(5?z$NApT>Q|Ar&*!{< zKJWLO&tFzB2<*>zHDAob!{di7!`3L??xUZo87wU=?V}m%7hnAGu+G_;`A%N>0h>Rk zygWT0o;Y!0_wP+Qmmhz;kYG?VL!IY<{rsO<3?Bae#~(dXYHM%bxOea0toYSelj`c^ zHt9HvxT>hBDQRhOMXeQEq~RpudgSQQho3%uDi-bN=~;64;e)$(Wv^emw&H45{Lhy5 z_Ts9lS&e7jmi_O%__CxvCnsmg&78EPq(|{5T>_U}%t#3i7FJhNtEjB>oOI{jy|kd9 zOWGg5d?{JCe*I*X>C>lYZoh45Zhrjp=g;36lai8{F73N<`LeLPySrxBqWF-tVV6^k z3UhLLx)x1PDK9IN5ElL{K1aneZ1UAubFduI}!apB5?F)Z5rR*uQ`O z{^QrKiTU~YG5nDZ{EH=__Act&YhB_rKJKa5AV9Lv$MZ=_wLxEM@okd9a^Bl_2}{AL<5P0tx+4d zY-w4!a^-eLJEb#c&a`+fJ@oRW=9)0=o_aUsNs}fmxc>TK(asIKcXv;nDw<&;b>nSW zNO-vO;){DuUA}p7?v}7}miF@<&=ghTh*WTw2h=`Dwvg7j0 zC5tp_>gv*>qi=s_WO#7wn43dGR~J{*+OR4cxk*b7Km1|GF#D{Sz=5YlhSt`zU0q%G z?A@#C`R&`cI{pT?#SbrDyg2)iuC8uOM1+Fpy!rEu_4WJf(>BjEH#b)~Id9&)3ycgK z7B4=m|LSYi-@Aq;CPz9tIL@6rH%aCExpNvEOulN9{|iY=NG$ML%EhaorPX!)`gN6) z-@cXI$}zLEvzw%H{P^*emtR^~Se)3j$*A5ZFHi4o-gbEt6$XY93mKJ@ix(>|TefV| zs#RTGi!MC>Y-n%)|LlzPHEVRN=K4)qqT;!bks+bH+}!iimoHN!B_(wnTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zIPo)U%g(`ns|| zVixD)G@QO=@-hYn#u85##}JFtb0_<198Q!uzCZ5S+8NW+^ist1PPN9wJbm_H=~*wY zvt6<>H%>ancv#Go-QrU0aN2Q>g|?=*XC`~_Wvj0 zdibB4Zr~p;tHw?Do@%$2{Jo^?q88>Ctm64D`|mOqR@>8^S9pFMnsQb1#$WOKS5D|M zY}3)N{N~Ze+2ENcuzf+wl~9$qhe1qCx7c+&4>XFsnAk9b(c$o-UDqZSc^~thG(Xt$YrAphFUA9tMH{a(M9jZZ%EC~yNnVeo;pdli zq6b7g)x_JJvNG8j68xDbGptfxV#H)|^^)O{ZS4#J&u6}7N(l6x-)F!N|bSLf61p*T^`;(8S8X(#phA+rYrez(Dt&(| n-29Zxv`X9>VzzX=VPIg81lbUrKQTa-i-Ez@)z4*}Q$iB}t&Q@D delta 906 zcmZ3+x`Ta!q%Io+14D6D)fWZ^29{zc&kzm{4vrd*lnw?42F?PH$YKTthPxolSP;C3 zeR3(2dOfqLr;B4qMC;LMwjQqoM2`DsXNP{6y{bD&SF35U(u&1O>y+w5j;s`0vbapF zP{3u^RX!n?70phC0{u(Ii)AhxaSiu02|R@uJ|Tt(!MDPnslj*G{CZ z?y-jolWL`n++~I^<&{#hvY~V2B_s?UwM|rP$T3@O@&Chz1gVA-4!fKd1~~qzoY#K& z<)4|x0imI-&CSeg2}MOgSNAPk$awkk8f=b!&>%iz)yp`&JfF2yJ!KK}U0lboAwu1T88aNyp(d*2zh zY~89j`Q!?=pv#{>Z;sl3fiEIHzW?LL!j{8{Dw91AH-5f)`}S)2gq$26adGh<;ACy@6zPFp}SAY0vQDa9y zSXkT5n~^_i?50ecCS}b$efsoe3`!F_-Z`(GdH?a_8S5a{zgpI|q z;ci}f&DJej5=u*_X2yKEs;;50fBg09)tVixt*kfwOG{1Py?e*NFiB-DoW}IiqGygjE?j$R@xq0Q zKPBr+OG_VA#x0wy!f9-5{3&lw-1=93eEj^P+AmhGdH4SP=FkgQuCzEPG%Q`J`sM3a z!*elu(^oD2{=K}yMlM1}EUovFqtDWy8+Yy;xpF1sU;dnZ(<-a0SMOY$VZycgs@83F zAmdKI;Vst0BHxU<^TWy diff --git a/src/resources/contents/locked-chest.png b/src/resources/contents/locked-chest.png index d70d448e9e99fd8ab71b76653377f4cf59d34925..b49e11651ebf58be8195b36d05245fd3757dc97e 100644 GIT binary patch delta 746 zcmZ3$y^w8!WDo-b14Edgss;lC153K2uOkD)#(wTUiL49^3<}8}LB0$ORcZ_j4J`}| zzZe)88eT9klo~KFyh>nTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zIPo)U%g(`ns|| zVixD)G@QO=@-hYn#`m5sjv*GOr(TZrxSS|*{G+k?_RLo%n?9uJPF%??w2`OD@nSa@ zUsu_~D#aIvtn-_cJd&oe2&eMy`ogN>qbBBcQ~K)JC3;*w9Y!e@O&5138OCm_-Cc0| z|NcMbukP5MfB*SF<8zsb_1d318yD73li69^_q4lp>+(BCZ|$`9D+&MVtWb73c*#e* zbH`^rQ@y5TcI{jHMi-Aa#d?dcTxX6vz~1N^82WF^rc>Wjo+Mc5|2>!#IbTcOr1J5a zn0pEKFE4d>Y-!&AYWk#pNq2=^x9jvdA1f&>zVIUW(*{+B`B}5BRpkjy4A*(KH_Rd1 zJE;C@v4cy_^IyIvedJEfXRWW?_1s$N(qp5UR_T`>>|ozFm2ZjPeQQ^hLoS}h`yOAC zZkRvq_l0DCh7a2oFNtwc@`>6Rv^PG!ytFSfnden?BmORCrPitV+D4Y)7fT(5IM|J{P-ho|1LU6j1-v{Elr zA?}C8i-ZbxmeW)E0~x#KFFmlB%cP+=GtpFh#)g^wcVx~mdf3?~U(IZ;R9nlSvb@Ul z;Iuxy>}O8g9UVXaY%z=Yn$EWQn)Plz9hPlryzk5MBY5Msh_8vBuxIb_poG*FAN9R6 zGWHhke)PBX>`t+IOaJ@{|5w~Md&B8db?2530|SFRdP{kVo554k%6Iw zu7Rt)x70 SVu&Oc1B0ilpUXO@geCwAT0K<& delta 1398 zcmZ3;wt#zrq%Io+14D6D)fWZ^29{zc&kzm{4vrd*lnw?42F?PH$YKTthI=5)c=uIv z*5nUN>h-L$o-U3d5v@n3=X(Ul${epRpFR8B%d{n%#9xXTnL2h}S!iVNpPNsm&Emg; z1c#twzRn>*ZPx&?qLtIb7Cdr^UFb0_>DM8TBMPj#s&2)Gn>H=FYI5_Joqp2w^qc>_ z{;)YO&UfeY`|p466rbDsT&AtV;s0Wme_Be)%AU(F2L=Y#3v#kB8O=UxVrltvy~Bg+ zOD<-7cy(2q;lR0beCy)&a&3(0`SPX2#MIPr`DH~lwPz0d?S1yKTFvFVzrUWH!9s@b z$&)7vrlz97!NEUv$LNW_yStlxZybN8OOXYGRBxN{{ad%3qN1dGad4 zqe+grxo_tm_){~%Yia$4n>h>&{l}XxFZXv|d@&(CU46mN^|$WbbMy4{{J{_#8yh1q zEw%8=i$DvRz71#6)6)z8{3u+qWXXcntGWB-?T=l!AmHWg&CGlv#i-`*FHwdMKR>4* zIeK*A_U-06pLdtPcTy2Lm|;?MdB^VE-LJ2&SGKZ}(wfTE+uM5~YwLs0KkN4~=<4dm zESNV>Zpo4*2i}&o=j3gSP!QoVG%-0c)l!CU#nr48AzD6uevgj#%g5Zkabt%5ffFY< z!e`E&{n}XeV9M4g#i?EgH|d0bdw17*$UTyFE>^wR`duxzx92;n2>s*wCTdlnne8_4M{GT(gFUsgWUStysUD z?V&$^Y7!dy`uIY^!6ofifaxV^u>pZ&1GjT<)@ z7;1ieV7zB<$ zXsp<`Z{D?Q*G{Bu4s>*6+^FMSTwE+7E9>jGeDb+@w%*74WR*AH^vTW5{qpRr^s9I8 z)RqQSD(t)exgp%xxZXHrV?;-y#Hy7m6*orsi0j8KIda6sNP;IMHrDs=-@jkp+%!&- zX#4c((~C1RjZJKAeOXyq4;~7>AefPnp|CN+=lQw0)&c4hJyvYpI(6E#X&Dt2Gg6Es z_tyQLbtbLY8Fa4)uIJl+qQ47Kl!rc(z9o3 zo+?6{Zof@r<#(-fS1>l7{HDxWRYfJBxY)S2ukX_K{QLi`8PRofcnt2ViFo?WdMH#c`X|AMg9E0-;66A~8wYnCF>_UZFy zO?&(Q9~if7+xFtw+1V~%KHC*MJtbPdYVF#kYu2oBHvN3+ZQ12VkCdi=ua5Kf_iw+L z@#SXTUMU$Fm$Wps>GS8!Ym3qQ|5okE)#d*44{XwzG5@=XRFr_IsOX<0A)SvEHX>qTi`K2vQ#kPMo!+lszb4F{Eq(8-#vBy^j)2h6*2YH0 zJNs?x<%@R8lbP0l+XkK?V_D^ diff --git a/src/resources/contents/lyre.png b/src/resources/contents/lyre.png index 041dbb0181cacf5f8b185e9985bea457b309e225..3adff24e57423ce838554bb7b255c021a9e4f3a6 100644 GIT binary patch delta 714 zcmaFE)z3CTGKhhJfgwy#RfB+ueoXe|!I#{Syr(>e)*?eO=if zF^ltY8cyFbc^Lx(<6Tb|#}JFtYcKnHgak?)`*=LjM16_>O0&R)fgUVUVOvg|TBLtR zM2K@M7i(bG2@N9+u322SMYc}#$}r6A{-e=*W~KtqLW$$99j$^l7HD)Gy4rpB+5M!V zcXMa%=Bx^TKIi#%i}ug^F4eDWVt-$M|4N#r|FpY2rN6H0zd3jIyYJ!Y&1L(R%O5+m zx&6`Zvm0NQ)k~s!1zUn^lX78A)CAoqx zuHsSUv*?Tc8 z(-_NDdJh$cFUbGkb;)GQ?&iP>^_SW`m3JNF1SVWznp0oK{Jrt?B&~+d-j@$Hu;xtK z@`7F9?o2MfvyAJ7Wm~@%%oWag&0w(oSpIJjhSk+S-W6?Lky7LP_(D3vil4t{&&*ZH z$~qQz-{VX3b^ofFQ_oGaGMF*zyNHVU((N`GH&vi4P7`Oe?` zmwnHpwyZro%XAnR7~)k+Tq8I(w{152@!X9x!e2S*J@N(Tc2180FpWHAE+!#xmYy!)y- zYw|rN^?H_L*|G~QGFT`zI1%lb!;k~&?KE?v5$w0G}bq0s8;-8nZm zxwfs7eSK>~VlxX9V3q-w{Z8}O=)MPPM$b1 zp@!Ye$TpW!;}0 zHGhAF1_cKTGkSS>xwwQh^-7zc`uX{J=%U%?`CaQ?Ynkyl+tvTmxqJ6+(yV2(-oJi5 z`FOwl>WcsW{%*>@zi-DK>#{ci46E4eYJagD*pzyj;m60v?99x}3^l*M_0FxgF28i; zii?KGqP=_Pc6D(z9aLy;Zr%~2XCue|`r6vVSzCj`!ra{5*%@}NyL|Vq?DXB6Hydwc zGw~H(e_i|g`}@BW4mIWFiS0NeR$x~<;x$JSTXJ> zdU{IY>pYFiCOfOXYO(XlD43gz3ohKVXU?ZjpIWvq-pB6c?LE^hS88EEhqQTK4>!Yt zWy{zO8x&a0ee(Qy|E@fj22t&>fRGRt2Ul0tzkmNeW_$7C#e+*ry&2|M6gKtr^gLmB zc6N6A`TFOF(>8zn^)>t4Tx;{Z&nx!C=|3!(!OAUm;l_;u8pIw#? zDng1PTq`SHURr9{u<(3(eOA^hdqxHiZ|~sb*=NO=C87!}EiEI~a`s+o*;??>$;j9^ z^v>0*qRbt3%NaJOolW}w?(Ss1fS4E=arWke5(hrm&wlkPOH4P)B=gzrZMlm#Y%s`M zw{W2%TR?pL`QP8)U-jL6_gphOf5g_Tt1V~0zq#q`?93dz%qOt8{N0_0PfyoRH*9EZ zWaN{#li6N)ZjPl*&5sGQW=TCeKi@ttdHLne^UohYI@-PJf!pVxyC++@#Zy!y+Z4;+ z--)Z=c=HvbVF=#P9#tzg)w6$|L_xx8FW_ z`gCK>&mtK<_Ojh`zkDgF`}fB)KVN_D+_^UO|K_BhpLg-jojE1)GffWczoh@NSTS+3 TLqQ~{RAlgU^>bP0l+XkKS5}@7 diff --git a/src/resources/contents/tinker.png b/src/resources/contents/tinker.png index 9709cee86d2d7c386bdb6c33184a630ba1b58d9c..dceb136762022d92b0695d89e82ae121d4cf41b4 100644 GIT binary patch delta 673 zcmeC+ueoXe|!I#{Syr(>e)*?eO=if zF^ltY8cyFbc^Lx(;}%aB#}JFty^{?+qzgsb>o2ZIFuoBs#o=N@Q?TRZg-2XBC}dpJ z6?+-@LP0{iB-3$I$tA~Do+dsezM~68+Fz&zW;h&Fn;X3$%&|~F#)#u$ca7{jy|^N| zx3lm4uf2cQwys?L@9rky)hFGr9{@?dO|1dLj-FkuQ@XPS z`vvzkvU&!sUXq!!c)3o`!OVb3k9JR*rEhag7)1dz8j9v4eP1^e|Bk5=K z@A^&O^BW#b_&)W^A2x;G3bppr=S^+MdC@FC{nG?q*TeRIcZ8j2n>VZT1GoIW3;)&? zS|!ckl$W#gl8l!5Emc-`l<{uzmVWi){yKIll|8?XPMW-SZ~fGbVdwr;-H_|O=X3X? z-2;PSRuT5o&WC+G7+1$P?TjiFO}JMYefW;`Z^0=l^|?mMp7RrL{(T_(VDZ*NJt~^b zs#agwcf6Xg#O%58lKZ+f%qLjpB;RS7+Yr5CrVhjUn40}twf3oJ?lX^kd$_meSMCMr z{~nj?|NO3JR9Rye8hT^ye+C8y)e_f;l9a@fRIB8o)Wnih1|tJQ3taM)4e((z`Zn>rT*gQu&X%Q~loCICMV8two9 delta 993 zcmaFH+Q%_LQkRW^fuXpn>I(w{152@!X9x!e2S*J@N(Tc2180FpWHAE+!(9+&EC^o2 zK6xvXdOdTur;B4qMC;M%z8+eEBFFpVS)VS_?`k~J*%an@ODRWKghh1g>W;PrtpRFV zGzFrssELd15GWG7s1)V0gl_+~0cU$sWnlE$r_PG+LLR z+x!2%?VaN1eQg~M|1WNFa$bM^@})~cvNAFgPCs3=Y}vBxULJ0^ZtdE)><3?`R(OVudPv^AKOrL2j;%}ZkV`FP}lyu;AQJOd*r0rrxh;ChBePQFZYhjs^ zVayZHrU`Z*eekvF;+;D@`|s;_doI6xXnw5m{`iA$B!Rpd2O%BoqaaV#@1G|D?UDc@xFa>jSdT>3QHMWTK@g3OW7PbbH~Mu zBe!lvZGH5Lv4i7dMT}bB#)tz3Jn!Duzh5o5o+qKcK3?hG?c3b*o^RZ#kz{n_Q z<&LU`TeqTS_^7Q}vu44%b$ouyg>_ChJ+=^B#8p_zpmSPjqQ`;PUz;9V%$Yx*nPJk& zC;J;T^yA)4@LYabLROYl@GqOwtwf`l37c;|DB78@`DRLb^~$?(sxJEigM*pppI6s5 z-TJ70f5QoLK7RhwT+Bb$-+uBW<)mkNTH1t@DGv%Pt}ycO@_M?+$;%6JwSM^eRW{fI6Tw3PMlRL?tnV!CU5wDtqi<01;efu80d*}DE z%Z-DrnW5qB+uWNf?(XhN4fo%#-*M*9!wo9kuV25O^u0bxX;FxlYu@(RW@ctD@{=Xp za_VbpPTZTm`P@0blb^3$6Dut(_55|=;>Cp?@fG`-8y-G<*kxQ$TB>^c#KM3T1@;>J zB6;hZS`R-=n!RF4_SUEyZ_92zO)D$gW^v&Dql+0^KDaN^%FoXif6udh`}T~Ci~zQb zoSY*!Z%RJ;Xu;ITpdltME?Td*>g&ptE1e26Si1hF)-#m-)_7LB+UpJj0|SGntDnm{ Hr-UW|KKj+< diff --git a/src/resources/contents/usable.png b/src/resources/contents/usable.png index 2bc93a7dac1e0dbba504da8bba3af971801caa56..c705997a83ee1afc02c1d4f2b54cecd365a77463 100644 GIT binary patch delta 766 zcmX@eb%nTu$sZZAYL$MSD+080|Qf%x4R3&|Mvbf`zIPo)U%g(`ns|| zVixD)G@QO=@-hYnCIL?u#}JFtQzzSdTuGETZhw#SrR7Rz5mrB5M-vva7c<|9&bTx| z)5OL3qJS2kV?@Uj`3q|m1e)GlIeEaIg*Qp`G4X zh5y^6w3!}cZtDtHcDT4>S16Oi^j$JNrI*dr)ESjlXR$k2EWO5b)%&@{Tj^)&3m)oR zzfzwfu_Aam!@2*nxHoS+x4k^%?>=^8$43ipF&z-zE&0`_sO92(!Hm$~jjngK&+9&Z z9d|fceo1`%Sw3db-@6!=l&H`6UZnOh>~6$&t^?)1Oqsp%e@+x^==5cH^y|6A!ytzr zAs!x?j~WWJ6l#_%I5PdPn&Ommf_4lc?_Q@TIPB$qSZ~drZ_2}}U&6d)WvxTV+_vAX zMU|WetFJLUj5YOo@@wFtVwH-WKxryYNNJ!JlKSLxu=Wm}mRY|0J0`n`42 zyOXPS&5wxkdhzm0XmXSdz+MWMF8aYhbKvWE^5>Vr5`yWn!sq tU|?lnp!?Dw07XM?eoAIqC6WeVG#xQpI^IllQ|Dq}@O1TaS?83{1OOZ!MvMRe delta 1302 zcmX@ac93g=q%Io+14D6D)fWZ^29{zc&kzm{4vrd*lnw?42F?PH$YKTthI=5)c=uIv z)?`6u^?H_lo-U3d5v@nVEj_ejMeJs>7;f}pvb*CTqLZV;a#S_z)eeO&F~z3V8y&4H zA~+Taxwu^La}+qDnl<&%Qr?3cMup7Mfr^tXReF!z&w6XEngZ|R#Nid+qbaN z2k(V=*e>3?_wPH4Mc?5oS31fiymoHbI>A(Ea$A7`%#m*CV1{qGBGG)Qam7cF&msq_hv09mLAd#Z2*`;*r)~zX= zFTPeq9^4tDmti7xG_tR+&q>5pL`}hqd$1qn(I%TIWt9A zLQ-;~ZuPF*D|hbjFuZv6ib?R`+p@!N%T5=tH8ZBCr}w;HxKMFgL)hx6Z$H1cT)$#P z!~OT}b#-Na*f_*%7b?_S-9Ys0jQii;gxR;*v2Uc=qQur}KOOOhRrhuS?6JLr#14?_a!ocl4(F zw{Lr!Iv#rSMrZMs+i$y0+Zh-zFi6PDvkNBH*2*$Wm^_);QDBKwM11`5%a?_D*qT#b z7g)@YFg7-x&%(#guj*KX1HEZ8B%4i&Ix|LBR*l2igCe7Y5w2jSCBFi_mE+u;`gORWvQ^p1cJb6{wwsNmnqpEq*MqGDsG{+c^?Zi2yLV$(7F1PLT@sr!$;aRSG*>}= z{rrPhu3XvR{_*eMdRyiV5jvM5@7=i3v2mke#oo9hNgL%kS(+WyDx95}7mKqze0}=? ze?~>c492Dlp%|#pT)0<%k1tRpRb@)p zqvg}4PF3aB>r#q}j^3Xf>Ad{1=INI=Z%V#;{W_FAKO^R$@j7il$Vl81@_U;D%FzaM`8 zEy&kCbN0L6oBaL!R@G0d&&|!v-4uK1k2EI>lb2<z@bT41$7fkQ$@ z=1<()F5k&1A14>cxL>_`_0svw!a~E(#Z|Snx_{@$$;nO9=*qe?DU0d<)IV&F7O{@s UgC?*tFfcH9y85}Sb4q9e0OPZ6GXMYp diff --git a/src/resources/document-save.png b/src/resources/document-save.png index a94e0eab97def13486256451f08973e0b68f9ad8..18e1f974ecbf9111f905ce6a6540d9cfb5237842 100644 GIT binary patch delta 1107 zcmeyzahGF)WIZzj1H+I_7kRSJdV; zhfG~q=u|K%Y1;0_wHHfPTn?`6^2}?>s*eh+>`GsB&ZS~by?xO%`>f8K#_+hB%G}<* z=(>)o-js^&7^l1r_u55X4a@9v+De*zeT$k3x|(J#&MEKC2`O(#sLhM6DynJB%`3>R z=t#{g$VNlYpFe-_;6YwNc6w$?T1Lw0)2C0II1w5i92y>Mk>1_E?RM$PtH}$_S=Z-G zbgx}pvf@hi(#u{AE8=DykDhigxMyp`q`e7qPv;e6msaLvbWRQ_sxB(c{`T!#!kkmh ztqpJ9ym|flbwKB)8T6#N9r5v`ucmHK7IQ3?b{tYcD#J~ z;`#IEmv5YT^yuNnjT4pzm0)`fwRCPvY3H^_c{nOI%&+VU|?WiFY)wsWq(x9EY8Pi zIDO0HWeg0AZk{fVArhB!&$R~~GGJ(Uxa0f1YJQhHQmpI|k3BLAu68cg2x8xHaPMoe zsp@8#?*;t--BI1CzcYq`K|x9A(xOGl4jCH@KXP{7wLP}v$&>(JU+?n6W-2&FaI^IH&jVF-1k;BdZqQG0^l${FQ&~azKl5N|^u7!n}F+p8jOLt(3k||Kjh{ zY^O3>Kdn09&397m=2258mR~#aVry@4R(clQSU6cgC+9`OJ=GHu`9|TQ$&m#w8xvP& zR=3O5CzwBRHFv#vdCzU8sPErW*D_a}5IcWy<91#J88wy(=U105D)stoXlK2D$DUpL zcJAF>A0T&i;m6CLPrttXyZ!%X{`$)Of9H2CVqsc%=iTpccBZ)+KC$+aU2WzcFRH6C zFfgc=xJHzuB$lLFB^RY8mZUNm85mmV8W`&u8HX5}Sos)OTA5gC8yHv_80fw<2td)1 eo1c=IR*9wqNkhz*jyDVp3=E#GelF{r5}E+JVIvLz delta 1140 zcmcc1@sDGIWIY=L1H+LmIo1pe3~Wi>?k)`fL2$v|<&zm07&r?&B8wRqc&~#nqm#z$ z3I+xS_7YEDSN5yiT)ZZt9;roa3=AyXo-U3d7N^%vjm;4W6**pS{M&MF?(WN})9+qO zjkKGl#CmH|ShswHu)KkjiCfJD@ykCLOg%z_n13nMyD>?0XXePe$eVOcI?>Ia!DDE4 zti!}HWR2>Ut!78B-Q9M%Y=3%sc}+%n&dLCvKkDYspUo@&_r3nSt#Nn)q%!le#Ly;H}z9~?%eft-(+Or(1bGvTsjtsuc z;85Qg!gRpa_d8RLnKz?NOl0I%kE^@Sn;U<){GFkvm#;B#!u8^mOP-I6wHTbkt18p) zml>-|@G$OSQg~;7Axhg*^~T#W8@YZ-kq>PzGH$xn=ktr+^WthVjAw5)+TPxHS{x+0 z!icFs=k({NA2xtIz~K`1>kq?B6tjyE(FYMgj zS#XujI4<Wl6k?oXTN;^_8?9$ zVaI!+<+o<7?7T9&W!0)l=U=M`aVEc=wUxm)$!zxBN8f)J?u=<#_gwSL{R%_J&`>Qe z<`SFR4)yi<{Q0)Q{;rt^zA!%dY{juaqf3Biozmo!)1qYgj=%FzN!oV$>;jG6n%Yf; zH}9vGmYVu4Uwo8Hp!?{IIdk?@-WStaNn!Ba?YI(KO3$DcJWi!Z8f^U%?|<9oeSM~pkSEm46>Y|~AhS<4b7*vw|X zopvg}Wo3i_%cYklrKMY6RLON8ZCdv_ZNc5V=lc(E3G}-0?!RyU-=}h#Z_)0%3@wKr ys+Q&CoMB*j*r_gmUzp>^`49F|qNA6%exF^hqLfx*+&&t;ucLK6Ttm>Wm{ diff --git a/src/resources/multiply-red.png b/src/resources/multiply-red.png index c238f07f5f2e8e854bb308356770d79cf728a5ae..f35adc741b48034ee8a9f8ee7b97f48fa464986b 100644 GIT binary patch delta 591 zcmbPKJBxLKqy#eq1A~Sxe=q|B153K2uOkD)#(wTUiL8_Ltn}&`Rs{Hjxc>kD|9_0j zM=ztdE;=u4RUezn-!qW7r785^+xUzG!~YnU|1mCqBOU)nI{pl`{T5(>sq(4{&n0>G zbJEP`q?yl1FhF$ujdc9Kq~m9(?f?1B-vTWD+AW%PeS>01|_|7|%hY*qhf)FeGN zm;c{W_`fLfo`J;w41bWV@oraDc>agkU6N=2A7F7#ni=Yj|Nn(uCOuXyet)NbpXpP72*bB^^ygQM@FL{b7{%9RfA z6y%jZe5P@*Ugn1VywsmHZ>ATtwZt`|BqgyV z)hf9tHL)a>!N|bSLf61p*T^`;(8S8X(#q68+rYrez@X%|eW@&pj@mdKI;Vst0K1atWdHyG literal 16018 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 Dr1D^# literal 16927 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 diff --git a/src/resources/switch-instance-icon.png b/src/resources/switch-instance-icon.png index b992babe9f12df5335a9dda816c350f5e7b1a451..cd509d3daa8d409e18d939f23a17731efaa82aca 100644 GIT binary patch delta 4278 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 literal 57516 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F4vn#R zCx2)8*4nD~Z{PmD{(H~!InV!`t31!&ASk3Z@!6s*2FsvU8><`g{r(^r3XtqYMlmm@6ylN;cU4VO*cjz{F5+RZm6e_{0Cry8_h085AZmJWvvP&doR> zh~b1@$O#dK6A}y?f;XpdF-&1#$f>MxQes%e%kbulryVQ9jg^z{h%?++B(su(p_h?i zriQx;lf!O?gwVzy9i{_^7#6H?P|{;Lu#T}Ia+{GmQ^Q_XhO)kh3H%NT3=K1#bj~m+ zSTHd-%L$)lR`6k7U~p;wgO%|Gtvfsz84jGDdUm?^C1a5tQ!hxBfBNv?k>aC6IUAi4 z#We-eIG-rZnLb-t*yA~~&p93j2C1JH5B{^TpYZ(IlZVgJp69&(a&*zZ><{@$c8VYG z|J&2U#KIupcmDmY_@_^=F&7+X+)%nddu24ktuTg+`#)oiZ*wk);<`}vv%AvbkAvL2 zg#jmQWM#Oxx!0lqm0W%nEqXG&yqao|xoU?bqf z_M}0EYoWw6N6C-_RySC-ZeW&LAUNxxz?OrC7QD|N2*otME)Zu+keGK!Vow_eq4&G6O25$J+nP-d+06+USfAiAajn7+Up6qC+|Js*wnB_ zVfw`F6Zj|iPx^iG@RRK#R!2J?`EV{$30g8m$jda<{wd4S`9@AN7pw|AyK>$Yj#V92 z^P@a-7nB9)2e+>jHYuH@dUm#$^XVnJi?3dom6@LTJwyLx$u7>j&2p~OFHFCb{eu1F z^OwzE%6WL(c$<%VBxy)yOIAxRm)I_;KhtL!>*eV)PlOm;Hj$@k-7sVymyNlnvdz(rn$i zpz@&pfb)Uzi}%I!fAG~a38 z*USjB3#$zK8g_k+=e3yEI(Ei{_U$bTl!?|VcYkPUp{<~cvN`i@!aLJmmm5(;kkZXSzKh?@4a&Vo9C#_yJnDk z;`Wi~2YXLfCs^6prv5tjlG*N<9n<`(`R)6b?NhpMyHC09THVY#_CND}TmL%!xBtif zhn1hiKKijHFdk%l%DA^ts&O-OHnTj-OqQkWrmVfJyV>-4>_nY-IC&%GizeqE5dS3o zGuik~y3VYNqNh0KibhHQGB~5=BX>=(ukAd?eSy0CWj}php4rCH@xVQ&V~2dEZKH?wy%>{zv< zv7-Hl>&NLrCBiD4Z#$nHxpBm{^KmiL^PE}6bDqo!nO2g#?&+OHJH?;9Ja>9txlN>L zT|%$U7#p-Jr6TjgrP|XOr#DUe z8}KM1DD+cS<(*G`LCu$zE_K#!3OAX$a>~imdF#GJ?MxO;oSG8)K5P2b=&*V%@u~4^ z3f8Px_hWxnB257FK0_?K`{W?5VTNrirF+qt9$xbNkamv&G-4=GMoa4*R=y_4a)?)oxwe zf498)Ghef;sP(<~Q{L>^s$CJDz1Ow&Yu=@IO?UgHlB9R-e^z&QhkLpI(RuyVORL$x zxxRm$Rg#}`XZ`;Dn>cfW%zEWKtO}maZpgni`|Ygqtp!n9e1{yL9#p@-tfu;Lz>9_F z4&OO^_WsQJ?O!=wdsJ#)vf5v|Mt5=U0^5aq-@oWtJXbbO)_vdh|8?&TA19X{H|-Cf zw_vV@?Z=-_nkGM9p0a%2Tt9o;D>Ls@e)st^Gdnggc5k}#`FZx@CGUK;$A3Th`QG#X z*bjROz9@Z9x~;n1d#&v{TlczxzYjguN9Vsz{eJpwxXrqfFTSs>FTTHA|10aj)#B?v zuIt6luiX3o*c<8Xd1`lMcBt<9`lIaITk&$PcRqJwtNJU}|Jirz?<@9S{IBY_{M(p% zAoszKgaZlZ4@dI9=i_Xj_ixJo%k2*@xu0>rs_drR+do%cUYb{G@28Y=lOHbMv|RZ7 zsk*TLm9L9eKfnL?(Qohb5r1xc;QrZte*e14m7j~=uU@&{>bUZ8`90?RwL~E)H9a%WR_Xoj{Yna%DYi=CroINg16w1-Ypui3%0DIeEoa6}C!XbFK1v0i>ry1t>MrKP@s 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 From 5a98d69dcdf470308823b8648367c2f13b52c593 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Fri, 23 Mar 2018 11:35:27 -0500 Subject: [PATCH 34/57] Fix tab index now that the archive tab is back --- src/tutorials/tutorial_conflictresolution_main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tutorials/tutorial_conflictresolution_main.js b/src/tutorials/tutorial_conflictresolution_main.js index a60a5c8d..3c782af2 100644 --- a/src/tutorials/tutorial_conflictresolution_main.js +++ b/src/tutorials/tutorial_conflictresolution_main.js @@ -65,7 +65,7 @@ function getTutorialSteps() { }, function() { tutorial.text = qsTr("Option A: Switch to the \"Data\"-tab if necessary") - if (!tutorialControl.waitForTabOpen("tabWidget", 1)) { + if (!tutorialControl.waitForTabOpen("tabWidget", 2)) { highlightItem("tabWidget", false) waitForClick() } else { From dcbcb29ec733801025556d294b90c9b8061a31e5 Mon Sep 17 00:00:00 2001 From: Silarn Date: Tue, 3 Apr 2018 14:59:04 -0500 Subject: [PATCH 35/57] Update to allow linking to updated bsatk --- CMakeLists.txt | 1 + src/CMakeLists.txt | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c6351f7..b63e8b81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT SET(DEPENDENCIES_DIR CACHE PATH "") # hint to find qt in dependencies path LIST(APPEND CMAKE_PREFIX_PATH ${QT_ROOT}/lib/cmake) +LIST(APPEND CMAKE_PREFIX_PATH ${LZ4_ROOT}/dll) FILE(GLOB_RECURSE BOOST_ROOT ${DEPENDENCIES_DIR}/boost*/project-config.jam) GET_FILENAME_COMPONENT(BOOST_ROOT ${BOOST_ROOT} DIRECTORY) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ab7b4836..70886f81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -288,11 +288,13 @@ INCLUDE_DIRECTORIES(${project_path}/uibase/src ${project_path}/../usvfs/include ${project_path}/game_gamebryo/src ${project_path}/game_features/src - ${project_path}/githubpp/src) + ${project_path}/githubpp/src + ${LZ4_ROOT}/include) INCLUDE_DIRECTORIES(shared ${ZLIB_INCLUDE_DIRS}) LINK_DIRECTORIES(${lib_path} - ${ZLIB_ROOT}/lib) + ${ZLIB_ROOT}/lib + ${LZ4_ROOT}/dll) EXECUTE_PROCESS( COMMAND git log -1 --format=%h WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} @@ -315,7 +317,7 @@ TARGET_LINK_LIBRARIES(ModOrganizer zlibstatic uibase esptk bsatk githubpp ${usvfs_name} - Dbghelp advapi32 Version Shlwapi) + Dbghelp advapi32 Version Shlwapi liblz4) IF (NOT "${OPTIMIZE_COMPILE_FLAGS}" STREQUAL "") SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES COMPILE_FLAGS_RELWITHDEBINFO ${OPTIMIZE_COMPILE_FLAGS}) From 74dd2bb914a1f2a31506c3544b6ee198f65e2b6b Mon Sep 17 00:00:00 2001 From: Silarn Date: Thu, 5 Apr 2018 23:57:24 -0500 Subject: [PATCH 36/57] Return extraction context menu to archive list --- src/mainwindow.cpp | 12 ++++++++++++ src/mainwindow.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0dbe4d53..faa4b880 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4345,6 +4345,18 @@ void MainWindow::displayColumnSelection(const QPoint &pos) } } +void MainWindow::on_bsaList_customContextMenuRequested(const QPoint &pos) +{ + m_ContextItem = ui->bsaList->itemAt(pos); + +// m_ContextRow = ui->bsaList->indexOfTopLevelItem(ui->bsaList->itemAt(pos)); + + QMenu menu; + menu.addAction(tr("Extract..."), this, SLOT(extractBSATriggered())); + + menu.exec(ui->bsaList->mapToGlobal(pos)); +} + void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int) { m_ArchiveListWriter.write(); diff --git a/src/mainwindow.h b/src/mainwindow.h index f84931ca..d0957305 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -553,6 +553,7 @@ private slots: // ui slots void on_actionUpdate_triggered(); void on_actionEndorseMO_triggered(); + void on_bsaList_customContextMenuRequested(const QPoint &pos); void on_clearFiltersButton_clicked(); void on_btnRefreshData_clicked(); void on_categoriesList_customContextMenuRequested(const QPoint &pos); From fed89352d1c9870bb34cbc1a65c3a8d3043086f9 Mon Sep 17 00:00:00 2001 From: Silarn Date: Fri, 6 Apr 2018 00:56:58 -0500 Subject: [PATCH 37/57] Changes to allow plugin loading in the mod info dialog (and rename SE) --- src/modinfo.cpp | 6 +++--- src/modinfo.h | 1 + src/modinfodialog.h | 1 + src/modinforegular.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/modinfo.cpp b/src/modinfo.cpp index c14eedb7..d80c636b 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -55,7 +55,7 @@ QMutex ModInfo::s_Mutex(QMutex::Recursive); QString ModInfo::s_HiddenExt(".mohidden"); -static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS) +bool ModInfo::ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS) { return QString::compare(LHS->name(), RHS->name(), Qt::CaseInsensitive) < 0; } @@ -98,7 +98,7 @@ QString ModInfo::getContentTypeName(int contentType) case CONTENT_INTERFACE: return tr("UI Changes"); case CONTENT_SOUND: return tr("Sound Effects"); case CONTENT_SCRIPT: return tr("Scripts"); - case CONTENT_SKSE: return tr("SKSE Plugins"); + case CONTENT_SKSE: return tr("Script Extender"); case CONTENT_SKYPROC: return tr("SkyProc Tools"); case CONTENT_MCM: return tr("MCM Data"); default: throw MyException(tr("invalid content type %1").arg(contentType)); @@ -239,7 +239,7 @@ void ModInfo::updateFromDisc(const QString &modDirectory, createFromOverwrite(); - std::sort(s_Collection.begin(), s_Collection.end(), ByName); + std::sort(s_Collection.begin(), s_Collection.end(), ModInfo::ByName); updateIndices(); } diff --git a/src/modinfo.h b/src/modinfo.h index d00c04e7..1ceb8e1f 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -599,6 +599,7 @@ protected: ModInfo(); static void updateIndices(); + static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS); private: diff --git a/src/modinfodialog.h b/src/modinfodialog.h index 312ff99e..e7c70762 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include "modinfo.h" #include "tutorabledialog.h" +#include "plugincontainer.h" #include #include diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 5486bb2c..4572f5bf 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -299,7 +299,7 @@ bool ModInfoRegular::setName(const QString &name) s_ModsByName[m_Name] = index; - std::sort(s_Collection.begin(), s_Collection.end(), ByName); + std::sort(s_Collection.begin(), s_Collection.end(), ModInfo::ByName); updateIndices(); } else { // otherwise mod isn't registered yet? m_Name = name; From a905ce130d0f1f4894f135660d9cf515788bb2ad Mon Sep 17 00:00:00 2001 From: Silarn Date: Fri, 6 Apr 2018 18:25:11 -0500 Subject: [PATCH 38/57] Update About dialog with new contributors (and don't translate names) --- src/aboutdialog.ui | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui index 348a33b0..69e52708 100644 --- a/src/aboutdialog.ui +++ b/src/aboutdialog.ui @@ -6,8 +6,8 @@ 0 0 - 604 - 369 + 1010 + 477 @@ -231,6 +231,11 @@ Alyndiar (French) + + + fruttyx (French) + + Jlkawaii (French) @@ -241,6 +246,11 @@ Rigoletto (French) + + + Yoplala (French) + + Faron (German) @@ -320,12 +330,7 @@ - SuperSandro2000 - - - - - AnyOldName3 + AnyOldName3 @@ -348,6 +353,11 @@ Bridger + + + Brixified + + GamerPoet @@ -363,6 +373,21 @@ GSDFan + + + ogrotten + + + + + Schilduin + + + + + SuperSandro2000 + + Uhuru @@ -383,11 +408,6 @@ thosrtanner - - - ogrotten - - From 5c39a762e68c3559438a622dbf747eb8bddec7ed Mon Sep 17 00:00:00 2001 From: Al12rs Date: Fri, 6 Apr 2018 21:35:15 +0200 Subject: [PATCH 39/57] Allow MO2 shortcuts that open the indicated MO2 instance in the argument if the executable name is omitted. This should be added after the MO2 exe path: ' "moshortcut://myInstanceName:" '. If there are caracters after the ":" then MO2 will assume that is an execuatble and will try to run it. --- src/main.cpp | 66 +++++++++++++++++++++++-------------------- src/moshortcut.cpp | 3 ++ src/moshortcut.h | 3 ++ src/organizercore.cpp | 5 ++-- 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0464ca9a..fc332fe7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -561,36 +561,42 @@ int runApplication(MOApplication &application, SingleInstance &instance, // if we have a command line parameter, it is either a nxm link or // a binary to start - if (arguments.size() > 1) { - if (MOShortcut shortcut{ arguments.at(1) }) { - try { - organizer.runShortcut(shortcut); - return 0; - } catch (const std::exception &e) { - reportError( - QObject::tr("failed to start shortcut: %1").arg(e.what())); - return 1; - } - } else if (OrganizerCore::isNxmLink(arguments.at(1))) { - qDebug("starting download from command line: %s", - qPrintable(arguments.at(1))); - organizer.externalMessage(arguments.at(1)); - } else { - QString exeName = arguments.at(1); - qDebug("starting %s from command line", qPrintable(exeName)); - arguments.removeFirst(); // remove application name (ModOrganizer.exe) - arguments.removeFirst(); // remove binary name - // pass the remaining parameters to the binary - try { - organizer.startApplication(exeName, arguments, QString(), QString()); - return 0; - } catch (const std::exception &e) { - reportError( - QObject::tr("failed to start application: %1").arg(e.what())); - return 1; - } - } - } + if (arguments.size() > 1) { + if (MOShortcut shortcut{ arguments.at(1) }) { + if (shortcut.hasExecutable()) { + try { + organizer.runShortcut(shortcut); + return 0; + } + catch (const std::exception &e) { + reportError( + QObject::tr("failed to start shortcut: %1").arg(e.what())); + return 1; + } + } + } + else if (OrganizerCore::isNxmLink(arguments.at(1))) { + qDebug("starting download from command line: %s", + qPrintable(arguments.at(1))); + organizer.externalMessage(arguments.at(1)); + } + else { + QString exeName = arguments.at(1); + qDebug("starting %s from command line", qPrintable(exeName)); + arguments.removeFirst(); // remove application name (ModOrganizer.exe) + arguments.removeFirst(); // remove binary name + // pass the remaining parameters to the binary + try { + organizer.startApplication(exeName, arguments, QString(), QString()); + return 0; + } + catch (const std::exception &e) { + reportError( + QObject::tr("failed to start application: %1").arg(e.what())); + return 1; + } + } + } QPixmap pixmap(splashPath); QSplashScreen splash(pixmap); diff --git a/src/moshortcut.cpp b/src/moshortcut.cpp index c8c2ef6f..aad7380e 100644 --- a/src/moshortcut.cpp +++ b/src/moshortcut.cpp @@ -24,6 +24,7 @@ along with Mod Organizer. If not, see . MOShortcut::MOShortcut(const QString& link) : m_valid(link.startsWith("moshortcut://")) , m_hasInstance(false) + , m_hasExecutable(false) { if (m_valid) { int start = (int)strlen("moshortcut://"); @@ -35,5 +36,7 @@ MOShortcut::MOShortcut(const QString& link) } else m_executable = link.mid(start); + if(!(m_executable=="")) + m_hasExecutable=true; } } diff --git a/src/moshortcut.h b/src/moshortcut.h index 7b7574b9..2ce54910 100644 --- a/src/moshortcut.h +++ b/src/moshortcut.h @@ -33,6 +33,8 @@ public: operator bool() const { return m_valid; } bool hasInstance() const { return m_hasInstance; } + + bool hasExecutable() const { return m_hasExecutable; } const QString& instance() const { return m_instance; } @@ -43,4 +45,5 @@ private: QString m_executable; bool m_valid; bool m_hasInstance; + bool m_hasExecutable; }; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index b84488da..0398e9ac 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -602,8 +602,9 @@ void OrganizerCore::downloadRequestedNXM(const QString &url) void OrganizerCore::externalMessage(const QString &message) { - if (MOShortcut moshortcut{ message }) { - runShortcut(moshortcut); + if (MOShortcut moshortcut{ message } ) { + if(moshortcut.hasExecutable()) + runShortcut(moshortcut); } else if (isNxmLink(message)) { MessageDialog::showMessage(tr("Download started"), qApp->activeWindow()); From fd9eb032b6df5eafa89a60a515963ba7d4652f24 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Fri, 23 Mar 2018 17:48:00 +0100 Subject: [PATCH 40/57] Added file preview in conflicts tab in the mod information dialog. The preview is not working for the lower file list for some reason but I left the setup of the context menu and all in case somebody else can figure out what I'm missing. --- src/mainwindow.cpp | 2 +- src/modinfodialog.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++- src/modinfodialog.h | 8 +++- src/modinfodialog.ui | 6 +++ 4 files changed, 110 insertions(+), 4 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index faa4b880..d9d83231 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2450,7 +2450,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, } } else { modInfo->saveMeta(); - ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN), this); + ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN), &m_OrganizerCore, &m_PluginContainer,this); connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString))); connect(&dialog, SIGNAL(downloadRequest(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection); diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index ccd2a122..f2042d15 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -30,6 +30,10 @@ along with Mod Organizer. If not, see . #include "questionboxmemory.h" #include "settings.h" #include "categories.h" +#include "organizercore.h" +#include "pluginlistsortproxy.h" +#include "previewgenerator.h" +#include "previewdialog.h" #include #include @@ -66,11 +70,12 @@ static bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS } -ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, QWidget *parent) +ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer, QWidget *parent) : TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo), m_ThumbnailMapper(this), m_RequestStarted(false), m_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr), - m_Directory(directory), m_Origin(nullptr) + m_Directory(directory), m_Origin(nullptr), + m_OrganizerCore(organizerCore), m_PluginContainer(pluginContainer) { ui->setupUi(this); this->setWindowTitle(modInfo->name()); @@ -1198,6 +1203,69 @@ void ModInfoDialog::unhideConflictFile() } +void ModInfoDialog::previewDataFile() +{ + QString fileName = QDir::fromNativeSeparators(m_ConflictsContextItem->data(0, Qt::UserRole).toString()); + + // what we have is an absolute path to the file in its actual location (for the primary origin) + // what we want is the path relative to the virtual data directory + + // we need to look in the virtual directory for the file to make sure the info is up to date. + + // check if the file comes from the actual data folder instead of a mod + QDir gameDirectory = m_OrganizerCore->managedGame()->dataDirectory().absolutePath(); + QString relativePath = gameDirectory.relativeFilePath(fileName); + QDir direRelativePath = gameDirectory.relativeFilePath(fileName); + // if the file is on a different drive the dirRelativePath will actually be an absolute path so we make sure that is not the case + if (!direRelativePath.isAbsolute() && !relativePath.startsWith("..")) { + fileName = relativePath; + } + else { + // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative directory + int offset = m_OrganizerCore->settings().getModDirectory().size() + 1; + offset = fileName.indexOf("/", offset); + fileName = fileName.mid(offset + 1); + } + + + + const FileEntry::Ptr file = m_OrganizerCore->directoryStructure()->searchFile(ToWString(fileName), nullptr); + + if (file.get() == nullptr) { + reportError(tr("file not found: %1").arg(fileName)); + return; + } + + // set up preview dialog + PreviewDialog preview(fileName); + auto addFunc = [&](int originId) { + FilesOrigin &origin = m_OrganizerCore->directoryStructure()->getOriginByID(originId); + QString filePath = QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName; + if (QFile::exists(filePath)) { + // it's very possible the file doesn't exist, because it's inside an archive. we don't support that + QWidget *wid = m_PluginContainer->previewGenerator().genPreview(filePath); + if (wid == nullptr) { + reportError(tr("failed to generate preview for %1").arg(filePath)); + } + else { + preview.addVariant(ToQString(origin.getName()), wid); + } + } + }; + + addFunc(file->getOrigin()); + for (auto alt : file->getAlternatives()) { + addFunc(alt.first); + } + if (preview.numVariants() > 0) { + preview.exec(); + } + else { + QMessageBox::information(this, tr("Sorry"), tr("Sorry, can't preview anything. This function currently does not support extracting from bsas.")); + } +} + + void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &pos) { m_ConflictsContextItem = ui->overwriteTree->itemAt(pos.x(), pos.y()); @@ -1211,11 +1279,37 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po } else { menu.addAction(tr("Hide"), this, SLOT(hideConflictFile())); } + + QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString(); + if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) { + menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); + } + menu.exec(ui->overwriteTree->mapToGlobal(pos)); } } } +void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint &pos) +{ + //For some reason the m_ConflictsContextItem does not pick up valid data from the overwrittenTree. + //TODO: find out what is going wrong. + /*m_ConflictsContextItem = ui->overwrittenTree->itemAt(pos.x(), pos.y()); + + if (m_ConflictsContextItem != nullptr) { + if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) { + QMenu menu; + + QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString(); + if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) { + menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); + } + + menu.exec(ui->overwrittenTree->mapToGlobal(pos)); + } + }*/ +} + void ModInfoDialog::on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int) { diff --git a/src/modinfodialog.h b/src/modinfodialog.h index e7c70762..ab878cf9 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -24,6 +24,7 @@ along with Mod Organizer. If not, see . #include "modinfo.h" #include "tutorabledialog.h" #include "plugincontainer.h" +#include "organizercore.h" #include #include @@ -77,7 +78,7 @@ public: * @param modInfo info structure about the mod to display * @param parent parend widget **/ - explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, QWidget *parent = 0); + explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer,QWidget *parent = 0); ~ModInfoDialog(); /** @@ -156,6 +157,7 @@ private slots: void hideConflictFile(); void unhideConflictFile(); + void previewDataFile(); void thumbnailClicked(const QString &fileName); void linkClicked(const QUrl &url); @@ -186,6 +188,7 @@ private slots: void on_overwriteTree_itemDoubleClicked(QTreeWidgetItem *item, int column); void on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int column); void on_overwriteTree_customContextMenuRequested(const QPoint &pos); + void on_overwrittenTree_customContextMenuRequested(const QPoint &pos); void on_fileTree_customContextMenuRequested(const QPoint &pos); void on_refreshButton_clicked(); @@ -209,6 +212,9 @@ private: QSignalMapper m_ThumbnailMapper; QString m_RootPath; + OrganizerCore *m_OrganizerCore; + PluginContainer *m_PluginContainer; + QFileSystemModel *m_FileSystemModel; QTreeView *m_FileTree; QModelIndexList m_FileSelection; diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index b5331424..05415445 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -489,6 +489,9 @@ Most mods do not have optional esps, so chances are good you are looking at an e + + Qt::CustomContextMenu + Qt::ElideLeft @@ -498,6 +501,9 @@ Most mods do not have optional esps, so chances are good you are looking at an e true + + 2 + 365 From a1d92fb67316d907b930737658bdb841fd8bc486 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 7 Apr 2018 17:12:22 -0500 Subject: [PATCH 41/57] Fix up CMAKE to use /MP and allow building through umbrella --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b63e8b81..5d069383 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12) + +ADD_COMPILE_OPTIONS($<$:/MP>) PROJECT(organizer) From d62669e1b48687842fb856f2190c3bd84c514fd0 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 7 Apr 2018 18:58:12 -0500 Subject: [PATCH 42/57] Fix overwritten file preview --- src/modinfodialog.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index f2042d15..f8655d6b 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -298,7 +298,9 @@ void ModInfoDialog::refreshLists() QStringList fields(relativeName); fields.append(ToQString(realOrigin.getName())); QTreeWidgetItem *item = new QTreeWidgetItem(fields); + item->setData(0, Qt::UserRole, fileName); item->setData(1, Qt::UserRole, ToQString(realOrigin.getName())); + item->setData(1, Qt::UserRole + 2, archive); ui->overwrittenTree->addTopLevelItem(item); ++numOverwritten; } @@ -1280,10 +1282,10 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po menu.addAction(tr("Hide"), this, SLOT(hideConflictFile())); } - QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString(); - if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) { - menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); - } + QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString(); + if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) { + menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); + } menu.exec(ui->overwriteTree->mapToGlobal(pos)); } @@ -1294,7 +1296,7 @@ void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint & { //For some reason the m_ConflictsContextItem does not pick up valid data from the overwrittenTree. //TODO: find out what is going wrong. - /*m_ConflictsContextItem = ui->overwrittenTree->itemAt(pos.x(), pos.y()); + m_ConflictsContextItem = ui->overwrittenTree->itemAt(pos.x(), pos.y()); if (m_ConflictsContextItem != nullptr) { if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) { @@ -1307,7 +1309,7 @@ void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint & menu.exec(ui->overwrittenTree->mapToGlobal(pos)); } - }*/ + } } From b409a0bef934eb20d10ecd2f7448c2da00c8e500 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 7 Apr 2018 20:09:41 -0500 Subject: [PATCH 43/57] Install the translation file (we need at least one) --- src/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 70886f81..ef009e03 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -253,6 +253,7 @@ FIND_PACKAGE(Qt5LinguistTools) QT5_WRAP_UI(organizer_UIHDRS ${organizer_UIS}) QT5_ADD_RESOURCES(organizer_RCCPPS ${organizer_QRCS}) QT5_CREATE_TRANSLATION(organizer_translations_qm ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/organizer_en.ts) +ADD_CUSTOM_TARGET(translations DEPENDS ${organizer_translations_qm}) INCLUDE_DIRECTORIES(${Qt5Declarative_INCLUDES}) @@ -373,6 +374,8 @@ INSTALL( # qdds.dll needs installing manually as Qt no longer ships with it by default. INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../qdds.dll DESTINATION bin/dlls/imageformats) +install(FILES ${organizer_translations_qm} DESTINATION bin/translations) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/stylesheets ${CMAKE_CURRENT_SOURCE_DIR}/tutorials DESTINATION bin) From cc2bd152568a4f1164a0a4ba5e6232e77e7c9945 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 7 Apr 2018 22:18:45 -0500 Subject: [PATCH 44/57] Fix for re-downloading a mod already downloading --- src/downloadmanager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index a4fde093..c0d7fbf3 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -460,7 +460,14 @@ void DownloadManager::addNXMDownload(const QString &url) return; } + if (m_PendingDownloads.contains(std::pair(nxmInfo.modId(), nxmInfo.fileId()))) { + qDebug("download requested is already started (mod: %s, file: %s)", qPrintable(nxmInfo.modId()), qPrintable(nxmInfo.fileId())); + QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been started."), QMessageBox::Ok); + return; + } + emit aboutToUpdate(); + m_PendingDownloads.append(std::make_pair(nxmInfo.modId(), nxmInfo.fileId())); emit update(-1); From 7eba6837dd65eb0e5f3b9f71e67e82fe553a56a6 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 7 Apr 2018 23:54:22 -0500 Subject: [PATCH 45/57] Prevent redownloading a mod if the download is still in progress --- src/downloadmanager.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index c0d7fbf3..45070885 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -460,10 +460,25 @@ void DownloadManager::addNXMDownload(const QString &url) return; } - if (m_PendingDownloads.contains(std::pair(nxmInfo.modId(), nxmInfo.fileId()))) { - qDebug("download requested is already started (mod: %s, file: %s)", qPrintable(nxmInfo.modId()), qPrintable(nxmInfo.fileId())); - QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been started."), QMessageBox::Ok); - return; + for (auto pair : m_PendingDownloads) { + if (pair.first == nxmInfo.modId() && pair.second == nxmInfo.fileId()) { + qDebug("download requested is already started (mod id: %s, file id: %s)", qPrintable(nxmInfo.modId()), qPrintable(nxmInfo.fileId())); + QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been queued."), QMessageBox::Ok); + return; + } + } + + for (DownloadInfo *download : m_ActiveDownloads) { + if (download->m_FileInfo->modID == nxmInfo.modId() && download->m_FileInfo->fileID == nxmInfo.fileId()) { + if (download->m_State == STATE_DOWNLOADING || download->m_State == STATE_PAUSED || download->m_State == STATE_STARTED) { + qDebug("download requested is already started (mod: %s, file: %s)", qPrintable(download->m_FileInfo->modName), + qPrintable(download->m_FileInfo->fileName)); + + QMessageBox::information(nullptr, tr("Already Started"), tr("There is already a download started for this file (%2).") + .arg(download->m_FileInfo->modName).arg(download->m_FileInfo->name), QMessageBox::Ok); + return; + } + } } emit aboutToUpdate(); From 0f8852f487cb1f8b993141042da4196db965e038 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sun, 8 Apr 2018 03:58:08 -0500 Subject: [PATCH 46/57] Also mark hidden downloads as uninstalled; refresh plugins after files --- src/downloadmanager.cpp | 20 ++++++++++++++++++++ src/downloadmanager.h | 3 +++ src/mainwindow.cpp | 6 ++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 45070885..161656b2 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -918,6 +918,10 @@ void DownloadManager::markInstalled(int index) setState(m_ActiveDownloads.at(index), STATE_INSTALLED); } +DownloadManager::DownloadInfo* DownloadManager::getDownloadInfo(QString fileName) +{ + return DownloadInfo::createFromMeta(fileName, true); +} void DownloadManager::markUninstalled(int index) { @@ -933,6 +937,22 @@ void DownloadManager::markUninstalled(int index) } +void DownloadManager::markUninstalled(QString fileName) +{ + int index = indexByName(fileName); + if (index >= 0) { + markUninstalled(index); + } else { + DownloadInfo *info = getDownloadInfo(fileName); + if (info != nullptr) { + QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat); + metaFile.setValue("uninstalled", true); + setState(info, STATE_UNINSTALLED); + } + } +} + + QString DownloadManager::getDownloadFileName(const QString &baseName) const { QString fullPath = m_OutputDirectory + "/" + baseName; diff --git a/src/downloadmanager.h b/src/downloadmanager.h index e63a0113..059c6cb5 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -314,6 +314,8 @@ public: */ void markUninstalled(int index); + void markUninstalled(QString download); + /** * @brief refreshes the list of downloads */ @@ -431,6 +433,7 @@ private slots: private: void createMetaFile(DownloadInfo *info); + DownloadManager::DownloadInfo* getDownloadInfo(QString fileName); public: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d9d83231..48a09718 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1980,6 +1980,7 @@ void MainWindow::directory_refreshed() refreshDataTree(); updateProblemsButton(); statusBar()->hide(); + m_OrganizerCore.refreshESPList(); } void MainWindow::modorder_changed() @@ -2307,10 +2308,7 @@ void MainWindow::removeMod_clicked() void MainWindow::modRemoved(const QString &fileName) { if (!fileName.isEmpty() && !QFileInfo(fileName).isAbsolute()) { - int index = m_OrganizerCore.downloadManager()->indexByName(fileName); - if (index >= 0) { - m_OrganizerCore.downloadManager()->markUninstalled(index); - } + m_OrganizerCore.downloadManager()->markUninstalled(fileName); } } From fb1c3765338d600a6362c6583b473de9dd26dc02 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 8 Apr 2018 14:41:03 +0200 Subject: [PATCH 47/57] Added "Open/Execute" context menu entry to the conflicts tab in the modinfodialog. --- src/modinfodialog.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++- src/modinfodialog.h | 3 ++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index f8655d6b..6a53d915 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -20,6 +20,7 @@ along with Mod Organizer. If not, see . #include "modinfodialog.h" #include "ui_modinfodialog.h" #include "descriptionpage.h" +#include "mainwindow.h" #include "iplugingame.h" #include "nexusinterface.h" @@ -44,6 +45,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include @@ -1204,6 +1206,88 @@ void ModInfoDialog::unhideConflictFile() } } +int ModInfoDialog::getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments) +{ + QString extension = targetInfo.suffix(); + if ((extension.compare("cmd", Qt::CaseInsensitive) == 0) || + (extension.compare("com", Qt::CaseInsensitive) == 0) || + (extension.compare("bat", Qt::CaseInsensitive) == 0)) { + binaryInfo = QFileInfo("C:\\Windows\\System32\\cmd.exe"); + arguments = QString("/C \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath())); + return 1; + } + else if (extension.compare("exe", Qt::CaseInsensitive) == 0) { + binaryInfo = targetInfo; + return 1; + } + else if (extension.compare("jar", Qt::CaseInsensitive) == 0) { + // types that need to be injected into + std::wstring targetPathW = ToWString(targetInfo.absoluteFilePath()); + QString binaryPath; + + { // try to find java automatically + WCHAR buffer[MAX_PATH]; + if (::FindExecutableW(targetPathW.c_str(), nullptr, buffer) > (HINSTANCE)32) { + DWORD binaryType = 0UL; + if (!::GetBinaryTypeW(buffer, &binaryType)) { + qDebug("failed to determine binary type of \"%ls\": %lu", buffer, ::GetLastError()); + } + else if (binaryType == SCS_32BIT_BINARY) { + binaryPath = ToQString(buffer); + } + } + } + if (binaryPath.isEmpty() && (extension == "jar")) { + // second attempt: look to the registry + QSettings javaReg("HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Runtime Environment", QSettings::NativeFormat); + if (javaReg.contains("CurrentVersion")) { + QString currentVersion = javaReg.value("CurrentVersion").toString(); + binaryPath = javaReg.value(QString("%1/JavaHome").arg(currentVersion)).toString().append("\\bin\\javaw.exe"); + } + } + if (binaryPath.isEmpty()) { + binaryPath = QFileDialog::getOpenFileName(this, tr("Select binary"), QString(), tr("Binary") + " (*.exe)"); + } + if (binaryPath.isEmpty()) { + return 0; + } + binaryInfo = QFileInfo(binaryPath); + if (extension == "jar") { + arguments = QString("-jar \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath())); + } + else { + arguments = QString("\"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath())); + } + return 1; + } + else { + return 2; + } +} + +void ModInfoDialog::openDataFile() +{ + if (m_ConflictsContextItem != nullptr) { + QFileInfo targetInfo(m_ConflictsContextItem->data(0, Qt::UserRole).toString()); + QFileInfo binaryInfo; + QString arguments; + switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) { + case 1: { + m_OrganizerCore->spawnBinaryDirect( + binaryInfo, arguments, m_OrganizerCore->currentProfile()->name(), + targetInfo.absolutePath(), "", ""); + } break; + case 2: { + ::ShellExecuteW(nullptr, L"open", + ToWString(targetInfo.absoluteFilePath()).c_str(), + nullptr, nullptr, SW_SHOWNORMAL); + } break; + default: { + // nop + } break; + } + } +} void ModInfoDialog::previewDataFile() { @@ -1282,6 +1366,8 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po menu.addAction(tr("Hide"), this, SLOT(hideConflictFile())); } + menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile())); + QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString(); if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) { menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); @@ -1294,14 +1380,14 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po void ModInfoDialog::on_overwrittenTree_customContextMenuRequested(const QPoint &pos) { - //For some reason the m_ConflictsContextItem does not pick up valid data from the overwrittenTree. - //TODO: find out what is going wrong. m_ConflictsContextItem = ui->overwrittenTree->itemAt(pos.x(), pos.y()); if (m_ConflictsContextItem != nullptr) { if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) { QMenu menu; + menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile())); + QString fileName = m_ConflictsContextItem->data(0, Qt::UserRole).toString(); if (m_PluginContainer->previewGenerator().previewSupported(QFileInfo(fileName).suffix())) { menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); diff --git a/src/modinfodialog.h b/src/modinfodialog.h index ab878cf9..9eb17be5 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -157,7 +157,10 @@ private slots: void hideConflictFile(); void unhideConflictFile(); + int getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments); void previewDataFile(); + void openDataFile(); + void thumbnailClicked(const QString &fileName); void linkClicked(const QUrl &url); From 208eaccbf7f1fc0441861d55c68c4b66e5c7d387 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sun, 8 Apr 2018 14:56:46 -0500 Subject: [PATCH 48/57] Updates to allow a full plugin data refresh in certain circumstances --- src/mainwindow.cpp | 5 ++--- src/organizercore.cpp | 16 ++++++++-------- src/organizercore.h | 2 +- src/pluginlist.cpp | 9 ++++++++- src/pluginlist.h | 3 ++- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 48a09718..85e96993 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1980,7 +1980,6 @@ void MainWindow::directory_refreshed() refreshDataTree(); updateProblemsButton(); statusBar()->hide(); - m_OrganizerCore.refreshESPList(); } void MainWindow::modorder_changed() @@ -4811,7 +4810,7 @@ void MainWindow::on_bossButton_clicked() } m_IntegratedBrowser.openUrl(url); } - m_OrganizerCore.refreshESPList(); + m_OrganizerCore.refreshESPList(false); m_OrganizerCore.savePluginList(); } } @@ -4888,7 +4887,7 @@ void MainWindow::on_restoreButton_clicked() QMessageBox::critical(this, tr("Restore failed"), tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError()))); } - m_OrganizerCore.refreshESPList(); + m_OrganizerCore.refreshESPList(true); } } diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 0398e9ac..895b3b9c 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1107,7 +1107,7 @@ void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &argument } refreshDirectoryStructure(); - refreshESPList(); + refreshESPList(true); savePluginList(); //These callbacks should not fiddle with directoy structure and ESPs. @@ -1559,13 +1559,13 @@ void OrganizerCore::refreshModList(bool saveChanges) refreshDirectoryStructure(); } -void OrganizerCore::refreshESPList() +void OrganizerCore::refreshESPList(bool force) { if (m_DirectoryUpdate) { // don't mess up the esp list if we're currently updating the directory // structure - m_PostRefreshTasks.append([this]() { - this->refreshESPList(); + m_PostRefreshTasks.append([=]() { + this->refreshESPList(force); }); return; } @@ -1574,7 +1574,7 @@ void OrganizerCore::refreshESPList() // clear list try { m_PluginList.refresh(m_CurrentProfile->name(), *m_DirectoryStructure, - m_CurrentProfile->getLockedOrderFileName()); + m_CurrentProfile->getLockedOrderFileName(), force); } catch (const std::exception &e) { reportError(tr("Failed to refresh list of esps: %1").arg(e.what())); } @@ -1615,7 +1615,7 @@ void OrganizerCore::refreshBSAList() void OrganizerCore::refreshLists() { if ((m_CurrentProfile != nullptr) && m_DirectoryStructure->isPopulated()) { - refreshESPList(); + refreshESPList(true); refreshBSAList(); } // no point in refreshing lists if no files have been added to the directory // tree @@ -1678,7 +1678,7 @@ void OrganizerCore::updateModInDirectoryStructure(unsigned int index, modInfo->stealFiles()); DirectoryRefresher::cleanStructure(m_DirectoryStructure); // need to refresh plugin list now so we can activate esps - refreshESPList(); + refreshESPList(true); // activate all esps of the specified mod so the bsas get activated along with // it updateModActiveState(index, true); @@ -1839,7 +1839,7 @@ void OrganizerCore::modStatusChanged(unsigned int index) updateModInDirectoryStructure(index, modInfo); } else { updateModActiveState(index, false); - refreshESPList(); + refreshESPList(true); if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) { FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())); diff --git a/src/organizercore.h b/src/organizercore.h index 9e81f0c3..54d9dd6d 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -130,7 +130,7 @@ public: void prepareStart(); - void refreshESPList(); + void refreshESPList(bool force = false); void refreshBSAList(); void refreshDirectoryStructure(); diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 8bf438f1..9bbcdc11 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -140,8 +140,15 @@ void PluginList::highlightPlugins(const QItemSelection &selected, const MOShared void PluginList::refresh(const QString &profileName , const DirectoryEntry &baseDirectory - , const QString &lockedOrderFile) + , const QString &lockedOrderFile + , bool force) { + if (force) { + m_ESPs.clear(); + m_ESPsByName.clear(); + m_ESPsByPriority.clear(); + } + ChangeBracket layoutChange(this); QStringList primaryPlugins = m_GamePlugin->primaryPlugins(); diff --git a/src/pluginlist.h b/src/pluginlist.h index 4762f79f..f9173810 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -116,7 +116,8 @@ public: **/ void refresh(const QString &profileName , const MOShared::DirectoryEntry &baseDirectory - , const QString &lockedOrderFile); + , const QString &lockedOrderFile + , bool refresh); /** * @brief enable a plugin based on its name From 47dc5cded72ff79a3964ef39b7ad23e6b27fcdff Mon Sep 17 00:00:00 2001 From: Silarn Date: Mon, 9 Apr 2018 12:17:15 -0500 Subject: [PATCH 49/57] Add DXTex header licenses for new BSATK handling of FO4 texture BA2s --- src/aboutdialog.cpp | 2 ++ src/aboutdialog.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index 5ac05df7..a350036f 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -54,6 +54,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) m_LicenseFiles[LICENSE_SIP] = "sip.txt"; m_LicenseFiles[LICENSE_CASTLE] = "Castle.txt"; m_LicenseFiles[LICENSE_ANTLR] = "AntlrBuildTask.txt"; + m_LicenseFiles[LICENSE_DXTEX] = "DXTex.txt"; addLicense("Qt", LICENSE_LGPL3); addLicense("Qt Json", LICENSE_GPL3); @@ -73,6 +74,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) addLicense("spdlog", LICENSE_SPDLOG); addLicense("{fmt}", LICENSE_FMT); addLicense("SIP", LICENSE_SIP); + addLicense("DXTex Headers", LICENSE_DXTEX); ui->nameLabel->setText(QString("%1 %2").arg(ui->nameLabel->text()).arg(version)); #if defined(HGID) diff --git a/src/aboutdialog.h b/src/aboutdialog.h index a67c9c73..3ae3237b 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -60,7 +60,8 @@ private: LICENSE_FMT, LICENSE_SIP, LICENSE_CASTLE, - LICENSE_ANTLR + LICENSE_ANTLR, + LICENSE_DXTEX }; private: From 9465966b2c782a3b86ed933e868b306194289bbd Mon Sep 17 00:00:00 2001 From: Silarn Date: Mon, 9 Apr 2018 12:18:22 -0500 Subject: [PATCH 50/57] Created threaded process for writing mod meta files to prevent hangs --- src/mainwindow.cpp | 14 +++++++++----- src/mainwindow.h | 3 +++ src/nexusinterface.cpp | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 85e96993..1e2ec68b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -153,8 +153,6 @@ along with Mod Organizer. If not, see . #include #include -#include - #ifndef Q_MOC_RUN #include #include @@ -901,6 +899,8 @@ void MainWindow::cleanup() QWebEngineProfile::defaultProfile()->clearAllVisitedLinks(); m_IntegratedBrowser.close(); + m_SaveMetaTimer.stop(); + m_MetaSave.waitForFinished(); } @@ -1568,9 +1568,13 @@ void MainWindow::checkBSAList() void MainWindow::saveModMetas() { - for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(i); - modInfo->saveMeta(); + if (m_MetaSave.isFinished()) { + m_MetaSave = QtConcurrent::run([this]() { + for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(i); + modInfo->saveMeta(); + } + }); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index d0957305..ef6eb262 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -63,6 +63,7 @@ namespace MOShared { class DirectoryEntry; } #include #include #include +#include class QAction; class QAbstractItemModel; @@ -336,6 +337,8 @@ private: QTimer m_SaveMetaTimer; QTimer m_UpdateProblemsTimer; + QFuture m_MetaSave; + QTime m_StartTime; //SaveGameInfoWidget *m_CurrentSaveView; MOBase::ISaveGameInfoWidget *m_CurrentSaveView; diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index eba02a6f..97186e8b 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -500,7 +500,7 @@ void NexusInterface::requestFinished(std::list::iterator iter) iter->m_URL = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString(); iter->m_Reroute = true; m_RequestQueue.enqueue(*iter); - nextRequest(); + //nextRequest(); return; } QByteArray data = reply->readAll(); From 5a24d2b60cbe93cabb8070ddbdccb17801bee8eb Mon Sep 17 00:00:00 2001 From: Silarn Date: Tue, 10 Apr 2018 01:53:59 -0500 Subject: [PATCH 51/57] Minor improvements to download hiding --- src/downloadmanager.cpp | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 161656b2..8977492c 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -580,36 +580,20 @@ void DownloadManager::removeDownload(int index, bool deleteFile) emit aboutToUpdate(); if (index < 0) { - if (index == -1) { - DownloadState minState = STATE_READY; + DownloadState minState = index == -1 ? STATE_READY : STATE_INSTALLED; index = 0; for (QVector::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) { if ((*iter)->m_State >= minState) { removeFile(index, deleteFile); delete *iter; iter = m_ActiveDownloads.erase(iter); + QCoreApplication::processEvents(); } else { ++iter; ++index; } } - } - else { - DownloadState minState = STATE_INSTALLED; - index = 0; - for (QVector::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) { - if ((*iter)->m_State == minState) { - removeFile(index, deleteFile); - delete *iter; - iter = m_ActiveDownloads.erase(iter); - } - else { - ++iter; - ++index; - } - } - } } else { if (index >= m_ActiveDownloads.size()) { reportError(tr("remove: invalid download index %1").arg(index)); From c4bfee0089512e37a84742cf3981545bc0072413 Mon Sep 17 00:00:00 2001 From: Silarn Date: Tue, 10 Apr 2018 23:28:33 -0500 Subject: [PATCH 52/57] Prep for Qt 5.11 (backward-compatible) --- src/CMakeLists.txt | 8 ++++---- src/downloadmanager.cpp | 2 +- src/mainwindow.cpp | 1 + src/queryoverwritedialog.cpp | 2 ++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ef009e03..fef640b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED (VERSION 2.8) +CMAKE_MINIMUM_REQUIRED (VERSION 2.8.11) CMAKE_POLICY(SET CMP0020 NEW) #CMAKE_POLICY(SET CMP0043 NEW) @@ -249,6 +249,8 @@ FIND_PACKAGE(Qt5Quick REQUIRED) FIND_PACKAGE(Qt5Network REQUIRED) FIND_PACKAGE(Qt5WinExtras REQUIRED) FIND_PACKAGE(Qt5WebEngineWidgets REQUIRED) +FIND_PACKAGE(Qt5Script REQUIRED) +FIND_PACKAGE(Qt5Qml REQUIRED) FIND_PACKAGE(Qt5LinguistTools) QT5_WRAP_UI(organizer_UIHDRS ${organizer_UIS}) QT5_ADD_RESOURCES(organizer_RCCPPS ${organizer_QRCS}) @@ -314,6 +316,7 @@ ENDIF() ADD_EXECUTABLE(ModOrganizer WIN32 ${organizer_HDRS} ${organizer_SRCS} ${organizer_UIHDRS} ${organizer_RCS} ${organizer_RCCPPS} ${organizer_translations_qm}) TARGET_LINK_LIBRARIES(ModOrganizer Qt5::Widgets Qt5::WinExtras Qt5::WebEngineWidgets Qt5::Quick + Qt5::Script Qt5::Qml Qt5::QuickWidgets Qt5::Network ${Boost_LIBRARIES} zlibstatic uibase esptk bsatk githubpp @@ -327,9 +330,6 @@ SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/LARGEADDRESSAWARE ${OPTIMIZE_LINK_FLAGS}") -QT5_USE_MODULES(ModOrganizer Widgets Script Qml QuickWidgets Quick Network WebEngineWidgets) - - ############### ## Installation diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 8977492c..c935d20b 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -462,7 +462,7 @@ void DownloadManager::addNXMDownload(const QString &url) for (auto pair : m_PendingDownloads) { if (pair.first == nxmInfo.modId() && pair.second == nxmInfo.fileId()) { - qDebug("download requested is already started (mod id: %s, file id: %s)", qPrintable(nxmInfo.modId()), qPrintable(nxmInfo.fileId())); + qDebug("download requested is already started (mod id: %s, file id: %s)", qPrintable(QString(nxmInfo.modId())), qPrintable(QString(nxmInfo.fileId()))); QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been queued."), QMessageBox::Ok); return; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1e2ec68b..0f66e505 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -89,6 +89,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include diff --git a/src/queryoverwritedialog.cpp b/src/queryoverwritedialog.cpp index 932b2637..eb67719d 100644 --- a/src/queryoverwritedialog.cpp +++ b/src/queryoverwritedialog.cpp @@ -20,6 +20,8 @@ along with Mod Organizer. If not, see . #include "queryoverwritedialog.h" #include "ui_queryoverwritedialog.h" +#include + QueryOverwriteDialog::QueryOverwriteDialog(QWidget *parent, Backup b) : QDialog(parent), ui(new Ui::QueryOverwriteDialog), m_Action(ACT_NONE) From e33da8402c9f843b2efe3883fba518bdd42bcdd3 Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 11 Apr 2018 00:55:52 -0500 Subject: [PATCH 53/57] Allow multi-extract via archive origin entry in the BSA tab --- src/mainwindow.cpp | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0f66e505..abcb5312 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4290,27 +4290,40 @@ bool MainWindow::extractProgress(QProgressDialog &progress, int percentage, std: void MainWindow::extractBSATriggered() { QTreeWidgetItem *item = m_ContextItem; + QString origin; QString targetFolder = FileDialogMemory::getExistingDirectory("extractBSA", this, tr("Extract BSA")); + QStringList archives = {}; if (!targetFolder.isEmpty()) { - BSA::Archive archive; - QString originPath = QDir::fromNativeSeparators(ToQString(m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(item->text(1))).getPath())); - QString archivePath = QString("%1\\%2").arg(originPath).arg(item->text(0)); - - BSA::EErrorCode result = archive.read(archivePath.toLocal8Bit().constData(), true); - if ((result != BSA::ERROR_NONE) && (result != BSA::ERROR_INVALIDHASHES)) { - reportError(tr("failed to read %1: %2").arg(archivePath).arg(result)); - return; + if (!item->parent()) { + for (int i = 0; i < item->childCount(); ++i) { + archives.append(item->child(i)->text(0)); + } + origin = QDir::fromNativeSeparators(ToQString(m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(item->text(0))).getPath())); + } else { + origin = QDir::fromNativeSeparators(ToQString(m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(item->text(1))).getPath())); + archives = QStringList({ item->text(0) }); } - QProgressDialog progress(this); - progress.setMaximum(100); - progress.setValue(0); - progress.show(); - archive.extractAll(QDir::toNativeSeparators(targetFolder).toLocal8Bit().constData(), - boost::bind(&MainWindow::extractProgress, this, boost::ref(progress), _1, _2)); - if (result == BSA::ERROR_INVALIDHASHES) { - reportError(tr("This archive contains invalid hashes. Some files may be broken.")); + for (auto archiveName : archives) { + BSA::Archive archive; + QString archivePath = QString("%1\\%2").arg(origin).arg(archiveName); + BSA::EErrorCode result = archive.read(archivePath.toLocal8Bit().constData(), true); + if ((result != BSA::ERROR_NONE) && (result != BSA::ERROR_INVALIDHASHES)) { + reportError(tr("failed to read %1: %2").arg(archivePath).arg(result)); + return; + } + + QProgressDialog progress(this); + progress.setMaximum(100); + progress.setValue(0); + progress.show(); + archive.extractAll(QDir::toNativeSeparators(targetFolder).toLocal8Bit().constData(), + boost::bind(&MainWindow::extractProgress, this, boost::ref(progress), _1, _2)); + if (result == BSA::ERROR_INVALIDHASHES) { + reportError(tr("This archive contains invalid hashes. Some files may be broken.")); + } + archive.close(); } } } From e037caf58e918c5bf4693e800069098d74ff5e96 Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 11 Apr 2018 10:58:22 -0500 Subject: [PATCH 54/57] Fix both remove and reinstall updating hidden downloads --- src/downloadmanager.cpp | 21 +++++++++++++++++++-- src/downloadmanager.h | 2 ++ src/organizercore.cpp | 2 ++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index c935d20b..569a7d31 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -902,6 +902,22 @@ void DownloadManager::markInstalled(int index) setState(m_ActiveDownloads.at(index), STATE_INSTALLED); } +void DownloadManager::markInstalled(QString fileName) +{ + int index = indexByName(fileName); + if (index >= 0) { + markInstalled(index); + } else { + DownloadInfo *info = getDownloadInfo(fileName); + if (info != nullptr) { + QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat); + metaFile.setValue("installed", true); + metaFile.setValue("uninstalled", false); + } + delete info; + } +} + DownloadManager::DownloadInfo* DownloadManager::getDownloadInfo(QString fileName) { return DownloadInfo::createFromMeta(fileName, true); @@ -927,12 +943,13 @@ void DownloadManager::markUninstalled(QString fileName) if (index >= 0) { markUninstalled(index); } else { - DownloadInfo *info = getDownloadInfo(fileName); + QString filePath = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + fileName; + DownloadInfo *info = getDownloadInfo(filePath); if (info != nullptr) { QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat); metaFile.setValue("uninstalled", true); - setState(info, STATE_UNINSTALLED); } + delete info; } } diff --git a/src/downloadmanager.h b/src/downloadmanager.h index 059c6cb5..a6d3b20c 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -307,6 +307,8 @@ public: */ void markInstalled(int index); + void markInstalled(QString download); + /** * @brief mark a download as uninstalled * diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 895b3b9c..999c7732 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -895,6 +895,8 @@ MOBase::IModInterface *OrganizerCore::installMod(const QString &fileName, ModInfoDialog::TAB_INIFILES); } m_ModInstalled(modName); + m_DownloadManager.markInstalled(fileName); + emit modInstalled(modName); return modInfo.data(); } else { reportError(tr("mod \"%1\" not found").arg(modName)); From 37b1bdd9e66f0c377b51b34ac94a4356dd337a5d Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 11 Apr 2018 12:58:46 -0500 Subject: [PATCH 55/57] Bump version to 2.1.2 and update meta info --- src/version.rc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/version.rc b/src/version.rc index a71a462a..142065bf 100644 --- a/src/version.rc +++ b/src/version.rc @@ -1,7 +1,7 @@ #include "Winver.h" -#define VER_FILEVERSION 2,1,1 -#define VER_FILEVERSION_STR "2.1.1\0" +#define VER_FILEVERSION 2,1,2 +#define VER_FILEVERSION_STR "2.1.2\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION @@ -10,17 +10,19 @@ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS (0) FILEOS VOS__WINDOWS32 FILETYPE VFT_APP -FILESUBTYPE VFT2_UNKNOWN +FILESUBTYPE (0) BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904B0" BEGIN VALUE "FileVersion", VER_FILEVERSION_STR - VALUE "CompanyName", "Tannin\0" - VALUE "FileDescription", "Mod Organizer UI\0" + VALUE "CompanyName", "Mod Organizer 2 Team\0" + VALUE "FileDescription", "Main Mod Oranizer 2 UI\0" VALUE "OriginalFilename", "ModOrganizer.exe\0" - VALUE "ProductName", "Mod Organizer\0" + VALUE "InternalName", "ModOrganizer\0" + VALUE "LegalCopyright", "Copyright 2011-2016 Sebastian Herbord\r\nCopyright 2016-2018 Mod Organizer 2 contributors\0" + VALUE "ProductName", "Mod Organizer 2\0" VALUE "ProductVersion", VER_FILEVERSION_STR END END From be2d39b03583fdd5a60318c73e19a14f99a38374 Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 11 Apr 2018 15:12:31 -0500 Subject: [PATCH 56/57] Add flag and description text to ESL-flagged ESPs --- src/pluginlist.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 9bbcdc11..bd863f52 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -878,8 +878,12 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const text += "
" + tr("Enabled Masters") + ": " + SetJoin(enabledMasters, ", "); } if (m_ESPs[index].m_HasIni) { - text += "
There is an ini file connected to this esp. Its settings will be added to your game settings, overwriting " - "in case of conflicts."; + text += "
" + tr("There is an ini file connected to this esp. " + "Its settings will be added to your game settings, overwriting in case of conflicts."); + } + if (m_ESPs[index].m_IsLightFlagged && !m_ESPs[index].m_IsLight) { + text += "

" + tr("This ESP is flagged as an ESL. " + "It will adhere to the ESP load order but the records will be loaded in ESL space."); } toolTip += text; } @@ -902,6 +906,9 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const if (m_ESPs[index].m_HasIni) { result.append(":/MO/gui/attachment"); } + if (m_ESPs[index].m_IsLightFlagged && !m_ESPs[index].m_IsLight) { + result.append(":/MO/gui/awaiting"); + } return result; } return QVariant(); From 8be73d2e3b0af9cb99616d31418a0d9c74aca466 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Fri, 13 Apr 2018 00:38:23 -0500 Subject: [PATCH 57/57] Remove extraneous search code --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d069383..0c5f58a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,5 @@ SET(DEPENDENCIES_DIR CACHE PATH "") # hint to find qt in dependencies path LIST(APPEND CMAKE_PREFIX_PATH ${QT_ROOT}/lib/cmake) LIST(APPEND CMAKE_PREFIX_PATH ${LZ4_ROOT}/dll) -FILE(GLOB_RECURSE BOOST_ROOT ${DEPENDENCIES_DIR}/boost*/project-config.jam) -GET_FILENAME_COMPONENT(BOOST_ROOT ${BOOST_ROOT} DIRECTORY) ADD_SUBDIRECTORY(src)