Compare commits

...
Author SHA1 Message Date
Tannin 30c016567f bugfix: first attempt at discovering java binary always failed 2015-01-11 11:28:02 +01:00
Tannin da27ec45da increased version number and minor stuff 2015-01-11 11:17:26 +01:00
Tannin 1321564a92 bugfix: priority couldn't be changed directly in plugin list (this change was apparently not copied to the branch) 2015-01-11 11:17:04 +01:00
Tannin 4d9795527d different way to check for file existence 2015-01-11 11:16:04 +01:00
Tannin 9f09c30e08 bugfix: translations for some plugins weren't loaded 2015-01-11 11:14:58 +01:00
Tannin caf31e72cc bugfix: executables with extensions other than .com, .cmd or .bat were started with cmd.exe (since 1.2.16) 2015-01-11 11:14:10 +01:00
Tannin f2ab6825bf Added tag release v1.2.16 for changeset a837623ea911 2015-01-11 11:10:21 +01:00
Tannin 25348238b2 bugfix: translations for configurator plugin weren't named correctly 2015-01-08 20:07:58 +01:00
Tannin 8b3a42bd17 bugfix: translations for plugins were not used 2015-01-08 20:07:32 +01:00
Tannin 6f1162c23f bugfix: showEvent contains initializion code that should be run only on first start of the application 2015-01-08 20:06:56 +01:00
Tannin 2b21463514 - download servers that haven't been available for over a month are now purged from the known servers list
- bugfix: encoding detection for fomod xmls could incorrectly interpret files as utf16 encoded
- bugfix: hashing algorithm for bsa files was wrong
- bugfix: nxmhandler reported non-issues as errors
- bugfix: nxmhandler tried to apply chrome fix on every start
- bugfix: "not endorsed" icon displayed for non-nexus mods
- bugfix: when drag&dropping within the overwrite dialog the file might still get moved to a mod (and probably not the intended one)
- bugfix: dropping files from overwrite on the modlist was refused when not sorting by priority (only in 1.2.15)
- bugfix: unmanaged mods couldn't be reordered (only in 1.2.15)
2015-01-07 23:13:40 +01:00
Tannin d20a26e0eb Added tag release v1.2.15 for changeset d1946676ce17 2015-01-07 23:09:58 +01:00
Tannin 459816ab71 updated packaging and build scripts 2015-01-03 15:09:25 +01:00
Tannin 9b5c238938 - repository info is now stored with the mod 2015-01-03 12:35:25 +01:00
Tannin e7b6a7cbdd - bugfix: no exec info returned for .exe
- bugfix: wide string conversion functions seem to have failed for empty string
2015-01-03 12:34:26 +01:00
Tannin ab925e1e7c added/updated translation files 2014-12-20 17:25:12 +01:00
Tannin 7bfb48d6ab cleanup 2014-12-20 14:45:08 +01:00
Tannin 88817c7f3b - drag&drop in the plugin list now also prompts a message instead of being impossible 2014-12-20 14:44:40 +01:00
Tannin ee0041ba18 - bugfix: file extensions when adding executables were treated case sensitive
- exe files are now started directly, not through cmd
2014-12-20 14:43:22 +01:00
Tannin 306ba78b0f bugfix: when merging mods with a custom installer, various ini settings (incl. category) were reset 2014-12-20 14:42:43 +01:00
Tannin e33406b4b5 endorsing is now only offered for mods with a valid nexus id 2014-12-20 14:42:00 +01:00
Tannin a5906f1044 workaround to prevent executables dialog from auto-selecting the top-most executable 2014-12-20 14:41:28 +01:00
Tannin ebfeb2fbf9 - mod-list can now be re-ordered with drag&drop while grouping is active
- drag&drop is not disabled when ordering by other columns than priority. MO will notify using messagedialog that it's impossible instead.
2014-12-14 18:25:26 +01:00
Tannin f666e3d835 when reinstalling a mod the existing mods name is used by default 2014-12-14 16:32:57 +01:00
Tannin 003cb6dec5 if a shortcut-started application is the same binary as a configured one, the corresponding steam app id is used 2014-12-14 16:32:30 +01:00
Tannin 7fb7207ac7 custom installers can now set the installation file (and the ncc installer now does) 2014-12-14 16:30:23 +01:00
Tannin 64eced4614 - NCC installer can now discover files in other mods (thanks Reunion!) and knows the script extender version 2014-12-13 16:47:11 +01:00
Tannin 8634b97bea all executables can now be repositioned, including auto-detected ones 2014-12-09 20:02:28 +01:00
Tannin 116a36b943 searching for steam process will no longer fail when more than 1024 processes are running (and steam is past the 1024th) 2014-12-09 18:35:32 +01:00
Tannin 479fdb3dcd removed use of ModInfo::internalName 2014-12-09 18:34:09 +01:00
Tannin acf35da699 now stored installed files with each mod 2014-12-09 18:09:11 +01:00
Tannin 6eb05396e4 bugfix: hitting the fix button in the diagnosis plugin could crash MO if the
line didn't have mouse focus
2014-12-04 19:30:07 +01:00
Tannin 9fcf34fec7 bugfix: ini tweaks were not applied in priority order 2014-12-04 19:27:55 +01:00
Tannin 6c1e63258c minor fixes 2014-12-04 19:25:07 +01:00
Tannin 226993eece - added error handling when a file can't be deleted from vfs
- minor bugfixes
2014-12-01 18:44:37 +01:00
Tannin 78da5fc37f more bugfixes 2014-11-26 20:22:00 +01:00
Tannin ffef339e2b several bugfixes from the bugfix-wc that I forgot to backport 2014-11-26 20:21:33 +01:00
Tannin 4fa700bb55 undid some changes that accidentally made it to this branch 2014-11-26 20:19:07 +01:00
Tannin 9907437d93 - fixed manifest for qt5
- download messages can now be sent from different user accounts
2014-11-14 23:33:49 +01:00
Tannin 3b7a468f73 - updated staging script to use qt5 and to fetch translations from transifex
- removed call to function unavailable in Windows XP
2014-11-11 23:48:22 +01:00
Tannin 0b14949d0e some work on installer scripts 2014-11-11 21:41:22 +01:00
Tannin 2237d7c103 - re-enabled use of img-tags in bbcode converter
- addded a workaround for cases where, after a MO update, the stored modlist layout has no size for new columns
- using a webview again for the nexus view of the modinfo dialog
2014-11-11 21:46:16 +01:00
Tannin 1eea3bd90e - bsa parser will now cancel in case of a read error. Before, when attempting to parse a broken bsa it could take forever and continuously allocate memory
- better error message when bsa parsing fails
- slightly better support for font colors in bbcode converter
- configurator now also uses pyqt5
- bugfix: bsa hashing function converted backslashes to slashes instead of the other way around. hash calculation is still often wrong on folder names...
2014-11-09 14:01:48 +01:00
Tannin 20db939501 - workaround for GetModuleFileName-calls that supply wrong buffer size
- removed obsoleted calls to GetVersionEx
- bugfix: download urls were potentially not encoded correctly
- bugfixes to tls-based recursion protection
2014-11-06 00:03:44 +01:00
Tannin bfa6c9ab1e - moved the hook-recursion-protection to tls
- some code cleanup and consolidation
- hook.dll will now report all of its own exceptions
- some more logging during startup
- changed the way urls are encoded for download requests
- now displaying (one of the) process name(s) while waiting for a program to end
- bugfix: spawned processes were forced to leave the job
2014-09-29 20:35:35 +02:00
Tannin 7a7c464b18 - archive library can now query for password during extraction (seems to be necessary for rars)
- process blacklist is now taken from a file if there is one, not hardcoded
- removed workaround for the papyrus compiler
- updated loot client to work with the actual api
- loot client now links with loot32.dll at runtime
- loot client now produces its output in a (json-)file which includes all plugin messages and dirty flags
- fomod installer now tries to parse the xml with several encodings
- fomod installer will now display a diagnostics warning if the jpg imageformat isn't supported
- base preview plugin now tries to be a bit smarter about resizing images to fit the screen
- bugfix: fomod installer no longer tries to open an image even after detecting its invalid
- bugfix: potential null-pointer dereferentiation in getprivateprofile... hooks
- bugfix: potential null-pointer dereferentiation in download manager
- bugfix: internal origin name showed up in one more place
- bugfix: ToString function produced strings that were one (zero-termination-)character too long
2014-11-05 23:48:06 +01:00
Tannin a62ecc5bf1 - several style fixes suggested by static analysis
- will now support up to 4 levels of version numbers (major.minor.subminor.subsubminor
2014-09-24 19:51:51 +02:00
Tannin 5f1022917b - removed a use of wostringstream which seems to have been involved in a bug. Still not sure how
- rewrote widechar <-> multibyte conversion functions to handle arbitrary string lengths
2014-09-19 22:01:37 +02:00
Tannin b77dcb2206 non-mo mods now have a constructed name that cannot conflict with a regular mod 2014-09-10 20:44:39 +02:00
Tannin 430048d201 when MO fails to overwrite its ini file it tries another method using qt functions 2014-09-10 20:43:33 +02:00
Tannin 4c42a6fbf1 plugins can now query the list of masters for a plugin 2014-09-10 20:37:17 +02:00
Tannin 243b59c64c profiles are now created with an (empty) archives.txt 2014-09-10 20:35:57 +02:00
Tannin b0a4748da5 - descriptions for plugin settings are now displayed 2014-09-10 20:34:31 +02:00
Tannin 9daeb9479b - re-enabled building of loot_cli and started developing against the new api
- extended set of default categories
- more tolerand bbcode parser
- added a few colors for the bbcode parser
- more fixes to qt5 compatibility
- started work on ability to unloading (and thus re-loading) of plugins
- names of plugins are no longer localizable (because those names are also used to store settings)
- added settings to disable individual diagnosis settings
- path of dependencies is now configured in a .pri file instead of environment variablees
- bugfix: if the modid-input is canceled, the id was saved as -1 and wasn't re-requested from the user
- bugfix: moving files with the SHFileOperation-Api didn't update the vfs correctly (still not perfect but better)
- bugfix: attempt to remove the deleter-file seems to have caused error messages for some users
- bugfix: fixed a couple of cases that might have caused the tutorial to hang
2014-09-08 20:37:23 +02:00
Tannin 07bae15d7c - bugfix: MO would report invalid index errors when downloading while download list is sorted by filetime descending 2014-08-25 21:07:29 +02:00
Tannin 778160cf0d - processes spawned from MO are now themselves allowed to break away from the job.
Without this the CEF (chromium embedded framework) seems to fail
- bugfix: Fixed an error message when installing a fomod wrapped in an archive
- bugfix: sorting plugins had no effect on non-skyrim games
- bugfix: fomod parser quit installing filelists after one file
- bugfix: function retrieving local appdata path read wrong directory
2014-08-25 20:12:25 +02:00
Tannin 14106436ca - bugfix: mods were specified by internal name in archive and data tab 2014-08-19 18:44:35 +02:00
Tannin 4f509e365e - new plugin-api to determine the origin of a file 2014-08-18 23:01:25 +02:00
Tannin 4ebc8dc014 - bugfix: text files weren't displayed in the mod-info-dialog 2014-08-18 23:01:02 +02:00
Tannin 5d3c1f34f4 - login package now also uses a "proper" user-agent 2014-08-18 22:57:00 +02:00
Tannin 844ba99892 - performance optimizations for detection of file changes in mod directories
- added a workaround for download-link handling in chrome
- MO will now create a profile even if the game-launcher has never been run
- bugfix: files weren't cleanly removed from vfs file register
2014-08-01 12:10:49 +02:00
Tannin 715623e790 - browser dialog now has a hidden url-field (for testing only)
- loot_cli is no longer part of this project. I will probably create a fork of loot that allows command-line usage instead
- loot integration now works with such a modified loot version
- integrated loot will now also integrate incompatibility messages in the MO UI
- overwrite-markers are now updated as the list order is changed
- fnis checker will now always allow the user to ignore fnis errors
- plugin interface now has a function to wait for handles returned from startApplication (which can be job or process handles)
- bugfix: non-mo mods sharing the name with regular mods now have a different internal name
- bugfix: using hotkeys the vanilla game-plugins could be moved
2014-07-27 18:34:32 +02:00
Tannin 9879aae575 - download-list will no longer show a file as having incomplete data if there is no file version
- added a new mod column with icons displaying the content of the mod
- MO now differentiates between mods using an internal name that disambiguates between foreign and regular mods
2014-07-21 19:14:24 +02:00
Tannin cc9827cdda normalized eol style (all files should now have windows line endings) 2014-07-17 22:02:15 +02:00
Tannin 4e5a67fc06 - bugfix: broke qt4 compatibility in trying to support qt5
- bugfix: overwrite dialog displayed system drives if the overwrite directory didn't exist
- bugfix: ini tweak activation wasn't saved
2014-07-17 20:04:22 +02:00
Tannin 67b0268e70 - qt 5 compatibility fixes
- detection for support of optimized find no longer depends on deprecated api
2014-07-15 17:31:44 +02:00
Tannin b1ac479fb6 slight fixes to qt5 compatibility 2014-07-03 17:42:31 +02:00
Tannin 80b10107d9 - Disabled compilation of loot_cli as the current loot version can't be compiled or linked against with vs 2010
- bugfix: some incompatibilities with non-skyrim games
- bugfix: incorrect handling of plurals in translateable strings
2014-07-15 20:37:10 +02:00
TheBloke 1707941f6e deleteSavegame:
- Confirmation question shows number of saves to be deleted, when more than 1
2014-07-13 16:11:30 +01:00
TheBloke d0b75e8b25 savegameList: more minor changes
- Context Menu - can do same job with fewer variables and assignments
- deleteSaveGame_clicked - const reference, not new value, in foreach loop
2014-07-13 15:45:19 +01:00
TheBloke 4fc441b249 savegameList:
- Context menu bugfix, previous method of getting rows didn't work when items
 were selected in certain ways, e.g. Control-A
- Context menu now uses selectedIndexes(), which always works with all selections.
- Renamed enableFixMods to multipleSelected so same value can be used to decide
 whether to show single or plural version of "Delete save(s)"
2014-07-13 15:24:46 +01:00
TheBloke 581d065d7a savegameList: A few cleanups and minor code improvements
- Slight improvements over previous commits, using more appropriate methods and
 removing some unnecessary code. No functional changes.
2014-07-12 11:15:34 +01:00
TheBloke 5d2b5202af - savegameList: Improved save game handling from MainWindow
-- Save game deletion now does Recycle Bin delete (wishlist #675)
-- Save game deletion now also deletes .skse file (bug #687)
-- Can select and delete multiple save games (ExtendedSelection) (wishlist #675)
-- Uses new SaveGame->saveFiles() method to get filenames (eg .ess & .skse)
-- Context menu - "Fix Mods.." option only appears if 1 save is selected
-- Context menu - delete menu option labelled "Delete save" or "Delete saves",
 according to 1 or >1 saves selected.
-- Context menu - delete menu confirmation shows list of all selected saves
2014-07-11 01:46:42 +01:00
TheBloke 8044ef4f1d - Save game management: re-factored getting of filenames including .skse
-- New - SaveGame->saveFiles(), returns all filenames for save (eg. ess + skse)
-- Moved - SaveGameGameBryo->attachedFiles() to SaveGame->attachedFiles()
-- This allows the getting of save file names with just a SaveGame object, not
 a GameBryo object, which would do a full file read including plugins and image etc.
-- Therefore SaveGame is no longer abstract.

- Transfer Saves: re-factored to use new SaveGame->saveFiles() method
-- Removed - TransferSavesDialog->getFilesToProcess, now redundant as information
 is now provided by SaveGame class itself.
2014-07-11 01:29:33 +01:00
TheBloke 3d98491ebc Additional 'make install' step - install boost_python DLL to output(d)\DLLs
Extended the new ModOrganizer.pro 'make install' steps, to now also copy
  $$(BOOSTPATH)\stage\lib\boost_python-vc*-mt-1*.dll
 This is the final install step required, so that now ModOrganizer.exe works
  fully when a Qt-Creator "Run" step is performed.
 The wildcard should pick up the right version of the library regardless of
  MSVC compiler version used.

Updated Qt5 version check to the standardised greaterThan check.
2014-07-08 04:05:33 +01:00
TheBloke 923654961b Compilation dependency tracking enabled for organizer, hook, bsaExtractor, shared
Previously, qmake did not detect when code was changed in the static libraries
 So for example, changing code in shared/*.cpp and then Build, would not cause
  a re-link and re-deploy of ModOrganizer.exe.
 This has been fixed by adding PRE_TARGETDEPS references to each project that
  depend on static libraries provided by other sub-projects.
 These checks are conditional on debug|release, to point to the correct lib.

 List of currently configured static library dependency checks -
  organizer - mo_shared.lib, bsatk.lib
  hookdll - mo_shared.lib, bsatk.lib
  shared - bsatk.lib
  bsaExtractor - bsatk.lib

 I have tested to confirm that changing a shared file results in re-linking and
  re-deplomyent of both ModOrganizer.exe and hook.dll.

 Note that dependencies have not been configured for DLLs, as these are
  loaded dynamically and so recompilation is not required.
  But there could be an argument for configuring DLLs as dependencies too -
   as if you make a change in DLL code, you might want all clients of the DLL to
    be recompiled to check that they have not been broken by the changes?
  The downside of that would be extra re-compilation every time.
2014-07-08 04:01:24 +01:00
TheBloke 76c861ed12 .pro files - formatting/consistency fixes
Many small formatting changes to the majority of .pro files
 Consistent style for Qt version checking, using greaterThan(QT_MAJOR_VERSION, 4)
  This seems safest, as would continue to work for a future Qt 6 etc.
  Note that this makes redudundant the commit before this one, to organizer.pro
 Consistent indenting
 Moved some file configuration sections to be together with related sections
 Moved some installation-related sections (e.g. OUTDIR/DSTDIR) to be at the bottom,
  immediately before the related POST_LINK install lines.
 Similarly, in some cases separated out CONFIG(debug,.. checks into separate
  LIB/INCLUDE sections (high in file) and installation directory sections (low
   in file)
2014-07-07 23:32:18 +01:00
TheBloke 31cab54861 organizer.pro - tiny tweak to Qt5 version check
Directly checking QT_MAJOR_VERSION instead of pattern matching on QT_VERSION
2014-07-07 21:51:35 +01:00
TheBloke 2a16cc4262 Added 'make install' steps in ModOrganizer.pro -
Added config to install required libraries to output(d) directory
 If the user adds a Deploy step, that runs 'jom install', he will have the
  necessary libraries copied to output(d)\dlls
 These libraries are -
  7z.dll
  Qt4 Core Declarative Gui Network OpenGL Script Sql Svg Webkit Xml XmlPatterns
   Different set configured for Qt5, e.g. adding Widgets, Qml, Quick
   In a debug build, the 'd' DLLs will be used instead.
   Qt4 libraries are copied from system Qt4 installation directory.
 This allows the Qt-Creator user to hit "Run" in Qt-C and end up with a complete
  install, including all DLLs; no manual Exporer copying required.
 This therefore removes the need for post-build steps 10 & 11 in Readme.txt.
 Future thought - Update all current POST_LINK (x)copy steps to make install?

Fixed DESTDIR in ModOrganizer.pro
 It was pointing to source/output(d) before, should be ..\output(d)
 It was not used before so didn't matter, but is now referenced for install.
2014-07-07 21:39:27 +01:00
Tannin af89733121 - bugfix: update.bsa is again treated like a regular bsa because hiding it from the archive-list made it impossible (in managed bsa mode) to overwrite files from update.bsa
- bugfix: disabled-state for mo management wasn't saved
- bugfix: when starting an application, settings were saved twice
- bugfix: origin ids and handles for directory updates were out of sync
2014-06-30 22:37:21 +02:00
Tannin baf1240be7 Added tag release v1.2.6 for changeset c40e9a70e99e 2014-06-29 15:09:55 +02:00
Tannin 6e4626852c - re-inserted code for bsa hiding (this was necessary to enforce expected bsa order after all)
- bsas from foreign bsas are now loaded as expected by hook.dll as well
- state of log-window-split is now saved
- auto completion in installer name boxes is now case-sensitive so that users can change casing of the mod names
- bugfix: self updater did enforce the skyrim url for MO updates but not the game_id
- bugfix: modinfo dialog didn't correctly read mod meta information on opening
- bugfix: MO didn't report on endorsement (for MO)
2014-06-29 15:09:45 +02:00
Tannin e8f56d65d2 Added tag release v1.2.5 for changeset 70663ff89a38 2014-06-25 23:51:39 +02:00
Tannin 5e7c875b29 - test-plugins accidentally distributed in the 1.2.5 release are now automatically deleted
- some fixes to the tutorial (mostly wording but also some actual problems)
- bugfix: could disable mods that aren't supposed to be disable-able
- bugfix: mod list wasn't saved on some changes
- bugfix: when trying to start directly to application, MO didn't start up correctly
- bugfix: hook.dll didn't load mod bsas into its directory structure and thus didn't allow bsas to overwrite loose files
- bugfix: in some constellations the tutorial files couldn't be found despite being in the right location
2014-06-25 23:51:29 +02:00
Tannin b2a7c7c223 Merge 2014-06-23 21:43:40 +02:00
Tannin 7b4582c1b1 - adjusted mod load order in hook.dll to match the one from the UI
- bugfix: fnis checker took files in archives into consideration for hashing
2014-06-23 20:23:59 +02:00
Tannin 5d7b23acef - bugfix: networkaccessmanager of browser dialog wasn't destroyed correctly. As a result the cookie jar doesn't get saved 2014-06-21 12:16:57 +02:00
Tannin 3628ec930b - changed the url used to login on nexus (the previous page was disabled)
- bugfix: download manager might have tried to read from a closed connection
2014-06-21 10:39:28 +02:00
Tannin e22aeca3ff - download read buffer is now limited to 1MB. Might prevent out-of-memory errors during download
- bugfix: plugins are now disabled when deactivating a mod  before the files are removed from the vfs
2014-06-17 18:36:28 +02:00
Tannin cbd6b288eb Merge 2014-06-16 21:50:53 +02:00
Tannin 484749e612 - added pseudo-categories to filter for mo-managed vs. unmanaged mods
- deleted mods are now moved to the recycle bin instead of being deleted permanently
- reduced modinfo dialog for foreign mods
- foreign mods are now displayed with a pseudo-category
- added a signal when a plugin is moved
- bugfix: refreshing of directory structure for mods with bsas didn't work correctly when enabling a mod and on changing display of foreign mods
- bugfix: one mod in the list was assigned the same priority on the directory structure as the data directory
- bugfix: conflicts tab in the mod info dialog offered the hide option for files in bsas
2014-06-16 21:49:57 +02:00
Tannin 5b3cdaa83b bugfix: the warning dialog upon changing the mod directory didn't have an effect, the process couldn't be canceled 2014-06-14 09:17:57 +02:00
Tannin 6d3f88b330 Added tag release v1.2.3 for changeset c503e48f97aa 2014-06-08 15:10:21 +02:00
Tannin 0feb4b702d - loot client now only updates the masterlist once per MO session
- new event to notify plugins of changed mod priority
- overwrite now shows up in the "checked" category instead of "unchecked"
- display of "foreign" mods can now be limited to only official content
- bugfix: bsa extraction dialog showed up even if the plugin was disabled
- bugfix: after detection of foreign mods the priority of the overwrite folder could get messed up
- bugfix: when displaying only the context menu for the mod list as a whole, the menu didn't disappear
- bugfix: MO crashed when trying to download via the integrated browser
2014-06-08 15:10:08 +02:00
Tannin 5a4b6e70fd - plugin-list now displays loot messages 2014-06-02 19:15:23 +02:00
Tannin 18574c2ba8 - removed needless modlist-rewrite 2014-05-31 13:44:26 +02:00
Tannin 1eb783aae3 - added a new mod type that represents files handled externally (i.e. DLCs) as mods in MO
- hashes of file names in bsa files are no longer checked all the time
- author and description is now read from esp files
- rewrote the code that fixes modlists after a rename, should be a bit more robust
- fixes to qt 5 and msvc 2013 compatibility
- started to update the tutorial (not done yet!)
- bugfix: counter for the problems badge wasn't calculated correctly
2014-05-31 13:43:48 +02:00
Tannin 93a19799b8 Merge 2014-05-28 14:23:11 +02:00
Tannin 2a31eb40fb small bugfixes 2014-05-28 14:14:28 +02:00
Tannin cf0a1bc2be - files in bsas are now only displayed in the data tab if they are managed by mo
- number of problems detected by MO is now displayed as a badge on the icon
- rephrased the explanation text on the Archives tab. unchecked plugin-loaded bsas no longer prompt a warning
- bsa extraction is now handled in a plugin
- added a way for plugins to react to mod installation
- re-enabled the automatic fix for asset order problems
- bugfix: In some cases when a download wasn't started successfully the download urls weren't stored in the meta file so no resume was possible
- bugfix: MO tried to resume downloads when it didn't have and download urls
- bugfix: downloads couldn't be paused if the download was already broken on the network layer
- bugfix: download managear did not recognize a file as downloaded if the download completed before signals were hooked up
- bugfix: in-place file replacement was re-broken
2014-05-25 15:39:45 +02:00
Tannin 48c8cca578 - NCC will now report an error if a script tries to extract a non-existent file instead of creating an empty output file
- ncc installer plugin now uses a more reliable method to force the installer window to the foreground
- missing version on TESV.exe will no longer be reported as an error
- bugfix: loot client didn't read list of active mods
- bugfix: invalid free call in error reporting function
2014-05-15 19:11:19 +02:00
Tannin 977b407525 - mod list context menu split into two menus (one for whole list, one for selected mods)
- added option to combine category filters using "or"
- added context menu option for deselecting category filters
- slightly changed ui on the category filters
- added a sample plugin for cpp that can be built without building the rest of MO
- simple installer can now be configured to run without any user interaction
- extended interface for python plugins
- iorganizer implementation moved out of the main window
- nexus requests from plugins will now be identified in the user agent
- bugfix: shortcuts created from MO used the wrong working directory
- bugfix: deactivation of bsas didn't stick
- bugfix: file hiding mechanism wasn't active
- bugfix: executables linked on the toolbar couldn't be removed if the executable was removed first
- bugfix: the endorsement-filter couldn't be combined with other filters
- bugfix: python interface to repository bridge was broken
2014-05-13 21:20:44 +02:00
Tannin f4b1aba61a Added tag release v1.2.1 for changeset 366d0a6ac409 2014-05-06 21:07:34 +02:00
Tannin 0eb1662a0e - very effective optimization to findfirstfile-calls
- several configuration files are now only saved to disk if the content actually changed.
  This should also get rid of a problem where plugins.txt was re-written immediately after starting the game
  (causing a conflict with the game)
- reduced "noise" from hook.dll
- removed some debugging messages
2014-05-05 18:24:15 +02:00
Tannin 164ec25a75 - bugfix: endless loop in detection of mod order problems 2014-05-04 16:13:35 +02:00
Tannin 6fb36d6c02 - main window now has a small view displaying log messages
- mod list will now be highlighted when grouping is active is active
- download tooltip now supports bbcode markup in the description
- bbcode translator will now translate some named colors
- algorithm for detection of mod order problems is now more sophisticated
- exposed more functionality to python plugins
- updated to qt 4.8.6 dlls
- bugfix: plugin list wasn't
- bugfix: state changes in mod list wasn't always reported
- bugfix: loot client will now create necessary directory
- bugfix: NCC sometimes used wrong source path for extracting
- bugfix: removed noisy debug message
2014-05-04 14:50:01 +02:00
Tannin ea1f959ad5 - download tooltip now also includes the file description
- will now display an error message when the ini file can't be updated (in addition to what windows says)
2014-05-01 10:03:40 +02:00
Tannin 7cf3b3455b Added tag release v1.2.0 for changeset cc9f6dd8ee3f 2014-04-25 20:02:53 +02:00
Tannin 84cfa95254 - bugfix: newly installed files could be added hidden
- bugfix: registered bsas in data aren't ordered correctly
2014-04-25 19:15:12 +02:00
Tannin 264da60929 - updated installer
- prettified a few log messages
2014-04-24 22:07:42 +02:00
Tannin 2db33523a1 - added an option to show meta info on downloads instead of filenames
- MO will now cancel if user tries to run MO vfs-injected
- when saving the MO ini file it is now written to a tmp file first and then overwritten
- updated to link against boost python 1.55
2014-04-23 23:59:30 +02:00
Tannin 540747177a - loot client no longer stalls the process while waiting for masterlist update
- configurator now gives better warning messages when encountering an invalid ini file
- bugfix: crash on cleanup up browser dialog
- bugfix: GetCurrentDirectory returned wrong string length
2014-04-16 22:32:59 +02:00
Tannin 739c3424e7 - loot integration now displays the report
- fixes to the previous merge
- bugfix: cli loot didn't handle non-ascii characters correctly
2014-04-05 20:54:08 +02:00
Tannin cabed9b268 Merge with branch1.1 2014-04-05 15:36:42 +02:00
Tannin c017f4a0d5 - added buttons to backup and restore the modlist and pluginlist
- replaced boss integration with loot
2014-04-05 15:14:37 +02:00
Tannin b1f1682790 - bugfix: the add/remove categories function could fail when a filter/grouping on categories was active 2014-03-26 17:23:26 +01:00
Tannin 28301e7486 - improved NCC compatibility
- crude support for multi-volume archives
- updated imageformats plugins
- nxmhandler now puts the exe to the top of the list when registering an MO instance, even if it is already in the list
- bugfix: WritePrivateProfileString hook attempted to access lpKeyName even when it is null
2014-03-26 15:35:59 +01:00
Tannin 2d0fab4482 Merge 2014-03-18 19:18:17 +01:00
Tannin c19c4820d8 - force-enabled game esms no longer break keyboard-navigation in plugin list 2014-03-18 19:18:04 +01:00
Tannin 8ab1b47943 - bugfix: if resuming a download failed with the server sending a textual error message,
MO tried to display the whole file inside the error message
- bugfix: resuming a download didn't trigger a nexus-login when necessary
- bugfix: integrated fomod installer only used the first block of data inside a description
2014-03-18 18:29:32 +01:00
Tannin ff272dcbbd Merge 2014-03-16 20:05:13 +01:00
Tannin 98354cd1e7 some fixes towards qt5 compatibility 2014-03-16 20:04:57 +01:00
Tannin 129b76d7d2 - unpacking bsas during installation no longer overwrites loose files (since the loose files
would have taken precedence)
2014-03-13 21:57:11 +01:00
Tannin a82b7e9949 - "CreateDirectory" will no longer create directories in original data directory
- bain installer will now be less picky about the archives supported
- updated NCC to be compatible with more recent NMM code base
- hack in NCC to allow it to install arbitrary sized files even in 32-bit builds
- updated the python27.dll to one that links to msvcr100.dll to get rid of the dependency of msvcr90.dll
- bugfix: dll search order wasn't set to allow plugins to load the correct qt dlls
2014-03-13 19:00:32 +01:00
Tannin 0f8f7bf777 Added tag releease v1.1.2 for changeset 4276e1188b42 2014-02-26 22:14:06 +01:00
Tannin f4cf992700 Removed tag 1.1.2 2014-02-26 22:13:53 +01:00
Tannin bec644bac3 Added tag 1.1.2 for changeset 4276e1188b42 2014-02-26 22:13:43 +01:00
Tannin bb98bfade6 - MO will now be elevated if needed 2014-02-23 18:53:38 +01:00
Tannin 00f4e1799f - slightly overworked display of icon delegates
- updated installer
2014-02-23 17:18:20 +01:00
Tannin 35fcf1c25b - made the indicator for drag&drop more visible
- message boxes can now be made to not (re-)activate the window
- executable names for starting from the command line are now case-insensitive
2014-02-22 19:22:12 +01:00
Tannin bed3c08a6d - bugfix: on-demand loading of data tree broke filtering on conflicting files 2014-02-18 19:08:12 +01:00
Tannin f9eba9dc15 - ini file changes that would have to overwrite ini tweaks are now stored in a separate file
and actually get used.
- a warning message advices users to clean out that separate file
- slightly improved default main window layout
- bugfix: newly created ini tweaks were added to the list with incorrect  properties
2014-02-17 21:15:20 +01:00
Tannin 9c8e43853d - a few hooks will now somewhat handle file names starting with \\?\
- mod meta information is now (also) saved by a timer to reduce the likelyhood
of a data loss in case of a crash
- mod meta files are now written to a temporary file and then renamed to real name to
reduce chance of breaking the file
- updated minimum compatible nmm version to 0.47.0
- bugfix: defaults for newestVersion, version and installationFile when creating
an empty mod were integers instead of strings
- bugfix: "Plugins" and "Archives" weren't translatable
2014-02-12 21:00:49 +01:00
Tannin 7aadb47637 - archives.txt is now written using the "safe"-write mechanism
- added the whole boss fork to the repository
- bugfix: boss db is now always re-initialised because otherwise there might have been differing results between runs
- bugfix: locked load order was ignored by integrated boss
- bugfix: archive list wasn't written back on all changes that affected it
- bugfix: CreateFile-hook didn't reroute files created with OPEN_ALWAYS to overwrite directory
- bugfix: NtQueryDirectoryFile-hook didn't return the correct status code when searching for a file that doesn't exist
2014-02-07 21:05:48 +01:00
Tannin 76fbe6effe - tabs in the mod info dialog can now be moved around by the user 2014-02-04 19:55:27 +01:00
Tannin 38ee6ccf0a Added tag release v1.1.1 for changeset 73a1f1438658 2014-02-02 15:14:07 +01:00
Tannin 7722a9b6df - main window is now actually disabled while integrated boss is running
- bugfix: integrated boss sorting couldn't recognize plugins specified via regular expression
2014-02-02 14:26:24 +01:00
Tannin 48704877ca - bugfix: upon moving files between mods, an attempt was made to access origins
for both, even if one (or both) mods weren't active
- bugfix: plugin-list should now deal with nested "layoutAboutToBeChanged" calls
gracefully. May be the reason of a bug.
2014-02-02 00:09:03 +01:00
Tannin 48c944c737 - bugfix: elevation dialog didn't offer a "yes" option
- bugfix: python plugins crashed the application when trying to create a nexus bridge
- bugfix: python plugins couldn't register for failed requests correctly
2014-01-29 21:06:55 +01:00
Tannin af50eedbe2 - bugfix: dds preview or transparent textures looked odd
- bugfix: lazy loaded data tree deleted the placeholder
2014-01-29 00:23:16 +01:00
Tannin 52e5dd3c57 Added tag release v1.1.0 for changeset 87c2eea95307 2014-01-29 00:20:47 +01:00
Tannin ccd5d1294f - bugfix: accessing profile without loading one when starting an app through the commandline
- bugfix: locked-dialog was disabled
2014-01-27 21:31:10 +01:00
Tannin de984a4ef8 - information from boss no longer gets lost as soon as the plugin list gets refreshed
- bugfix: modified boss dll missed one file on sorting
2014-01-23 21:14:44 +01:00
Tannin e597823337 - boss integration
- plugin list can now also display multiple flags for a file (like the mod list)
- changed some compiler&linker settings to produce smaller binaries
2014-01-23 00:05:46 +01:00
Tannin e69210b3a7 - when a download server returns a text file, it's assumed to be an error and the text displayed as an error
- save games can now be deleted from inside MO
- bugfix: removing the pending download entry failed if the download-url request failed
- bugfix: download manager didn't stop automatically resuming failed downloads under certain circumstances
- bugfix: uninstalled downloads were treated as not-finished when refreshing the download list
- bugfix: updating the filesystem watcher on the saves directory didn't work correctly
2014-01-18 19:51:58 +01:00
Tannin 40d20ab294 - added an about dialog
- updated json library
2014-01-16 20:43:42 +01:00
Tannin 6ed82866b0 - moved code for file previews to plugins 2014-01-14 21:16:36 +01:00
Tannin a083a2d3b6 - implemented hook for NtQueryDirectoryFile
- saves list is now automatically updated on FS changes
- optimization: data tree widget is no longer filled completely at once but one directory at a time
- bugfix: pending downloads were not removed from list after a failed nxm request
- bugfix: there was still a nmm.nexusmods.com link
- bugfix: the text "alpha" in version strings wasn't interpreted correctly
2014-01-13 19:32:54 +01:00
Tannin db09b806b9 - Mod Organizer can now display most image types (including dds) and txt files from the data
tree, presenting a comparison of variants in case of overwritten files
2014-01-05 18:50:56 +01:00
Tannin 859c0aed98 download manager now removed orphaned meta files 2014-01-04 16:39:38 +01:00
Tannin 0ea7d99b9f Merge 2014-01-04 16:05:39 +01:00
Tannin 6cffbd4f27 using icons + splash from heavydude 2014-01-04 16:05:25 +01:00
Tannin 4dc3538a7d - nxmhandler will now ask before registering itself
- downloads from nexus are now displayed before file information is retrieved
- logging from the ui is now a bit more informative
- download list now scrolls to bottom automatically
2014-01-04 15:57:14 +01:00
Tannin e45b747c82 Added tag release v1.0.12 for changeset 440287834340 2014-01-03 18:43:03 +01:00
Tannin 2d6bacbb6a -removed compiled translations from the repository 2014-01-03 18:41:47 +01:00
Tannin d029e97724 - hook dll now monitors all mod directories, not only overwrite
- dialog for changing executables now warns if changes will be lost
- main window is now locked before activating pre-start hooks
- better responsiveness while main window is locked (or should be)
2014-01-03 18:40:46 +01:00
Tannin a9435f637e Added tag release v1.0.11 for changeset 806fd77aa2de 2013-12-19 20:33:38 +01:00
Tannin e1e35da6fe Added tag release v1.0.10 for changeset e72788d8ac35 2013-12-19 20:31:48 +01:00
Tannin e43f126b03 - bugfix: crash on overwriting a mod (introduced after the previous release)
- bugfix: ncc installer now brings the installer window to front (again? more reliably? not sure if it really worked before)
2013-12-19 20:30:39 +01:00
Tannin 35c9fe3e98 - bugfix: archive.dll could cause a crash, attempting to close an archive that failed to open
- bugfix: upon changing categories the mappings of deleted categories wasn't cleaned up which could cause an error message
- bugfix: the number of esps/esms that can be loaded is actually 255 not 256 since the save game counts too
- bugfix: "visit on nexus" from the modinfo dialog also lead to the wrong url
2013-12-19 19:40:59 +01:00
Tannin 82f7b09b40 Merge 2013-12-14 17:19:27 +01:00
Tannin f33d24870f - added more information to readme
- 7zip source path is now configurable
2013-12-14 17:19:15 +01:00
Tannin 14ac234daf - plugin list now highlights plugins with attached ini files
- bugfix: opening nexus through the globe icon used the nmm.nexusmods.com url
2013-12-14 13:23:13 +01:00
Tannin 22b8eb7c5a - downgrading a mod (using replace) will now change the version
- bain installer will now accept archives with omod conversion data.
2013-12-11 20:43:30 +01:00
Tannin 9ee90a35dc - MO now applies a minimum to the nmm-compatibility field.
- bugfix: "visit on nexus" directed the browser to the servers meant for nmm
- bugfix: url for "check all for updates" and "enorse/unendorse" were not constructed correctly
2013-12-08 14:16:25 +01:00
Tannin ff78c6a014 - bugfix: extracting bsas did not work with non-ascii characters in the mod name
- another attempt to switch branches...
2013-12-07 17:41:45 +01:00
Tannin 340edcfbca - returned to default branch
- nexus interface will now use the nmm url
- nmm importer no longer cancels on a missing non-essential flag
2013-12-07 17:13:36 +01:00
Tannin c4f0bc39c7 Merge with default 2013-12-07 16:55:19 +01:00
Tannin e71c37df37 - bugfix: drag&drop on archive list didn't always work properly 2013-12-07 16:54:08 +01:00
Tannin b32457a7d2 - minor text fixes
- versions without a subminor version are now displayed without it (1.1 instead of 1.1.0)
- version compares now prefer the decimal comparison over the traditional
2013-12-07 16:07:28 +01:00
Tannin 6e1e8c37eb minor text changes 2013-12-07 14:23:51 +01:00
Tannin 469cc2d945 - download manager now saves the file times on nexus, for potential later use in version check
- nexus interface now supports 301 redirects
- now using the new nexus url format
- bugfix: "visit on nexus" used an outdated url scheme and thus caused unnecessary redirection
2013-12-07 12:48:18 +01:00
Tannin 0e90b9d233 - bugfix: changing nexus id directly via mod list did not cause the change to be saved 2013-12-04 19:54:28 +01:00
Tannin 0e19c84722 Added tag release v1.0.9 for changeset a61a930515ae 2013-12-01 23:52:42 +01:00
Tannin daf4ae44fa - added second context menu for changing categories that applies only changes to
the selected mods instead of replacing the existing set of categories (thanks to Ross!)
- bugfix: category filtering didn't work correctly when grouping was also active
2013-12-01 23:50:24 +01:00
Tannin ac29aa81f2 minor updates to readme and mod info ui 2013-12-01 21:43:16 +01:00
Tannin a0335d0a63 Added tag 1.0.8 for changeset a61a930515ae 2013-11-27 20:25:55 +01:00
Tannin f1515193ca - plugins can now be localized too
- fixes to the installer script
- extended build scripts to fetch translations from pootle server automatically
2013-11-27 20:25:24 +01:00
Tannin db0347212a - bugfix: installFile for mods was not a relative path if the downloads directory was non-default
- bugfix: crash after removing the last profile in the list (ordered alphabetically)
- improved subdirs ordering to ensure pythonrunner is compiled before pythonproxy
- translation files for plugins are now generated
- set some texts as un-translatable where it made no sense
- staging script now re-builds MO completely before packaging
- updated qt libraries for packaging to 4.8.5
- added python to the package
2013-11-22 17:45:34 +01:00
Tannin 5895a1a92d - bugfix: canceling creation of an ini tweak prompted an error message
- added missing files from earlier commit (wtf?)
2013-11-20 21:54:14 +01:00
Tannin c6101e34e1 - archive.dll now supports querying the crc value of files
- esptk now determines if a esp is a dummy (without records)
- hook.dll no longer creates a log file if noone wrote to it
- nexus id and installtime columns are now hidden by default
- modlist can now be refreshed without saving first (so plugins can replace the modlist.txt as a whole)
- plugins can now query more details about virtualised files
- added style options "plastique" and "cleanlooks"
- "overwrite" is no longer listed with a creation time
- a warning will now be displayed if the user has too many plugins active
- a warning will now be displayed if mods with scripts have an installation order that doesn't match the corresponding esp load order
- nmm importer now has select all/deselect all buttons
- nmm importer no longer tries to unpack missing files from archives (won't work anyway)
- initial support for importing from nmm 0.5 alpha
- removed some broken warning suppresions
- python runner now works with bundled python
- extended qbs build system (still fails to build the main gui application)
- implemented a nsis-based installer
2013-11-18 20:17:14 +01:00
Tannin 75475a7984 - started qbs based project files (not functional yet)
- modlist will now updated immediately after a change throw the modinfo dialog
- bugfix: configurator wasn't able to save after revision 137
2013-11-11 23:19:54 +01:00
Tannin 315ed6e41a Added tag release v1.0.7 for changeset 1973f6e00784 2013-11-06 18:40:09 +01:00
Tannin b2d613e9d1 Added tag release v1.0.6 for changeset 1973f6e00784 2013-11-06 18:40:03 +01:00
Tannin f010c22a3b - diagnosis plugins can now request to be re-evaluated
- main application now contains means for plugins to react on some changes (to be extended)
- plugins can now retrieve more information about a mod
- user-agent sent to nexus now automatically contains the current MO version
- included updated russian translation
- problems dialog now refreshes itself after a fix was applied
- fixed new esp/asset ordering diagnosis. May be fully functional now
- bugfix: restoring locked load order could leave MO in an endless loop (not sure if this fix is correct yet)
- bugfix: plugin list was not visually updated after some changes
- bugfix: nmm importer threw away mod ordering
2013-11-06 18:35:27 +01:00
Tannin d1594798e6 - added a new diagnosis to detect potential problems in regards to esp vs. asset ordering (not fully functional yet)
- new plugin interfaces to the mod list
- plugins can now query the origin (mod) of a esp/esm
- bugfix: potential access to profile before one was activated
- bugfix: regression in previous (not-yet-released) commit prevented changes to bsa list from being saved
2013-11-01 14:59:25 +01:00
Tannin 09bd3dbead - text files encoded in system encoding should now be correctly recognized in the mod info dialog
- archive-list can be user-sorted again (within one mod)
2013-10-26 15:02:31 +02:00
Tannin 8c0b309bde - Option to choose edition of the game. Currently only relevant for FO3 because FO3 GOTY is its own app
- applications that aren't in the executables list can again be started from the command line
- references to missing categories are now removed from mods
- bugfix: integrated fomod installer didn't update description and picture on some constellations of Windows version and theme
2013-10-25 14:49:42 +02:00
Tannin bc7c42dbe8 - directories in data-view are now sorted
- questionbox with selection memory is now exposed to plugins
- the choice to run fnis from the checker can now be memorized
2013-10-20 16:51:40 +02:00
Tannin 9a03783f49 - tooltip on download list now contains the file name
- bugfix: when refreshing the directory tree conflict information wasn't immediately refreshed (including on start)
- bugfix: dataChanged events wasn't emitted when user changed the modlist
- bugfix: file patterns in checkfnis plugin weren't completely correct
2013-10-18 23:35:38 +02:00
Tannin d73b1e38c8 - mod sorting now always uses priority as secondary sorting
- added missing ipluginlist.h
2013-10-17 19:21:22 +02:00
Tannin b47c89661e - plugin (esp/esm) list is now exposed to plugins (read-only functionality right now)
- integrated fomod installer now supports file dependencies
- bugfix: integrated fomod installer crashed if the installer had no optiosn´´ns
2013-10-16 23:04:03 +02:00
Tannin 0b84cc3d45 Merge 2013-10-16 19:34:56 +02:00
Tannin 1bf3cc585e - nmm importer now also transfers category, endorsement state and lastest version information
- nmm importer should now always determine the correct nexus id
- nmm importer will now correctly restore overwritten files for imported mods
2013-10-16 19:32:59 +02:00
Tannin eae275cc84 Added tag release v1.0.5 for changeset c6a9d2ab2d6c 2013-10-15 23:34:16 +02:00
Tannin f3cb50057b - bugfixes to last merge
- fnis-check plugin can now be disabled
2013-10-12 13:21:37 +02:00
Tannin 5518309300 Merge 2013-10-12 12:32:37 +02:00
Tannin f22bb9d6a6 Merge 2013-10-11 23:04:44 +02:00
Tannin 382226bb46 - added new plugin to test if fnis needs to be run
- some functionality to the plugin interface to enable them to search for files&directories in the virtual FS (rudimentary atm)
- functionality for plugins to react to application being started from MO
- broken ESPs are no longer reported as popup windows but only in the log file
- bugfix: plugins couldn't store persistent data if they had no user-editable settings
2013-10-11 23:03:49 +02:00
Tannin bdf04f516c - MO now warns if a nxm-link for a wrong game was attempted instead of downloading the wrong file
- bugfix: in nxmhandler adding a new line with different game but same executable didn't work (the change was silently dropped)
2013-10-10 21:23:25 +02:00
Tannin 54c7131a5e - new toggle to display hidden downloads
- hidden downloads can be un-hidden
- the installation manager now more thoroughly cleans up the temporary directory after installation
- added SkyrimLauncher.exe to the list of auto-detected executables
- bugfix: shutting down MO while downloads where active in some occasions didn't work
- bugfix: when canceling the only active download the taskbar icon didn't return to normal
2013-10-10 19:32:01 +02:00
Tannin 15e256ef44 Added tag release v1.0.4 for changeset 7732c5d2e41d 2013-10-10 19:09:29 +02:00
Tannin b23a4885e0 - bugfix: When updating MO, if login is required, the process didn't continue automatically after login 2013-10-06 14:12:25 +02:00
Tannin 823dfd410b - option to ignore/unignore updates is now only shown if there IS an update
- window now shouldn't lose focus on win 8 2 seconds after mod information gets invalidated
- small bugfix related to new version scheme parsing
2013-10-06 13:34:34 +02:00
Tannin ba09054e6b Merge 2013-10-06 12:20:07 +02:00
Tannin 694e3ed279 bugfix: statusbar may have stayed enabled if an error occured on handling the refreshed-event 2013-10-06 12:19:46 +02:00
Tannin cffd9eb4e2 - hook.dll now doesn't inject to certain applications (currently steam, chrome and firefox)
- versioning system improved. Will now report "downgrades" for mods and support a different versioning system (requires manual switch)
- updates can now be ignored until a new version is uploaded
- new splash screen
- bugfix: a few memory leaks (shouldn't account for much)
- bugfix: result of GetModuleHandle wasn't zero-terminated in some cases
2013-10-05 14:20:48 +02:00
Tannin 640b14ef25 diagnosis plugin now warns when nitpick is installed 2013-09-30 18:33:45 +02:00
Tannin 47293827bb - download progress is now visible in task bar
- esp-tooltip now lists all masters, highlighting the missing ones
- python plugin will now report a problem if the path contains a semicolon
- leak detection now (somewaht) works around the fact that we don't always get a stack trace
- bugfix: mod meta-file is now reliably created if it was missing
- bugfix: parser for nxm-links didn't handle numbers in the mod name
- bugfix: small memory leak
2013-09-28 21:13:57 +02:00
Tannin 0a3169b808 - plugin tooltip now only lists the masters that aren't enabled (if any) 2013-09-26 19:10:44 +02:00
Tannin f4528c7aaa - bugfix: esp parsing could crash for broken/unrecognized esps
- bugfix: esp parser didn't handle oblivion esps correctly
2013-09-23 22:39:58 +02:00
Tannin 4f0a6e8b88 Added tag release v1.0.2 for changeset 0aaed2f8f48d 2013-09-22 13:24:53 +02:00
Tannin c57b172204 - removed some obsolete code
- MO will no longer start an application while the directory structure is being refreshed because MO may need to access profile files afterwards
- bugfix: the overwrite info-dialog was not destroyed and could thus keep a lock on files thus preventing those files from being moved/deleted
2013-09-22 13:10:21 +02:00
Tannin dfca8be71b - esp reader now handles invalid files more gracefully
- files moved will now also be treated as "deleted" in the old location so a newly created file with that same name is not created in overwrite
- introduced a mechanism by which MO can recognize if it crashed before when attempting to load a plugin. That plugin can be blacklisted so it doesn't get loaded again
- plugins can now programaticaly change their settings
- plugins can now store data persistently without exposing that data as settings
- requesting an unset-setting from a plugin is no longer treated as a bug
- clarified warning message for when files are in overwrite directory
- the proxyPython plugin will now discover if python initialization crashed MO on a previous session and give the user a chance to fix it or disable the plugin
- bugfix: GetModuleFileName modified the buffer past the zero termination. While this doesn't violate the API documentation it is different from the regular windows implementation
- bugfix: proxy plugins couldn't access the parent widget
- bugfix: when moving a file from overwrite to a mod the in-memory file structure wasn't updated
- bugfix: name input dialog for profiles allowed names that weren't valid directory names
- bugfix: profile dialog wasn't able to delete profiles if the name started or ended in whitespaces
- bugfix: The name-cells for plugin settings could be changed (without effect)
- removed a few obsolete files from the repository
2013-09-21 19:25:33 +02:00
Tannin 08037bf876 Added tag release v1.0.1 for changeset b90a2e9174c0 2013-09-21 18:59:47 +02:00
Tannin 500ab7f706 - bugfix: testing for missing masters at the wrong time seems to have caused crashes
- bugfix: mod list is now written to a temporary file first. Only on success is the original file overwritten
- bugfix: moving a mod priority to just above the overwrite could cause a crash or error message
- bugfix: versions with a release candidate number weren't sorted correctly (woops)
- bugfix: staging script didn't include archive.dll and dlls.manifest
- installation time on overwrite no longer updates constantly
2013-09-16 22:32:42 +02:00
Tannin 08309b71ba Added tag release v1.0.0rc1 for changeset 438584941a82 2013-09-15 16:11:16 +02:00
Tannin 98e5e57a84 - added support for mod page plugins
- re-introduced the integrated browser
- added a plugin to download from the tes alliance page
- the download list now contains the file description
- nexus interface now stores cookies persistently to reduce number of required log-ins
2013-09-15 15:20:00 +02:00
Tannin dce78b62b8 - bugfix: when installing mods through the nmm importer if no other mods were previously installed
the correct installation directory was never set
- bugfix: the nmm importer didn't "sanitize" mod names and potentially tried to create invalid directories
- bugfix: 0.99.x packages didn't contain qt plugins to handle certain image formats
2013-09-12 21:45:57 +02:00
Tannin af6e1c3ab4 - when installing mods from outside the download directory the absolute path is now stored
- added a context menu to the toolbar buttons so tool icons can be removed directly
- initweaks modinfo tab is now always available and allows new ini tweaks to be created
- fake esms are now treated as masters (as they should)
- MO will now display a warning if not all masters of an esp are enabled. The tooltip gives a list of required masters
- bugfix: path returned by getfullpathname was sometimes not correctly terminated
- bugfix: path after reverse-rerouting was sometimes incorrect, missing a path separator
- bugfix: change of current directory sometimes used a fake directory without need
- bugfix: icons in shortcut menu were not alwayscorrectly updated
2013-09-11 22:54:45 +02:00
Tannin 50325c8fc2 Added tag release v0.99.6 for changeset d9dedb857683 2013-09-05 21:14:19 +02:00
Tannin 7a382eab75 updated versions 2013-09-05 21:14:08 +02:00
Tannin 8e6868bf88 - bugfix: automatically removes a file from old NCC release that was interfering with the current version
- bugfix: fomod installer didn't find fomod files in nested folder
- bugfix: python proxy will now not even try to initialize python if python_dir contains no python.
This is necessary because the python interpreter crashes the application if the path is invalid
2013-09-05 21:04:20 +02:00
Tannin a891146446 Added tag release v0.99.5 for changeset f75473410ed3 2013-09-02 19:28:24 +02:00
Tannin 72f14df8a7 - bugfix: "overwrite" is no longer a localizable string, at least for now, because some pieces of code rely on the name 2013-09-02 19:22:40 +02:00
Tannin 0fa7155eb8 - bugfix: division-by-zero error in the newly introduced server-speed calculation
- bugfix: temp files extracted during fomod installation were not cleaned up. This still doesn't remove directories
- bugfix: fomod installer didn't find the installer xmls because they are in a subdirectory since release 0.99.4
2013-09-02 18:51:17 +02:00
Tannin c6c61ce792 Added tag release v0.99.4 for changeset a2ccfea95ef0 2013-09-02 18:48:52 +02:00
Tannin ef801879ab - separated python proxy into two dlls. One is a wrapper without external
dependencies that fulfills the plugin interface. The other contains the actual python
functionality. This way the outer dll can always be loaded and report issues.
- The build process embeds the second dll into the first, this way only one dll has to be shipped
2013-09-01 18:36:43 +02:00
Tannin 1e6c5f7c25 - added a new column for not-yet-endorsed mods
- set categories menu no longer closes when the mouse cursor leaves the menu
- MO will no longer change the endorsement flag if an update doesn't contain it
- the column selection for the mod list can now only be accessed by mouse,
hotkeys open the context menu of the mod
- now displaying a progress dialog during login. For unknown reasons MO hangs during that time
2013-09-01 13:40:44 +02:00
Tannin 49e1dd23b6 - mod list can now be sorted by install time
- the sorting of download archives wasn't actually by index instead of file time
- bugfix: some of the plugins crashed if they failed to create a mod
2013-08-31 17:11:17 +02:00
Tannin 9c31cfa915 - the download manager now registers download speed. Right now this is only used
to display an average speed on the settings menu
- added a python27.dll compiled with vc100. This can now be bundled without introducing more dependencies
- bugfix: extracting now stops after an error
- bugfix: the way hook.dll caused CREATE_ALWAYS/CREATE_NEW to always write into overwrite could lead to the
file being created when the call should have failed (because the file existed and was protected)
- bugfix: GetPrivateProfileString does NOT properly report files as missing. This means that
the ini-query optimization could optimize away requests that should work
- bugfix: fomod installer couldn't display images because they were unpacked to the wrong temporary location
- bugfix: When disabling local saves and choosing to delete the saves nothing happened
- bugfix: the python plugin couldn't find the pyqt libraries
2013-08-30 20:59:12 +02:00
Tannin 91dd38cb29 Added tag release v0.99.3 for changeset bf57300454f1 2013-08-25 13:32:33 +02:00
Tannin bf0db9c218 - position of splitter in main window is now saved and restored
- confirmation dialog before enabling/disabling all plugins
- bugfix: GetPrivateProfileString-hook potentially accessed buffer that is allowed to be NULL
- bugfix: attempt to extract an archive crashed MO in 0.99.2
- bugfix: archive list wasn't saved correctly in 0.99.2
- bugfix: plugins.txt was incorrectly interpreted as utf-8
2013-08-25 13:15:23 +02:00
Tannin 8fcf21e771 - column sizing is now changeable by the user yet still automatically resizes fit content on first start 2013-08-24 23:11:20 +02:00
Tannin b46b2fe6f2 Merge 2013-08-24 22:50:22 +02:00
Tannin e91eebefbe - download size is now displayed
- multiple esps/mods can now be enabled/disabled at once using space
- bugfix: fomod installer didn't compile because of changes to condition checking
- bugfix: broken inverse virtual name resolution in case of non-default mod directory
2013-08-24 22:50:00 +02:00
Tannin 2e605b275b Added tag release v0.99.2 for changeset 95e629510d01 2013-08-24 14:14:00 +02:00
Tannin 5f2a49b3be - added code for c++ based boss dummy
- fixed staging scripts
2013-08-24 14:12:58 +02:00
Tannin c4955231cf - turned boss dummy into a c++ project (unmanaged exports with c# is a pain)
- updated NCC to current NMM codebase
- updated translation files
2013-08-24 12:08:57 +02:00
Tannin 87f4e2df26 Merge 2013-08-17 08:54:53 +02:00
Tannin 9272013103 - bugfix: download manager will now properly pause all downloads on exiting the application
- bugfix: resumed downloads now get their automatic-retry-count reset
- fiddled with condition tests in fomod (not sure if it works right now)
2013-08-17 08:54:09 +02:00
Tannin 78c4178f2a - plugins that failed to load are now reported as problems
- some wording fixes in the tutorial
- updated proxyPython to a modified interface
2013-08-17 08:49:36 +02:00
Tannin 7d79e3ad1e - bugfix: nameprefix-flag incorrectly interpreted on oblivion-style bsas
- bugfix: optimization for missing inis fixed
- bugfix: fixmods didn't search for esps in overwrite
- bugfix: configurator didn't work for fallout new vegas because of a missing cast
- bugfix: configurator attempted parameter formatting on ini files instead of using the raw data
- bugfix: searching for a path in the directory structure could cause a crash when not using the directory output
- optimization to findfirstfile for cases where a single file is searched
- display of bsas changed. hopefully it is more understandable now
- cache for the test whether a mod is in conflict. Should speed ab scrolling in mod list
- mod list has now an additional column for the installation time
- nmm importer no longer cancels in cases where a data file references an undeclared mod.
- integrated improved settings.json for the configurator contributed by "delta534"
2013-08-15 22:13:18 +02:00
Tannin d0f2c4fcf7 - now avoids a few unnecessary copy operations during generation of the directory structure
- bugfix: circular dependency caused a memory leak
- bugfix: removing a single mod lead to the wrong mod being deleted
2013-07-17 20:58:58 +02:00
Tannin 36ac91e0b7 - basic diagnosis plugin now catches an issue where the users fontconfig.txt refers missing files
- plugins can now resolve relative file names on the virtual directory (no enumeration yet)
- bugfix: dummy plugins were not initialized
2013-07-14 14:59:01 +02:00
Tannin 5c968a1242 - added the ability to connect to the internet through a proxy
- integrated fomod installer now supports the or-operator for page conditions
- integrated fomod installer now caches condition results to speed up tests
2013-07-13 22:11:30 +02:00
Tannin e09cef3909 - minor fixes to ncc build files
- MO will now use system-wide proxy if one is configured
2013-07-13 11:52:40 +02:00
Tannin 8d34ae3413 - some fixes to the refreshing behaviour
- "fix" buttons in problems dialog are now actually functional
- python proxy now has diagnosis functionality to warn user if correct proxy version is not available
- python proxy now has a configurable python path
2013-07-13 10:10:46 +02:00
Tannin 849a0a0ef4 bugfix: nxmhandler in headless calls didn't save changes 2013-07-05 14:34:46 +02:00
Tannin 3b3717a021 - nxmhandler now has a ui to modify the proxy-handler
- mo now registers itself with nxmhandler when launching the browser
- pdbs are now generated for plugins
- reverted configurator to pyqt4
2013-06-29 21:10:53 +02:00
Tannin fe37b48dff - caching of downloadwidgets to fix performance problem, currently broken and disabled
- added new state for downloads "uninstalled" for mods that were at one point installed and then removed
- user-configured server preference is now used
- updated tutorial to account for removal of integrated browser
- reverted to qt 4
- using performance optimised findfirstfile on win vista and up
- bugfix: it was possible to disable all columns of the mod list
- bugfix: hook.dll doesn't load on win xp
2013-06-29 18:04:10 +02:00
Tannin f8c683f700 - some fixes for qt5 compatibility
- hook.dll no longer creates a dump and uninstalls it if an exception is reported that doesn't originate from it
- NCC used read-only transactions again because otherwise solid archives become unusably slow.
- removed the integrated nexus browser
- the mod description and motd are now rendered in QTextBrowser. This (and the above) eliminates the dependency on qtwebkit
- removed the direct file download for mod files
- reduced CPU usage during downloads by invalidating only one column of the download list. This widget still needs to be replaced
- added the complete filename as an option for the modname
- applications that require elevation can now be started by invoking an elevated secondary ModOrganizer instance
- MO will now register nexus file servers and provides a settings dialog to pick preferred servers. (This preference is not used yet)
- worked around 1-2 bugs in QSortFilterProxy
- handling of nxm links is now done by an external application. This allows the registration of different applications depending on the game
- integrated fomod installer now displays the screenshot in a scalable view
- bugfix: integrated fomod installer didn't name output files correctly if the name differs from the source name
- bugfix: a successful login to nexus was (sometimes?) not correctly detected as a success
- bugfix: top-level entries in QtGroupingProxy were sometimes incorrectly displayed as groups
- bugfix: GetPrivateProfile... optimization could cause null-pointer indirection
- bugfix: GetCurrentWorkingDirectory caused buffer overflow in case of pre-flighting (buffer size 0)
- bugfix: configurator plugin now also uses qt5 (it's currently broken though)
2013-06-20 21:55:37 +02:00
Tannin 49cbe03491 - completed Qt5 compatibility
- added GetFileVerisonInfoW hook for Windows 8 compatibility
- fixed BossDummy to compile correctly with current version of the RGiesecke.DllExport assembly
- fixed NCC components compiling with different Framewerk versions
- dropped files-list in Nexus-tab of modinfo dialog
2013-06-15 14:42:20 +02:00
Tannin 6069decb15 - mod list no longer loses selection whenever categories context menu gets hidden 2013-06-08 22:23:25 +02:00
Tannin 30dece9093 Merge 2013-06-07 18:30:26 +02:00
Tannin 50d0523622 - locking/unlocking esps can now be done for the whole selection
- bugfix: MO crashed if the locked index file is borked. This shouldn't happen
anymore so I'm not sure how that file breaks to begin with
2013-06-07 18:16:52 +02:00
Tannin 067f272da3 - bugfix: archive file wasn't closed after installation
- bugfix: batch installer was treated as handler for "manual" installations
- bugfix: dropped include of unused sip interface
2013-06-06 20:19:38 +02:00
Tannin 97111de140 Merge 2013-06-05 10:05:29 +02:00
Tannin 280691ebc3 - skyrim-specific optimization to accelerate startup
- bugfix in SetCurrentDirectory hook
2013-06-05 10:04:56 +02:00
Tannin 1606c1366f - install plugins now get a chance to update name, version and modid of mods
- NCC now makes name, version and modid from the info.xml file available to the installer
- integrated fomod installer also uses version and modid from the info.xml
- mods can now be renamed during installation
- configurator plugin now highlights changed keys and saves changes
2013-06-05 09:51:48 +02:00
Tannin 8077c1ad73 updated .hgignore 2013-05-28 23:17:41 +02:00
Tannin aadd076269 - added hook for ansi version of SHFileOperation, this function may not be routed to the unicode version in every windows variant 2013-05-28 23:14:49 +02:00
Tannin d8cb9a4e37 - bugfixes in hookdll related to path-rerouting
- bugfix: expanding modlist groups after changes to modlist works now
- bugfix: sorting grouped modlist was broken
2013-05-28 22:43:19 +02:00
Tannin 3c21d1884a Merge 2013-05-25 12:26:13 +02:00
Tannin 16bda49e06 - bugfix: mod priority ordering could become incorrect
- bugfix: when grouping is enabled, newly installed mods broke grouping
- bugfix: syncing overwrite didn't clean up emptied directory
2013-05-25 12:24:48 +02:00
Tannin daf8bab136 - bugfix: installation using custom installer always created mod directory
- batch installer now displays progress during mod installation
2013-05-23 20:03:35 +02:00
Tannin 2c4ba2c62c Merge 2013-05-22 20:48:23 +02:00
Tannin 0ae7d4753c - diagnosis plugin now reports file in overwrite as a problem
- bugfix: GetModuleFileName returned the wrong string length
- bugfix: Vector Exception Handler no longer stops hook.dll on recoverable errors
2013-05-22 20:43:08 +02:00
Tannin f0ba6ce95c - added NCC to repository
- deleting files from download manager now moves them to recycle bin instead of deleting permanentyl
- cleanup in installation manager
- ini editor (old) can now be configured to open files in external editor
- bugfix: .net check in ncc installer was broken
- bugfix: mod-overwrite dialog wasn't displayed for complex installers
2013-05-22 18:16:56 +02:00
Tannin cdea0c9da5 Merge 2013-05-19 11:37:03 +02:00
Tannin 0beb88760b - added hook for GetModuleFileName
- downloads are now identifiable by ID
- fixed a bug with the multi-select categories list
- fixed a problem with the nexus-login code breaking support for certain passwords
- fixed a bug where detection of archive invalidation didn't work correctly
- fixed ncc plugin trying to handle archives that aren't actually fomods
2013-05-19 11:36:36 +02:00
Tannin 45f6cd21a2 - extended plugin interface to allow plugins access to download manager
- extended plugin interface to allow installation of mods from files
- improved detection of online state
- download tab now also displays files supported through plugins
- batch installer now has basic functionality (downloads and installes files)
2013-05-17 20:44:40 +02:00
Tannin fc3753dcc5 Merge 2013-05-10 11:00:09 +02:00
Tannin 9bc123e8e2 - initial support for exposing the nexusbridge to python
- started improving usability of nexus bridge
- support for installers implemented in python
2013-05-10 10:57:35 +02:00
Tannin d161e1a0d6 - if no version is known for a mod, the file date is used
- added files for the python proxy
2013-04-14 20:49:18 +02:00
Tannin 1c9018e9fd - bugfix: wrong multibyte to widechar conversion in hookdll breaks internationalization
- bugfix: mod names not checked for validity on rename
- bugfix: mod list wasn't invalidated after rename (regression?)
- problem reports moved to separate dialog
- ncc plugin now does the check for dotNet
- python plugin wrapper started (only supports tools currently)
- new ini editor plugin in python (non-functional currently)
2013-04-13 19:23:18 +02:00
Tannin 4fbfc9aa54 - multi-selection in category window
- profile loading is now slightly more forgiving
2013-04-12 15:31:47 +02:00
Tannin 528338d7bf some code cleanup 2013-04-05 18:24:36 +02:00
Tannin 5b04f38345 added modlist view class (updates drop behaviour on modlist depending on mime type) 2013-04-04 21:51:13 +02:00
Tannin de27ab391f - creating mods from overwrite
- moving files from overwrite to mods
- offline mode
- several fixes to the grouping system
- fix to "duplicate translation" errors
2013-04-04 21:49:44 +02:00
Tannin d9a6dbb916 Merge 2013-03-29 10:26:19 +01:00
Tannin f682f82db5 some improvements to the grouped modlist views 2013-03-29 10:25:38 +01:00
Tannin a47d971788 Merge with default 2013-03-29 10:12:34 +01:00
Tannin 59d6b7840b - post-merge cleanup 2013-03-29 09:41:41 +01:00
Tannin b4220cf2f4 Merge with branch1.0 2013-03-27 21:04:27 +01:00
Tannin e0eb97922d - added hooks for getFileVersion* functions
- automatic donwload retry
- support for storing multiple download urls
- improved "query info" functionality
- some cleanup to download manager code
- external fomod installer dialog are now brought to front
- added shell... functions to have windows handle problematic situations
- added visual clue when filters are active
- esps are now automatically activated when installing a mod
- added option to never endorse a mod
- added "previous" and "next" buttons to mod info dialog
- improved the way messagedialog text is shortened
- coloring in mod info dialog now visible in other color schemes
- plugin list is now saved automatically
- vanilla bsas are now enabled even if they are not listed in the ini file
- bugfix: setting mod to maximum now doesn't try to place the mod below overwrite
2013-03-27 20:48:33 +01:00
Tannin 10485e15e4 - some cleanup to hookdll
- exchanged grouping proxies with existing solution from the kde project
2013-03-27 12:32:23 +01:00
Tannin ec0ea9df8d Merge with default 2013-03-22 18:57:45 +01:00
Tannin 24cc386191 removed obsolete files 2013-03-22 18:54:04 +01:00
Tannin 0a19f04339 - support for grouping filters for mod list (incomplete)
- offering multiple options for mod names during installation
- support for renaming profiles
- updated installer plugins
- minor bugfixes
2013-03-22 18:46:40 +01:00
Tannin 74c75e60d6 Added tag release v0.12.9 for changeset ff711d0a1fa9 2013-03-18 20:03:57 +01:00
Tannin 8b31996525 - bugfix: invalid ini file name when creating profile for oblivion from default settings
- bugfix: archives.txt file was potentially not generated if there were no bsas
- bugfix: static __declspec(thread) declaration causes crashes in windows versions before vista
- logger class in hook.dll now tries alternative names for the log file if it can't access the regular file
- path-environment variable for mo-spawned processes now contains the path to MO, in case the hook.dll needs to find the msvc-dlls
- stack-search in ini-limit hack now starts searching on local stack. This should find the right stack position for the hack more reliable
2013-03-18 20:03:46 +01:00
Tannin b3d0fcb208 - some more safety checks in the ini-limit removal code
- some code cleanup and minor bug fixes based on results from static code analysis
- added naemfilter for the esp list
- bsa changes are now stored automatically but delayed by up to 0.5 seconds (for performance reasons)
- bugfix: buffer overrun when certain functions are called with empty file names
- bugfix: reroute for the ini-limit fix was placed in the data segment
- bugfix: mod list got mixed up when the mod directory was changed externally
- bugfix: plugins.txt reroute on skyrim didn't work on winXP
- bugfix: MO could become unresponsive if the tutorial script couldn't be interpreted
2013-03-13 19:35:20 +01:00
Tannin 93e073c324 Added tag release v0.12.8 for changeset 0f4efc99546f 2013-03-06 19:33:55 +01:00
262 changed files with 29365 additions and 66795 deletions
+32
View File
@@ -2,3 +2,35 @@ syntax: glob
ModOrganizer-build-desktop*
outputd/*
output/*
build-ModOrganizer-*
source/NCC/*/bin
source/NCC/*/obj
source/NCC/bin
*.orig
source/plugins/proxyPython/build
staging/*
source - Copy/*
ModOrganizer-build-*
pdbs/*
source/NCC/BossDummy.x/*
*.ts
staging_prepare/*
staging_trans/*
tools/python_zip/*
Makefile
html
*.vcxproj
*.pdb
*.dll
*.exp
*.tlog
*.user
*.obj
*.suo
*.sln
*.log
*.filters
*.lib
syntax: regexp
Makefile\.(Debug|Release)
source/.*/debug/.*
+182 -22
View File
@@ -1,53 +1,139 @@
HOW TO BUILD
============
Intro:
------
Building Mod Organizer can be a rather daunting task especially if you're not very comfortable with C++ development under windows.
Please note that if you only want to work on and build a plugin you can save yourself a lot of trouble
Overview:
---------
As of Juli 2014 MO consists of the following subprojects:
- organizer: The main userinterface. heavy usage of various libraries
- hookdll: core library of the virtual file system
- uibase: interop between plugins and the main application as well as some reusable functionality
- shared: functionality shared between organizer and hookdll. I'm attempting to get rid of this library over time
- nxmhandler: tool to pass handling of nxm links to MO or other applications
- helper: tool for doing operations requiring elevated priviledges if MO doesn't have them
- proxydll: dll used in the "proxy dll" load mechanism
- esptk: small library containing functionality to work with esps/esms
- bsatk: small library containing functionality to work with bsas. Requires zlib to extract files. Requires boost_thread to provide multi-threaded extraction
- archive: small wrapper library around 7zip for dealing with mod archives. Requires 7zip
- NCC: extension to NMM to provide a binary with command line interface for fomod installation. This is c# code and does not build with the rest of the project. Requires the rest of NMM
- bossdummy: dummy dll that looks like the boss.dll. This is used instead of the real boss dlls in NCC to save some disk space
- pythonrunner: library for embedding python code. Requires boost_python, python 2.7 and pyqt4
- loot_cli: this is a command line client of loot. This can be better integrated with MO than the official loot client.
And various plugins:
- bsaExtractor: offers to extract bsas after a mod has been installed
- checkFNIS: Activates each time an application is started from MO and runs fnis if necessary
- diagnoseBasic: Various diagnostic checks on the game
- inieditor: minimalistic file editor for ini files
- installerBain: handles non-scripted bain installers
- installerBundle: handles installation of archives wrapped in archives
- installerFomod: handles installation of xml fomods
- installerManual: handles installations of archives that aren't supported by any other plugin (or if the user chooses to do the installation manually)
- installerNCC: handles installation of any fomod (requires NCC)
- installerQuick: handles very simple one-click installations
- NMMImport: importer from existing nmm installation
- proxyPython: integrates pythonrunner as a plugin into MO
- pyniEdit: more user-friendly ini editor. python code
- previewBase: used for file previews. this plugin covers image formats supported by the qt installation (usually at least jpg, gif, png) and text files
- previewDDS: used to preview dds textures. uses code from the nif file format library
There are a few more plugins that are either broken or samples
- installerBCF: this was intended to use .bcf (bain conversion file) files as installation instructions but currently it is completely function-less
- helloWorldCpp: sample for cpp plugins. This should compile even without fulfilling most dependencies below
- pageTESAlliance: integrates the tes alliance page into MO. This integration is not nearly as tight as that of nexus.
Requirements:
-------------
Visual C++ compiler 2010 (VC 10.0) or up
- Included in visual c++ express 2010 or windows sdk 7.0
- Included in visual c++ express 2010 or windows sdk 7.x
- Do install windows sdk too if only for the cdb debugger which is included in that package
Note: If you're having trouble installing the windows sdk, you may be affected by this bug: http://support.microsoft.com/kb/2717426
QtSDK 4.8.x (http://qt-project.org/downloads)
- Qt5 is not yet supported but WIP
Qt Libraries 4.8.x (http://qt-project.org/downloads)
- i.e. "Qt libraries 4.8.6 for Windows (VS 2010, 235 MB)"
- tested: 4.8.6
- Install according to instruction
Qt 5 Compatibility:
MO compiles and mostly runs correctly built with Qt 5.3 and VC++ 2013 but
- python plugins haven't been rewritten to use qt5 yet
- pyqt5 isn't distributed as binaries for python 2.7 so this needs to be set up and built first
- tutorial doesn't work because it seems to be impossible to create a transparent Qt Quick control...
- the previewdds plugin only compiles with the opengl variant of the qt 5 distribution
- Qt5 is a bi*** to distribute
boost libraries (http://www.boost.org/)
- Compile according to their instructions (using vc++)
- As of time of writing boost_thread is the only compiled boost library used, you can
disable the others to safe yourself the compile time
- tested: 1.55
- Build according to their instructions (using vc++): http://www.boost.org/doc/libs/1_54_0/more/getting_started/windows.html
- A few of the boost libraries need to be built (the rest is header-only). The only compiled libs MO needs (at the time of writing) are
boost_thread (for everything that links agains bsatk) and boost_python (for pythonrunner). You can disable the others to save yourself compile time (even on a modern system compiling boost can easily take an hour)
zlib (http://www.zlib.net/)
- Compile static library according to their instructions
- You should have a "zlibstatic.lib" under "build" afterwards
- Depending on the version of zlib and how you built you should have a file called zlibstatic.lib or zlibstat.lib in "build" or "x86\ZLibStatRelease".
- Please copy that lib file to "build\zlibstatic.lib" (if it doesn't exist) so MO finds it.
7z sourcecode (http://www.7-zip.org/download.html)
- only for "archive" subproject
- no need to compile, will be linked into project
Python 2.7 (32-bit)
- only for pythonrunner
PyQt4 for Python 2.7
- tested: 4.10
- only for pythonrunner
7z.dll (http://www.7-zip.org/download.html)
- Part of the 7-zip program
- Has to be the 32-bit dll! (approx. 893kb)
Recommended:
------------
Qt Creator
- Included in QtSDK but there might be a newer version as a separate download
- http://qt-project.org/downloads#qt-creator
- I.e. "Qt Creator 2.8.1 for Windows (53 MB)"
- With Qt Creator usually the rule is "the newer the better"
- Start Qt Creator and check if things are set up correctly:
1) Go to Tools > Options > Build & Run > Qt Versions
2.1) If the QtSDK 4.8.x you installed earlier is not auto-detected, click "Add" to add it manually
2.2) Navigate to your <your qt4 installation>\bin\qmake.exe
2.3) Restart qt creator
3) Go to Tools > Options > Build & Run > Kits
3.1) If no Kit is auto-detected (or the auto-detected ones have picked up the wrong qt or vc++ installation) click "Add"
3.2) Enter a Name (i.e. "Qt 4.8.5 MSVC2010 32bit")
3.3) In Compiler select the visual studio compiler installed earlier (may show up as "Microsoft Windows SDK for Windows x). Make sure you select the x86 variant
3.4) CDB should be auto-detected
3.5) Select the qt version set up earlier
4) Apply and close the options
Set up (using Qt Creator):
--------------------------
1. Using Qt Creator open source/ModOrganizer.pro from your working copy
2. Open the "Projects" tab, open the "Details" for "Build Environment"
3. Click "Add" to add a variable called "BOOSTPATH" with the path of your boost installation as the value (i.e. C:\code\boost_1_52_0)
4. Click "Add" to add a variable called "ZLIBPATH" with the path of your zlib installation as the value (i.e. C:\code\zlib-1.2.7)
5. Switch the build configuration at the very top of the same page from "debug" to "release" (or vice versa) and repeat steps 3 and 4
6. Compile the configuration(s) you want to use (debug and/or release) (Build All). This should compile correctly.
3a. Click "Add" to add a variable called "BOOSTPATH" with the path of your boost installation as the value (i.e. C:\code\boost_1_49_0)
3b. Click "Add" to add a variable called "ZLIBPATH" with the path of your zlib installation as the value (i.e. C:\code\zlib-1.2.7)
3c. Click "Add" to add a variable called "SEVENZIPPATH" with the path of your 7zip installation as the value (i.e. C:\code\7zip)
3d. Click "Add" to add a variable called "PYTHONPATH" with the path of your python installation as the value (i.e. C:\code\python)
4. Switch the build configuration at the very top of the same page from "debug" to "release" (or vice versa) and repeat step 3
5. Compile the configuration(s) you want to use (debug and/or release) (Build All). This should compile correctly.
6. <reserved for future use. Maybe grab a coffee?>
7. return to the "projects" tab and switch to "Run Settings"
8. Determine the folder of the qt binaries in the package you downloaded. This could be "QtSDK\Desktop\Qt\4.8.5\msvc2010\bin" or "Qt4.8.5\bin"
For Release build:
8r. Add a "Run configuration" that points to <your working copy>\output\ModOrganizer.exe
9r. Copy "7z.dll" to <your working copy>\output\dlls
10r. From QtSDK\Desktop\Qt\4.8.0\msvc2010\bin copy the following files to <your working copy>\output\dlls: QtCore4.dll, QtDeclarative4.dll, QtGui4.dll, QtNetwork4.dll, QtScript4.dll, QtSql4.dll, QtWebkit4.dll, QtXml4.dll, QtXmlPatterns4.dll
9r. Add a "Run configuration" that points to <your working copy>\output\ModOrganizer.exe
10r. Copy "7z.dll" to <your working copy>\output\dlls
11r. From the qt binaries directory, copy the following files to <your working copy>\output\dlls: QtCore4.dll, QtDeclarative4.dll, QtGui4.dll, QtNetwork4.dll, QtScript4.dll, QtSql4.dll, QtWebkit4.dll, QtXml4.dll, QtXmlPatterns4.dll
For Debug build:
8d. Add a "Run configuration" that points to <your working copy>\outputd\ModOrganizer.exe
9d. Copy "7z.dll" to <your working copy>\outputd\dlls
10d. From QtSDK\Desktop\Qt\4.8.0\msvc2010\bin copy the following files to <your working copy>\outputd\dlls: QtCored4.dll, QtDeclaratived4.dll, QtGuid4.dll, QtNetworkd4.dll, QtScriptd4.dll, QtSqld4.dll, QtWebkitd4.dll, QtXmld4.dll, QtXmlPatternsd4.dll
9d. Add a "Run configuration" that points to <your working copy>\outputd\ModOrganizer.exe
10d. Copy "7z.dll" to <your working copy>\outputd\dlls
11d. From the qt binaries copy the following files to <your working copy>\outputd\dlls: QtCored4.dll, QtDeclaratived4.dll, QtGuid4.dll, QtNetworkd4.dll, QtScriptd4.dll, QtSqld4.dll, QtWebkitd4.dll, QtXmld4.dll, QtXmlPatternsd4.dll
Now you should be able to compile and run Mod Organizer.
Please note that when you change anything apart from the "organizer" subproject, qt creator may not pick up on the changes
@@ -65,4 +151,78 @@ Set up (without Qt Creator):
I'm not using this workflow so I can't give more detailed instructions.
Please note that the primary project format of MO remains qmake, if you work with visual studio and make changes to the project (like adding
source files) you have to manually transfer those changes to the .pro file.
source files) you have to manually transfer those changes to the .pro file.
-----------------
Troubleshooting (thanks to Ross):
-----------------
1) When I try to build, I am seeing the error "error: LNK1104: cannot open file 'zlibstatic.lib'"
a) Make sure you have the following files
{ZLIBPATH}\build\zconf.h
{ZLIBPATH}\build\zlib.h
{ZLIBPATH}\build\zlibstatic.lib
b) make sure "zlibstat.lib" was renamed to "zlibstatic.lib"
c) currently, there are references to zlibstatic in the following 2 project files:
./bsatk/bsatk.pro
./hookdll/hookdll.pro
2) After building, I try to open {MOPROJECTPATH}\outputd\ModOragnizer.exe and get this error
"The program can't start because QtDeclaratived4.dll is missing from your computer. Try reinstalling the program to fix this problem."
-> When setting up Qt4.8.x, make sure you copied the "d" (debug) versions of the dll files to {MOPROJECTPATH}\outputd\dlls
If you copied the release version or did not copy the dlls at all, you may see this error.
The *.dll files can be found in {QT48xPATH}\bin
Similiar:
http://stackoverflow.com/questions/11196416/cant-start-qt-exe-file-on-windows-7
3) I am getting one or more of the the following compiler warnings...
"{MOPROJECTPATH}\source\bsatk\bsaexception.cpp:32: warning: C4996: 'vsnprintf': This function or variable may be unsafe.
Consider using vsnprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details."
-> Ignore/suppress warning like this and make be ultra-careful using printf-style functions. vsnprintf_s is a visual-c++ only function so using those would make porting (i.e. to mingw) harder
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\stdio.h:354: see declaration of 'vsnprintf'"
-> see previous
"debug\bsaarchive.obj:-1: warning: LNK4042: object specified more than once; extras ignored"
-> This appears to be an issue when using VC++ 2010 as the compiler. There are some posts on StackOverflow
which suggest fixes when using VC++ as the IDE, but not sure how to apply them to Qt Creator.
http://stackoverflow.com/questions/3729515
http://stackoverflow.com/questions/3695174
-> Also, not sure if this affects VC++ 2012 / VC++ 2013 / GCC via cygwin/mingw.
Not even sure if the project would successfully compile on these.
"{MOPROJECTPATH}\source\organizer\mainwindow.cpp:3995: warning: C4428: universal-character-name encountered in source"
-> very pointless warning.
http://stackoverflow.com/questions/11589571
http://stackoverflow.com/questions/7078013
the best solution I saw was to just disable the warning altogether...
#pragma warning( disable : 4428 )
"warning: LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library"
-> You can always add a #pragma to ignore them :P
http://msdn.microsoft.com/en-us/library/2c8f766e%28v=vs.80%29.aspx
4) I got the following error while building...
"error: LNK1201: error writing to program database
'{MOPROJECTPATH}\{whatever-your-build-directory-name-is}\organizer\debug\ModOrganizer.pdb';
check for insufficient disk space, invalid path, or insufficient privilege"
-> I had this happen after trying to look at something in memory via Process Explorer.
To resolve, I killed and restarted PE. Alternatively, you could probably use the
Unlocker utility. After unlocking, I manually deleted everything in the directory.
Unlocker: http://www.filehippo.com/download_unlocker/ or http://www.emptyloop.com/unlocker/
Warning: With Unlocker v1.9.2, you must select "Advanced" then uncheck everything to
avoid having some Delta toolbar garbage installed...
+41 -12
View File
@@ -1,22 +1,51 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = bsatk \
shared \
uibase \
organizer \
hookdll \
archive \
helper \
shared \
uibase \
organizer \
hookdll \
archive \
helper \
plugins \
proxydll
proxydll \
nxmhandler \
BossDummy \
pythonRunner \
esptk
pythonRunner.depends = uibase
plugins.depends = pythonRunner uibase
hookdll.depends = shared
organizer.depends = shared, uibase
organizer.depends = shared uibase plugins
CONFIG(debug, debug|release) {
DESTDIR = outputd
DESTDIR = $$PWD/../outputd
} else {
DESTDIR = output
DESTDIR = $$PWD/../output
}
STATICDATAPATH = $${DESTDIR}\\..\\tools\\static_data\\dlls
DLLSPATH = $${DESTDIR}\\dlls
otherlibs.path = $$DLLSPATH
otherlibs.files += $${STATICDATAPATH}\\7z.dll \
$${BOOSTPATH}\\stage\\lib\\boost_python-vc*-mt-1*.dll
qtlibs.path = $$DLLSPATH
greaterThan(QT_MAJOR_VERSION, 4) {
QTLIBNAMES += Core Gui Network OpenGL Script Sql Svg Qml Quick Webkit Widgets Xml XmlPatterns
} else {
QTLIBNAMES += Core Declarative Gui Network OpenGL Script Sql Svg Webkit Xml XmlPatterns
}
QTLIBSUFFIX = $${QT_MAJOR_VERSION}.dll
CONFIG(debug, debug|release): QTLIBSUFFIX = "d$${QTLIBSUFFIX}" # Can't use Debug: .. here, it ignores the line - no idea why, as it works in BossDummy.pro
for(QTNAME, QTLIBNAMES) {
QTFILE = Qt$${QTNAME}
qtlibs.files += $$[QT_INSTALL_BINS]\\$${QTFILE}$${QTLIBSUFFIX}
}
INSTALLS += qtlibs otherlibs
+85
View File
@@ -0,0 +1,85 @@
/*
Copyright (C) 2014 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "aboutdialog.h"
#include "ui_aboutdialog.h"
#include <utility.h>
AboutDialog::AboutDialog(const QString &version, QWidget *parent)
: QDialog(parent)
, ui(new Ui::AboutDialog)
{
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_BOOST] = "boost.txt";
m_LicenseFiles[LICENSE_CCBY3] = "by-sa3.txt";
m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt";
m_LicenseFiles[LICENSE_APACHE2] = "apache-license-2.0.txt";
addLicense("Qt 4.8.5", LICENSE_LGPL3);
addLicense("Qt Json", LICENSE_GPL3);
addLicense("Boost Library", LICENSE_BOOST);
addLicense("Tango Icon Theme", LICENSE_NONE);
addLicense("RRZE Icon Set", LICENSE_CCBY3);
addLicense("7-zip", LICENSE_LGPL3);
addLicense("ZLib", LICENSE_ZLIB);
addLicense("NIF File Format Library", LICENSE_BSD3);
addLicense("BOSS (modified)", LICENSE_GPL3);
addLicense("Alphanum Algorithm", LICENSE_ZLIB);
addLicense("Castle Core", LICENSE_APACHE2);
ui->nameLabel->setText(QString("<span style=\"font-size:12pt; font-weight:600;\">%1 %2</span>").arg(ui->nameLabel->text()).arg(version));
#ifdef HGID
ui->revisionLabel->setText(ui->revisionLabel->text() + " " + HGID);
#else
ui->revisionLabel->setText(ui->revisionLabel->text() + " unknown");
#endif
}
AboutDialog::~AboutDialog()
{
delete ui;
}
void AboutDialog::addLicense(const QString &name, Licenses license)
{
QListWidgetItem *item = new QListWidgetItem(name);
item->setData(Qt::UserRole, license);
ui->creditsList->addItem(item);
}
void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem*)
{
auto iter = m_LicenseFiles.find(current->data(Qt::UserRole).toInt());
if (iter != m_LicenseFiles.end()) {
QString filePath = qApp->applicationDirPath() + "/license/" + iter->second;
QString text = MOBase::readFileText(filePath);
ui->licenseText->setText(text);
} else {
ui->licenseText->setText(tr("No license"));
}
}
+70
View File
@@ -0,0 +1,70 @@
#ifndef ABOUTDIALOG_H
/*
Copyright (C) 2014 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#define ABOUTDIALOG_H
#include <QDialog>
#include <QListWidgetItem>
#include <map>
#include <vector>
#include <utility>
namespace Ui {
class AboutDialog;
}
class AboutDialog : public QDialog
{
Q_OBJECT
public:
explicit AboutDialog(const QString &version, QWidget *parent = 0);
~AboutDialog();
private:
enum Licenses {
LICENSE_NONE,
LICENSE_LGPL3,
LICENSE_GPL3,
LICENSE_BSD3,
LICENSE_BOOST,
LICENSE_CCBY3,
LICENSE_ZLIB,
LICENSE_APACHE2
};
private:
void addLicense(const QString &name, Licenses license);
private slots:
void on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
private:
Ui::AboutDialog *ui;
std::map<int, QString> m_LicenseFiles;
};
#endif // ABOUTDIALOG_H
+310
View File
@@ -0,0 +1,310 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>335</height>
</rect>
</property>
<property name="windowTitle">
<string>About</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="iconLabel">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="resources.qrc">:/MO/gui/mo_icon.ico</pixmap>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="about">
<attribute name="title">
<string>About</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string notr="true">Mod Organizer</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="revisionLabel">
<property name="text">
<string>Revision:</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string notr="true">Copyright 2011-2014 Sebastian Herbord</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;See the GNU General Public License for more details.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="software">
<attribute name="title">
<string>Used Software</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QListWidget" name="creditsList"/>
</item>
<item>
<widget class="QTextBrowser" name="licenseText"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="credits">
<attribute name="title">
<string>Credits</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Translators</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QListWidget" name="listWidget_2">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<item>
<property name="text">
<string notr="true">pndrev (German)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">DaWul (Spanish)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Fiama (Spanish)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Alyndiar (French)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Jlkawaii (French)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Rigoletto (French)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Scythe1912 (Chinese)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">yc0620shen (Chinese)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">miraclefreak (Czech)</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">tokcdk (Russian)</string>
</property>
</item>
<item>
<property name="text">
<string>Ren (Korean)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Others</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QListWidget" name="listWidget">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<item>
<property name="text">
<string notr="true">blacksol</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">DoubleYou</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">deathneko11</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Bridger</string>
</property>
</item>
<item>
<property name="text">
<string>GamerPoet</string>
</property>
</item>
<item>
<property name="text">
<string>Gopher</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">GSDFan</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Uhuru</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Wolverine2710</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">z929669</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="resources.qrc"/>
</resources>
<connections>
<connection>
<sender>closeButton</sender>
<signal>clicked()</signal>
<receiver>AboutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>460</x>
<y>313</y>
</hint>
<hint type="destinationlabel">
<x>253</x>
<y>167</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+20 -25
View File
@@ -1,22 +1,22 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "activatemodsdialog.h"
#include "ui_activatemodsdialog.h"
@@ -30,7 +30,7 @@ ActivateModsDialog::ActivateModsDialog(const std::map<QString, std::vector<QStri
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
QHeaderView *headerView = modsTable->horizontalHeader();
#if QT_VERSION >= 0x050000
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
headerView->setSectionResizeMode(0, QHeaderView::Stretch);
headerView->setSectionResizeMode(1, QHeaderView::Interactive);
#else
@@ -65,11 +65,6 @@ ActivateModsDialog::~ActivateModsDialog()
}
void ActivateModsDialog::on_buttonBox_accepted()
{
}
std::set<QString> ActivateModsDialog::getModsToActivate()
{
std::set<QString> result;
+70 -71
View File
@@ -1,71 +1,70 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTIVATEMODSDIALOG_H
#define ACTIVATEMODSDIALOG_H
#include "tutorabledialog.h"
#include <map>
#include <set>
namespace Ui {
class ActivateModsDialog;
}
/**
* @brief Dialog that is used to batch activate/deactivate mods and plugins
**/
class ActivateModsDialog : public MOBase::TutorableDialog
{
Q_OBJECT
public:
/**
* @brief constructor
*
* @param missingPlugins a map containing missing plugins that need to be activated
* @param parent ... Defaults to 0.
**/
explicit ActivateModsDialog(const std::map<QString, std::vector<QString> > &missingPlugins, QWidget *parent = 0);
~ActivateModsDialog();
/**
* @brief get a list of mods that the user chose to activate
*
* @note This can of ocurse only be called after the dialog has been displayed
*
* @return set< QString > the mods to activate
**/
std::set<QString> getModsToActivate();
/**
* @brief get a list of plugins that should be activated
*
* @return set< QString > the plugins to activate. This contains only plugins that become available after enabling the mods retrieved with getModsToActivate
**/
std::set<QString> getESPsToActivate();
private slots:
void on_buttonBox_accepted();
private:
Ui::ActivateModsDialog *ui;
};
#endif // ACTIVATEMODSDIALOG_H
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTIVATEMODSDIALOG_H
#define ACTIVATEMODSDIALOG_H
#include "tutorabledialog.h"
#include <map>
#include <set>
namespace Ui {
class ActivateModsDialog;
}
/**
* @brief Dialog that is used to batch activate/deactivate mods and plugins
**/
class ActivateModsDialog : public MOBase::TutorableDialog
{
Q_OBJECT
public:
/**
* @brief constructor
*
* @param missingPlugins a map containing missing plugins that need to be activated
* @param parent ... Defaults to 0.
**/
explicit ActivateModsDialog(const std::map<QString, std::vector<QString> > &missingPlugins, QWidget *parent = 0);
~ActivateModsDialog();
/**
* @brief get a list of mods that the user chose to activate
*
* @note This can of ocurse only be called after the dialog has been displayed
*
* @return set< QString > the mods to activate
**/
std::set<QString> getModsToActivate();
/**
* @brief get a list of plugins that should be activated
*
* @return set< QString > the plugins to activate. This contains only plugins that become available after enabling the mods retrieved with getModsToActivate
**/
std::set<QString> getESPsToActivate();
private slots:
private:
Ui::ActivateModsDialog *ui;
};
#endif // ACTIVATEMODSDIALOG_H
-98
View File
@@ -1,98 +0,0 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "archivetree.h"
#include <QDragMoveEvent>
ArchiveTree::ArchiveTree(QWidget *parent) :
QTreeWidget(parent)
{
}
bool ArchiveTree::testMovePossible(QTreeWidgetItem *source, QTreeWidgetItem *target)
{
if ((target == NULL) ||
(source == NULL)) {
return false;
}
if ((source == target) ||
(source->parent() == target)) {
return false;
}
return true;
}
void ArchiveTree::dragEnterEvent(QDragEnterEvent *event)
{
QTreeWidgetItem *source = this->currentItem();
if ((source == NULL) || (source->parent() == NULL)) {
// can't change top level
event->ignore();
return;
} else {
QTreeWidget::dragEnterEvent(event);
}
}
void ArchiveTree::dragMoveEvent(QDragMoveEvent *event)
{
if (!testMovePossible(this->currentItem(), itemAt(event->pos()))) {
event->ignore();
} else {
QTreeWidget::dragMoveEvent(event);
}
}
void ArchiveTree::dropEvent(QDropEvent *event)
{
event->ignore();
QTreeWidgetItem *target = itemAt(event->pos());
QList<QTreeWidgetItem*> sourceItems = this->selectedItems();
for (QList<QTreeWidgetItem*>::iterator iter = sourceItems.begin();
iter != sourceItems.end(); ++iter) {
QTreeWidgetItem *source = *iter;
if ((source->parent() != NULL) &&
testMovePossible(source, target)) {
source->parent()->removeChild(source);
if (target->data(0, Qt::UserRole).toInt() != 0) {
// target is a file
if (target->parent() == NULL) {
// this should really not happen, how should a
// file get to the top level?
return;
}
int index = target->parent()->indexOfChild(target);
target->parent()->insertChild(index, source);
emit changed();
} else {
// target is a directory
target->insertChild(target->childCount(), source);
emit changed();
}
}
}
}
-55
View File
@@ -1,55 +0,0 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ARCHIVETREE_H
#define ARCHIVETREE_H
#include <QTreeWidget>
/**
* @brief QT tree widget used to display the content of an archive in the manual installation dialog
**/
class ArchiveTree : public QTreeWidget
{
Q_OBJECT
public:
explicit ArchiveTree(QWidget *parent = 0);
signals:
void changed();
public slots:
protected:
virtual void dragEnterEvent(QDragEnterEvent *event);
virtual void dragMoveEvent(QDragMoveEvent *event);
virtual void dropEvent(QDropEvent *event);
private:
bool testMovePossible(QTreeWidgetItem *source, QTreeWidgetItem *target);
};
#endif // ARCHIVETREE_H
-124
View File
@@ -1,124 +0,0 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "baincomplexinstallerdialog.h"
#include "textviewer.h"
#include "ui_baincomplexinstallerdialog.h"
#include <QDir>
using namespace MOBase;
BainComplexInstallerDialog::BainComplexInstallerDialog(DirectoryTree *tree, const QString &modName, bool hasPackageTXT, QWidget *parent)
: TutorableDialog("BainInstaller", parent), ui(new Ui::BainComplexInstallerDialog), m_Manual(false)
{
ui->setupUi(this);
ui->nameEdit->setText(modName);
for (DirectoryTree::const_node_iterator iter = tree->nodesBegin(); iter != tree->nodesEnd(); ++iter) {
const QString &dirName = (*iter)->getData().name;
if ((dirName.compare("fomod", Qt::CaseInsensitive) == 0) ||
(dirName.startsWith("--"))) {
continue;
}
QListWidgetItem *item = new QListWidgetItem(ui->optionsList);
item->setText((*iter)->getData().name);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(item->text().mid(0, 2) == "00" ? Qt::Checked : Qt::Unchecked);
item->setData(Qt::UserRole, qVariantFromValue((void*)(*iter)));
ui->optionsList->addItem(item);
}
ui->packageBtn->setEnabled(hasPackageTXT);
}
BainComplexInstallerDialog::~BainComplexInstallerDialog()
{
delete ui;
}
QString BainComplexInstallerDialog::getName() const
{
return ui->nameEdit->text();
}
void BainComplexInstallerDialog::moveTreeUp(DirectoryTree *target, DirectoryTree::Node *child)
{
for (DirectoryTree::const_node_iterator iter = child->nodesBegin();
iter != child->nodesEnd();) {
target->addNode(*iter, true);
iter = child->detach(iter);
}
for (DirectoryTree::const_leaf_reverse_iterator iter = child->leafsRBegin();
iter != child->leafsREnd(); ++iter) {
target->addLeaf(*iter);
}
}
DirectoryTree *BainComplexInstallerDialog::updateTree(DirectoryTree *tree)
{
DirectoryTree *newTree = new DirectoryTree;
for (DirectoryTree::const_node_reverse_iterator iter = tree->nodesRBegin();
iter != tree->nodesREnd();) {
QList<QListWidgetItem*> items = ui->optionsList->findItems((*iter)->getData().name, Qt::MatchFixedString);
if ((items.count() == 1) && (items.at(0)->checkState() == Qt::Checked)) {
moveTreeUp(newTree, *iter);
}
iter = tree->erase(iter);
}
return newTree;
}
void BainComplexInstallerDialog::on_okBtn_clicked()
{
this->accept();
}
void BainComplexInstallerDialog::on_cancelBtn_clicked()
{
this->reject();
}
void BainComplexInstallerDialog::on_manualBtn_clicked()
{
m_Manual = true;
this->reject();
}
void BainComplexInstallerDialog::on_packageBtn_clicked()
{
TextViewer viewer("package.txt", this);
viewer.setDescription("");
viewer.addFile(QDir::tempPath().append("/package.txt"), false);
viewer.exec();
}
-95
View File
@@ -1,95 +0,0 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BAINCOMPLEXINSTALLERDIALOG_H
#define BAINCOMPLEXINSTALLERDIALOG_H
#include "mytree.h"
#include "installdialog.h"
#include "tutorabledialog.h"
namespace Ui {
class BainComplexInstallerDialog;
}
/**
* @brief Dialog to choose from options offered by a (complex) bain package
**/
class BainComplexInstallerDialog : public MOBase::TutorableDialog
{
Q_OBJECT
public:
/**
* @brief Constructor
*
* @param tree the directory tree of the archive. The caller is resonsible to verify this actually qualifies as a bain installer
* @param modName proposed name for the mod. The dialog allows the user to change this
* @param hasPackageTXT set to true if a package.txt is available for this archive. The file has to be unpacked to QDir::tempPath before displaying the dialog!
* @param parent parent widget
**/
explicit BainComplexInstallerDialog(MOBase::DirectoryTree *tree, const QString &modName, bool hasPackageTXT, QWidget *parent);
~BainComplexInstallerDialog();
/**
* @return bool true if the user requested the manual dialog
**/
bool manualRequested() const { return m_Manual; }
/**
* @return QString the (user-modified) name to be used for the mod
**/
QString getName() const;
/**
* @brief retrieve the updated archive tree from the dialog. The caller is responsible to delete the returned tree.
*
* @note This call is destructive on the input tree!
*
* @param tree input tree. (TODO isn't this the same as the tree passed in the constructor?)
* @return DataTree* a new tree with only the selected options and directories arranged correctly. The caller takes custody of this pointer!
**/
MOBase::DirectoryTree *updateTree(MOBase::DirectoryTree *tree);
private slots:
void on_manualBtn_clicked();
void on_okBtn_clicked();
void on_cancelBtn_clicked();
void on_packageBtn_clicked();
private:
void moveTreeUp(MOBase::DirectoryTree *target, MOBase::DirectoryTree::Node *child);
private:
Ui::BainComplexInstallerDialog *ui;
bool m_Manual;
};
#endif // BAINCOMPLEXINSTALLERDIALOG_H
+113 -48
View File
@@ -1,27 +1,28 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bbcode.h"
#include <QRegExp>
#include <map>
#include <algorithm>
#include <boost/assign.hpp>
namespace BBCode {
@@ -38,29 +39,65 @@ public:
return s_Instance;
}
QString convertTag(const QString &input, int &length)
QString convertTag(QString input, int &length)
{
// extract the tag name
m_TagNameExp.indexIn(input, 1, QRegExp::CaretAtOffset);
QString tagName = m_TagNameExp.cap(0).toLower();
//qDebug("tag name %s", tagName.toUtf8().constData());
TagMap::iterator tagIter = m_TagMap.find(tagName);
if (tagIter != m_TagMap.end()) {
// recognized tag
if (tagName.endsWith('=')) {
tagName.chop(1);
}
QString closeTag = tagName == "*" ? "<br/>"
: QString("[/%1]").arg(tagName);
int closeTagPos = input.indexOf(closeTag, 0, Qt::CaseInsensitive);
//qDebug("close tag %s at %d", closeTag.toUtf8().constData(), closeTagPos);
int closeTagPos = 0;
int closeTagLength = 0;
if (tagName == "*") {
// ends at the next bullet point
closeTagPos = input.indexOf(QRegExp("(\\[\\*\\]|</ul>)", Qt::CaseInsensitive), 3);
// leave closeTagLength at 0 because we don't want to "eat" the next bullet point
} else if (tagName == "line") {
// ends immediately after the tag
closeTagPos = 6;
// leave closeTagLength at 0 because there is no close tag to skip over
} else {
QString closeTag = QString("[/%1]").arg(tagName);
closeTagPos = input.indexOf(closeTag, 0, Qt::CaseInsensitive);
if (closeTagPos == -1) {
// workaround to improve compatibility: add fake closing tag
input.append(closeTag);
closeTagPos = input.size() - closeTag.size();
}
closeTagLength = closeTag.size();
}
if (closeTagPos > -1) {
length = closeTagPos + closeTag.length();
length = closeTagPos + closeTagLength;
QString temp = input.mid(0, length);
if (tagIter->second.first.indexIn(temp) == 0) {
return temp.replace(tagIter->second.first, tagIter->second.second);
if (tagIter->second.second.isEmpty()) {
if (tagName == "color") {
QString color = tagIter->second.first.cap(1);
QString content = tagIter->second.first.cap(2);
if (color.at(0) == '#') {
return temp.replace(tagIter->second.first, QString("<font style=\"color: %1;\">%2</font>").arg(color, content));
} else {
auto colIter = m_ColorMap.find(color.toLower());
if (colIter != m_ColorMap.end()) {
color = colIter->second;
}
return temp.replace(tagIter->second.first, QString("<font style=\"color: #%1;\">%2</font>").arg(color, content));
}
} else {
qWarning("don't know how to deal with tag %s", qPrintable(tagName));
}
} else {
if (tagName == "*") {
temp.remove(QRegExp("(\\[/\\*\\])?(<br/>)?$"));
}
return temp.replace(tagIter->second.first, tagIter->second.second);
}
} else {
// expression doesn't match. either the input string is invalid
// or the expression is
@@ -96,9 +133,9 @@ private:
m_TagMap["size="] = std::make_pair(QRegExp("\\[size=([^\\]]*)\\](.*)\\[/size\\]"),
"<font size=\"\\1\">\\2</font>");
m_TagMap["color="] = std::make_pair(QRegExp("\\[color=([^\\]]*)\\](.*)\\[/color\\]"),
"<font style=\"color: #\\1;\">\\2</font>");
"");
m_TagMap["font="] = std::make_pair(QRegExp("\\[font=([^\\]]*)\\](.*)\\[/font\\]"),
"<font face=\\1>\\2</font>");
"<font style=\"font-family: \\1;\">\\2</font>");
m_TagMap["center"] = std::make_pair(QRegExp("\\[center\\](.*)\\[/center\\]"),
"<div align=\"center\">\\1</div>");
m_TagMap["quote"] = std::make_pair(QRegExp("\\[quote\\](.*)\\[/quote\\]"),
@@ -109,6 +146,8 @@ private:
"<pre>\\1</pre>");
m_TagMap["heading"]= std::make_pair(QRegExp("\\[heading\\](.*)\\[/heading\\]"),
"<h2><strong>\\1</strong></h2>");
m_TagMap["line"] = std::make_pair(QRegExp("\\[line\\]"),
"<hr>");
// lists
m_TagMap["list"] = std::make_pair(QRegExp("\\[list\\](.*)\\[/list\\]"),
@@ -121,8 +160,6 @@ private:
"<ol>\\1</ol>");
m_TagMap["li"] = std::make_pair(QRegExp("\\[li\\](.*)\\[/li\\]"),
"<li>\\1</li>");
m_TagMap["*"] = std::make_pair(QRegExp("\\[\\*\\](.*)<br/>"),
"<li>\\1</li>");
// tables
m_TagMap["table"] = std::make_pair(QRegExp("\\[table\\](.*)\\[/table\\]"),
@@ -139,26 +176,50 @@ private:
"<a href=\"\\1\">\\1</a>");
m_TagMap["url="] = std::make_pair(QRegExp("\\[url=([^\\]]*)\\](.*)\\[/url\\]"),
"<a href=\"\\1\">\\2</a>");
m_TagMap["img"] = std::make_pair(QRegExp("\\[img\\](.*)\\[/img\\]"),
"<img src=\"\\1\"/>");
m_TagMap["img="] = std::make_pair(QRegExp("\\[img=([^\\]]*)\\](.*)\\[/img\\]"),
"<img src=\"\\2\" align=\"\\1\" />");
m_TagMap["img"] = std::make_pair(QRegExp("\\[img\\](.*)\\[/img\\]"),
"<img src=\"\\1\">");
m_TagMap["img="] = std::make_pair(QRegExp("\\[img=([^\\]]*)\\](.*)\\[/img\\]"),
"<img src=\"\\2\" alt=\"\\1\">");
m_TagMap["email="] = std::make_pair(QRegExp("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"),
"<a href=\"mailto:\\1\">\\2</a>");
m_TagMap["youtube"] = std::make_pair(QRegExp("\\[youtube\\](.*)\\[/youtube\\]"),
"<a href=\"http://www.youtube.com/v/\\1\">http://www.youtube.com/v/\\1</a>");
// make all patterns non-greedy and case-insensitive
for (TagMap::iterator iter = m_TagMap.begin(); iter != m_TagMap.end(); ++iter) {
iter->second.first.setCaseSensitivity(Qt::CaseInsensitive);
iter->second.first.setMinimal(true);
}
// this tag is in fact greedy
m_TagMap["*"] = std::make_pair(QRegExp("\\[\\*\\](.*)"),
"<li>\\1</li>");
m_ColorMap.insert(std::make_pair<QString, QString>("red", "FF0000"));
m_ColorMap.insert(std::make_pair<QString, QString>("green", "00FF00"));
m_ColorMap.insert(std::make_pair<QString, QString>("blue", "0000FF"));
m_ColorMap.insert(std::make_pair<QString, QString>("black", "000000"));
m_ColorMap.insert(std::make_pair<QString, QString>("gray", "7F7F7F"));
m_ColorMap.insert(std::make_pair<QString, QString>("white", "FFFFFF"));
m_ColorMap.insert(std::make_pair<QString, QString>("yellow", "FFFF00"));
m_ColorMap.insert(std::make_pair<QString, QString>("cyan", "00FFFF"));
m_ColorMap.insert(std::make_pair<QString, QString>("magenta", "FF00FF"));
m_ColorMap.insert(std::make_pair<QString, QString>("brown", "A52A2A"));
m_ColorMap.insert(std::make_pair<QString, QString>("orange", "FFA500"));
m_ColorMap.insert(std::make_pair<QString, QString>("gold", "FFD700"));
m_ColorMap.insert(std::make_pair<QString, QString>("deepskyblue", "00BFFF"));
m_ColorMap.insert(std::make_pair<QString, QString>("salmon", "FA8072"));
m_ColorMap.insert(std::make_pair<QString, QString>("dodgerblue", "1E90FF"));
m_ColorMap.insert(std::make_pair<QString, QString>("greenyellow", "ADFF2F"));
m_ColorMap.insert(std::make_pair<QString, QString>("peru", "CD853F"));
}
private:
QRegExp m_TagNameExp;
TagMap m_TagMap;
std::map<QString, QString> m_ColorMap;
};
@@ -174,7 +235,6 @@ QString convertToHTML(const QString &inputParam)
QString input = inputParam.mid(0).replace("\r\n", "<br/>");
input.replace("\\\"", "\"").replace("\\'", "'");
QString result;
int lastBlock = 0;
int pos = 0;
@@ -184,18 +244,23 @@ QString convertToHTML(const QString &inputParam)
// append everything between the previous tag-block and the current one
result.append(input.midRef(lastBlock, pos - lastBlock));
// convert the tag and content if necessary
int length = -1;
QString replacement = BBCodeMap::instance().convertTag(input.mid(pos), length);
if (length != 0) {
QString temp = convertToHTML(replacement);
result.append(temp);
// length contains the number of characters in the original tag
pos += length;
if ((pos < (input.size() - 1)) && (input.at(pos + 1) == '/')) {
// skip invalid end tag
int tagEnd = input.indexOf(']', pos) + 1;
pos = tagEnd;
} else {
// nothing replaced
result.append('[');
++pos;
// convert the tag and content if necessary
int length = -1;
QString replacement = BBCodeMap::instance().convertTag(input.mid(pos), length);
if (length != 0) {
result.append(convertToHTML(replacement));
// length contains the number of characters in the original tag
pos += length;
} else {
// nothing replaced
result.append('[');
++pos;
}
}
lastBlock = pos;
}
+19 -19
View File
@@ -1,22 +1,22 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BBCODE_H
#define BBCODE_H
+296
View File
@@ -0,0 +1,296 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "browserdialog.h"
#include "ui_browserdialog.h"
#include "messagedialog.h"
#include "report.h"
#include "persistentcookiejar.h"
#include <gameinfo.h>
#include "json.h"
#include <utility.h>
#include <gameinfo.h>
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QMenu>
#include <QInputDialog>
#include <QWebHistory>
#include <QDir>
#include <QWebFrame>
#include <QDesktopWidget>
#include <QKeyEvent>
BrowserDialog::BrowserDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::BrowserDialog)
, m_AccessManager(new QNetworkAccessManager(this))
{
ui->setupUi(this);
m_AccessManager->setCookieJar(new PersistentCookieJar(
QDir::fromNativeSeparators(MOBase::ToQString(MOShared::GameInfo::instance().getCacheDir())) + "/cookies.dat", this));
Qt::WindowFlags flags = windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint;
Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
flags = flags & (~helpFlag);
setWindowFlags(flags);
m_Tabs = this->findChild<QTabWidget*>("browserTabWidget");
installEventFilter(this);
connect(m_Tabs, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int)));
ui->urlEdit->setVisible(false);
}
BrowserDialog::~BrowserDialog()
{
delete ui;
}
void BrowserDialog::closeEvent(QCloseEvent *event)
{
// m_AccessManager->showCookies();
QDialog::closeEvent(event);
}
void BrowserDialog::initTab(BrowserView *newView)
{
newView->page()->setNetworkAccessManager(m_AccessManager);
newView->page()->setForwardUnsupportedContent(true);
connect(newView, SIGNAL(loadProgress(int)), this, SLOT(progress(int)));
connect(newView, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged(QString)));
connect(newView, SIGNAL(initTab(BrowserView*)), this, SLOT(initTab(BrowserView*)));
connect(newView, SIGNAL(startFind()), this, SLOT(startSearch()));
connect(newView, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl)));
connect(newView, SIGNAL(openUrlInNewTab(QUrl)), this, SLOT(openInNewTab(QUrl)));
connect(newView->page(), SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest)));
connect(newView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedContent(QNetworkReply*)));
ui->backBtn->setEnabled(false);
ui->fwdBtn->setEnabled(false);
m_Tabs->addTab(newView, tr("new"));
newView->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
newView->settings()->setAttribute(QWebSettings::AutoLoadImages, true);
}
void BrowserDialog::openInNewTab(const QUrl &url)
{
BrowserView *newView = new BrowserView(this);
initTab(newView);
newView->setUrl(url);
}
BrowserView *BrowserDialog::getCurrentView()
{
return qobject_cast<BrowserView*>(m_Tabs->currentWidget());
}
void BrowserDialog::urlChanged(const QUrl &url)
{
BrowserView *currentView = getCurrentView();
if (currentView != NULL) {
ui->backBtn->setEnabled(currentView->history()->canGoBack());
ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
}
ui->urlEdit->setText(url.toString());
}
void BrowserDialog::openUrl(const QUrl &url)
{
if (isHidden()) {
show();
}
openInNewTab(url);
}
void BrowserDialog::maximizeWidth()
{
int viewportWidth = getCurrentView()->page()->viewportSize().width();
int frameWidth = width() - viewportWidth;
int contentWidth = getCurrentView()->page()->mainFrame()->contentsSize().width();
QDesktopWidget screen;
int currentScreen = screen.screenNumber(this);
int screenWidth = screen.screenGeometry(currentScreen).size().width();
int targetWidth = std::min<int>(std::max<int>(viewportWidth, contentWidth) + frameWidth, screenWidth);
this->resize(targetWidth, height());
}
void BrowserDialog::progress(int value)
{
ui->loadProgress->setValue(value);
if (value == 100) {
maximizeWidth();
ui->loadProgress->setVisible(false);
} else {
ui->loadProgress->setVisible(true);
}
}
void BrowserDialog::titleChanged(const QString &title)
{
BrowserView *view = qobject_cast<BrowserView*>(sender());
for (int i = 0; i < m_Tabs->count(); ++i) {
if (m_Tabs->widget(i) == view) {
m_Tabs->setTabText(i, title.mid(0, 15));
m_Tabs->setTabToolTip(i, title);
}
}
}
QString BrowserDialog::guessFileName(const QString &url)
{
QRegExp uploadsExp(QString("http://.+/uploads/([^/]+)$"));
if (uploadsExp.indexIn(url) != -1) {
// these seem to be premium downloads
return uploadsExp.cap(1);
}
QRegExp filesExp(QString("http://.+\\?file=([^&]+)"));
if (filesExp.indexIn(url) != -1) {
// a regular manual download?
return filesExp.cap(1);
}
return "unknown";
}
void BrowserDialog::unsupportedContent(QNetworkReply *reply)
{
try {
QWebPage *page = qobject_cast<QWebPage*>(sender());
if (page == NULL) {
qCritical("sender not a page");
return;
}
BrowserView *view = qobject_cast<BrowserView*>(page->view());
if (view == NULL) {
qCritical("no view?");
return;
}
qDebug("unsupported: %s - %s", view->url().toString().toUtf8().constData(), reply->url().toString().toUtf8().constData());
emit requestDownload(view->url(), reply);
} catch (const std::exception &e) {
if (isVisible()) {
MessageDialog::showMessage(tr("failed to start download"), this);
}
qCritical("exception downloading unsupported content: %s", e.what());
}
}
void BrowserDialog::downloadRequested(const QNetworkRequest &request)
{
qCritical("download request %s ignored", request.url().toString().toUtf8().constData());
}
void BrowserDialog::tabCloseRequested(int index)
{
if (m_Tabs->count() == 1) {
this->close();
} else {
m_Tabs->widget(index)->deleteLater();
m_Tabs->removeTab(index);
}
}
void BrowserDialog::on_backBtn_clicked()
{
BrowserView *currentView = getCurrentView();
if (currentView != NULL) {
currentView->back();
}
}
void BrowserDialog::on_fwdBtn_clicked()
{
BrowserView *currentView = getCurrentView();
if (currentView != NULL) {
currentView->forward();
}
}
void BrowserDialog::startSearch()
{
ui->searchEdit->setFocus();
}
void BrowserDialog::on_searchEdit_returnPressed()
{
BrowserView *currentView = getCurrentView();
if (currentView != NULL) {
currentView->findText(ui->searchEdit->text(), QWebPage::FindWrapsAroundDocument);
}
}
void BrowserDialog::on_refreshBtn_clicked()
{
getCurrentView()->reload();
}
void BrowserDialog::on_browserTabWidget_currentChanged(int index)
{
BrowserView *currentView = qobject_cast<BrowserView*>(ui->browserTabWidget->widget(index));
if (currentView != NULL) {
ui->backBtn->setEnabled(currentView->history()->canGoBack());
ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
}
}
void BrowserDialog::on_urlEdit_returnPressed()
{
QWebView *currentView = getCurrentView();
if (currentView != NULL) {
currentView->setUrl(QUrl(ui->urlEdit->text()));
}
}
bool BrowserDialog::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = reinterpret_cast<QKeyEvent*>(event);
if ((keyEvent->modifiers() & Qt::ControlModifier)
&& (keyEvent->key() == Qt::Key_U)) {
ui->urlEdit->setVisible(!ui->urlEdit->isVisible());
return true;
}
}
return QDialog::eventFilter(object, event);
}
+128 -161
View File
@@ -1,161 +1,128 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NEXUSDIALOG_H
#define NEXUSDIALOG_H
#include "nexusview.h"
#include "nxmaccessmanager.h"
#include "tutorialcontrol.h"
#include <QDialog>
#include <QProgressBar>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTimer>
#include <QWebView>
#include <QQueue>
#include <QTabWidget>
#include <QAtomicInt>
namespace Ui {
class NexusDialog;
}
/**
* @brief a dialog containing a webbrowser that is intended to browse the nexus network
**/
class NexusDialog : public QDialog
{
Q_OBJECT
public:
/**
* @brief constructor
*
* @param accessManager the access manager to use for network requests
* @param parent parent widget
**/
explicit NexusDialog(NXMAccessManager *accessManager, QWidget *parent = 0);
~NexusDialog();
/**
* @brief set the url to open. If automatic login is enabled, the url is opened after login
*
* @param url the url to open
**/
void openUrl(const QString &url);
/**
* @brief log-in to the nexus page.
*
* After successful login, loadNexus() is automatically called. If the user is already
* logged in, this happens immediately
*
* @param username the user name to log in as
* @param password the user password
**/
void login(const QString &username, const QString &password);
/**
* @brief load the page set with openUrl()
**/
void loadNexus();
signals:
/**
* @brief emitted when the user caused a download
*
* @param reply the network-reply transmitting the file
* @param modID mod id of the file requested
* @param fileName suggested filename
**/
void requestDownload(QNetworkReply *reply, int modID, const QString &fileName);
void loginSuccessful(bool necessary);
protected:
virtual void closeEvent(QCloseEvent *);
private slots:
void loginFailed(const QString &message);
void loginFinished(bool necessary);
// void loginError(QNetworkReply::NetworkError errorCode);
// void loginTimeout();
void initTab(NexusView *newView);
void openInNewTab(const QUrl &url);
void progress(int value);
void titleChanged(const QString &title);
void requestNXMDownload(const QString &url);
void unsupportedContent(QNetworkReply *reply);
void downloadRequested(const QNetworkRequest &request);
void tabCloseRequested(int index);
// void openByModID();
void on_browserTabWidget_customContextMenuRequested(const QPoint &pos);
void urlChanged(const QUrl &url);
void on_backBtn_clicked();
void on_fwdBtn_clicked();
void on_modIDEdit_returnPressed();
void on_searchEdit_returnPressed();
void startSearch();
void on_browserTabWidget_currentChanged(QWidget *arg1);
void on_refreshBtn_clicked();
private:
QString guessFileName(const QString &url);
NexusView *getCurrentView();
private:
Ui::NexusDialog *ui;
MOBase::TutorialControl m_Tutorial;
QString m_Url;
QRegExp m_ModUrlExp;
QTabWidget *m_Tabs;
NexusView *m_View;
QProgressBar *m_LoadProgress;
NXMAccessManager *m_AccessManager;
};
#endif // NEXUSDIALOG_H
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BROWSERDIALOG_H
#define BROWSERDIALOG_H
#include "browserview.h"
#include "tutorialcontrol.h"
#include <QDialog>
#include <QProgressBar>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTimer>
#include <QWebView>
#include <QQueue>
#include <QTabWidget>
#include <QAtomicInt>
namespace Ui {
class BrowserDialog;
}
/**
* @brief a dialog containing a webbrowser that is intended to browse the nexus network
**/
class BrowserDialog : public QDialog
{
Q_OBJECT
public:
/**
* @brief constructor
*
* @param accessManager the access manager to use for network requests
* @param parent parent widget
**/
explicit BrowserDialog(QWidget *parent = 0);
~BrowserDialog();
/**
* @brief set the url to open. If automatic login is enabled, the url is opened after login
*
* @param url the url to open
**/
void openUrl(const QUrl &url);
virtual bool eventFilter(QObject *object, QEvent *event);
signals:
/**
* @brief emitted when the user starts a download
* @param pageUrl url of the current web site from which the download was started
* @param reply network reply of the started download
*/
void requestDownload(const QUrl &pageUrl, QNetworkReply *reply);
protected:
virtual void closeEvent(QCloseEvent *);
private slots:
void initTab(BrowserView *newView);
void openInNewTab(const QUrl &url);
void progress(int value);
void titleChanged(const QString &title);
void unsupportedContent(QNetworkReply *reply);
void downloadRequested(const QNetworkRequest &request);
void tabCloseRequested(int index);
void urlChanged(const QUrl &url);
void on_backBtn_clicked();
void on_fwdBtn_clicked();
void on_searchEdit_returnPressed();
void startSearch();
void on_refreshBtn_clicked();
void on_browserTabWidget_currentChanged(int index);
void on_urlEdit_returnPressed();
private:
QString guessFileName(const QString &url);
BrowserView *getCurrentView();
void maximizeWidth();
private:
Ui::BrowserDialog *ui;
QNetworkAccessManager *m_AccessManager;
QTabWidget *m_Tabs;
};
#endif // BROWSERDIALOG_H
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NexusDialog</class>
<widget class="QDialog" name="NexusDialog">
<class>BrowserDialog</class>
<widget class="QDialog" name="BrowserDialog">
<property name="geometry">
<rect>
<x>0</x>
@@ -11,13 +11,22 @@
</rect>
</property>
<property name="windowTitle">
<string>Nexus</string>
<string>Some Page</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -180,7 +189,16 @@
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -237,6 +255,13 @@
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="urlEdit">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -250,23 +275,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Mod ID</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="modIDEdit">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
+75 -122
View File
@@ -1,122 +1,75 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "nexusview.h"
#include <QEvent>
#include <QKeyEvent>
#include <QWebFrame>
#include <QWebElement>
#include <QNetworkDiskCache>
#include <QMenu>
#include <Shlwapi.h>
#include "utility.h"
using namespace MOBase;
NexusView::NexusView(QWidget *parent)
: QWebView(parent), m_LastSeenModID(0)
{
installEventFilter(this);
// this->pageAction(QWebPage::OpenLinkInNewWindow)
connect(this, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl)));
page()->settings()->setMaximumPagesInCache(10);
}
void NexusView::urlChanged(const QUrl &url)
{
QRegExp modidExp(QString("http://([a-zA-Z0-9]*).nexusmods.com/downloads/file.php\\?id=(\\d+)"), Qt::CaseInsensitive);
if (modidExp.indexIn(url.toString()) != -1) {
m_LastSeenModID = modidExp.cap(2).toInt();
}
}
void NexusView::openPageExternal()
{
::ShellExecuteW(NULL, L"open", ToWString(url().toString()).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
void NexusView::openLinkExternal()
{
::ShellExecuteW(NULL, L"open", ToWString(m_ContextURL.toString()).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
QWebView *NexusView::createWindow(QWebPage::WebWindowType)
{
NexusView *newView = new NexusView(parentWidget());
emit initTab(newView);
return newView;
}
bool NexusView::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->matches(QKeySequence::Find)) {
emit startFind();
} else if (keyEvent->matches(QKeySequence::FindNext)) {
emit findAgain();
}
} else if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::MidButton) {
mouseEvent->ignore();
return true;
}
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::MidButton) {
QWebHitTestResult hitTest = page()->frameAt(mouseEvent->pos())->hitTestContent(mouseEvent->pos());
if (hitTest.linkUrl().isValid()) {
emit openUrlInNewTab(hitTest.linkUrl());
}
mouseEvent->ignore();
return true;
}
}
return QWebView::eventFilter(obj, event);
}
void NexusView::contextMenuEvent(QContextMenuEvent *event)
{
if (!page()->swallowContextMenuEvent(event)) {
QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos());
QMenu *menu = page()->createStandardContextMenu();
QAction *openExternalAction = new QAction("Open in external browser", menu);
if (r.linkUrl().isEmpty()) {
connect(openExternalAction, SIGNAL(triggered()), this, SLOT(openPageExternal()));
} else {
m_ContextURL = r.linkUrl();
connect(openExternalAction, SIGNAL(triggered()), this, SLOT(openLinkExternal()));
}
menu->addSeparator();
menu->addAction(openExternalAction);
menu->exec(mapToGlobal(event->pos()));
}
}
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "browserview.h"
#include <QEvent>
#include <QKeyEvent>
#include <QWebFrame>
#include <QWebElement>
#include <QNetworkDiskCache>
#include <QMenu>
#include <Shlwapi.h>
#include "utility.h"
BrowserView::BrowserView(QWidget *parent)
: QWebView(parent)
{
installEventFilter(this);
page()->settings()->setMaximumPagesInCache(10);
}
QWebView *BrowserView::createWindow(QWebPage::WebWindowType)
{
BrowserView *newView = new BrowserView(parentWidget());
emit initTab(newView);
return newView;
}
bool BrowserView::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->matches(QKeySequence::Find)) {
emit startFind();
} else if (keyEvent->matches(QKeySequence::FindNext)) {
emit findAgain();
}
} else if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::MidButton) {
mouseEvent->ignore();
return true;
}
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::MidButton) {
QWebHitTestResult hitTest = page()->frameAt(mouseEvent->pos())->hitTestContent(mouseEvent->pos());
if (hitTest.linkUrl().isValid()) {
emit openUrlInNewTab(hitTest.linkUrl());
}
mouseEvent->ignore();
return true;
}
}
return QWebView::eventFilter(obj, event);
}
+80 -95
View File
@@ -1,95 +1,80 @@
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NEXUSVIEW_H
#define NEXUSVIEW_H
#include "finddialog.h"
#include <QWebView>
#include <QWebPage>
#include <QTabWidget>
/**
* @brief web view used to display a nexus page
**/
class NexusView : public QWebView
{
Q_OBJECT
public:
explicit NexusView(QWidget *parent = 0);
/**
* @return last mod id seen in the url
*/
int getLastSeenModID() const { return m_LastSeenModID; }
signals:
/**
* @brief emitted when the user opens a new window to be displayed in another tab
*
* @param newView the view for the newly opened window
**/
void initTab(NexusView *newView);
/**
* @brief emitted when the user requests a link to be opened in a new tab by middle-clicking
*
* @param url the url to open
*/
void openUrlInNewTab(const QUrl &url);
/**
* @brief Ctrl-f was clicked. The containing dialog should activate its find-facility
*/
void startFind();
/**
* @brief F3 was pressed. The containing dialog should search again
*/
void findAgain();
protected:
virtual QWebView *createWindow(QWebPage::WebWindowType type);
virtual bool eventFilter(QObject *obj, QEvent *event);
virtual void contextMenuEvent(QContextMenuEvent *event);
private slots:
void urlChanged(const QUrl &url);
void openPageExternal();
void openLinkExternal();
private:
QString m_FindPattern;
bool m_MiddleClick;
int m_LastSeenModID;
QUrl m_ContextURL;
};
#endif // NEXUSVIEW_H
/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NEXUSVIEW_H
#define NEXUSVIEW_H
#include "finddialog.h"
#include <QWebView>
#include <QWebPage>
#include <QTabWidget>
/**
* @brief web view used to display a nexus page
**/
class BrowserView : public QWebView
{
Q_OBJECT
public:
explicit BrowserView(QWidget *parent = 0);
signals:
/**
* @brief emitted when the user opens a new window to be displayed in another tab
*
* @param newView the view for the newly opened window
**/
void initTab(BrowserView *newView);
/**
* @brief emitted when the user requests a link to be opened in a new tab by middle-clicking
*
* @param url the url to open
*/
void openUrlInNewTab(const QUrl &url);
/**
* @brief Ctrl-f was clicked. The containing dialog should activate its find-facility
*/
void startFind();
/**
* @brief F3 was pressed. The containing dialog should search again
*/
void findAgain();
protected:
virtual QWebView *createWindow(QWebPage::WebWindowType type);
virtual bool eventFilter(QObject *obj, QEvent *event);
private:
QString m_FindPattern;
bool m_MiddleClick;
};
#endif // NEXUSVIEW_H
+319 -274
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More