mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
86
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25348238b2 | ||
|
|
8b3a42bd17 | ||
|
|
6f1162c23f | ||
|
|
2b21463514 | ||
|
|
d20a26e0eb | ||
|
|
459816ab71 | ||
|
|
9b5c238938 | ||
|
|
e7b6a7cbdd | ||
|
|
ab925e1e7c | ||
|
|
7bfb48d6ab | ||
|
|
88817c7f3b | ||
|
|
ee0041ba18 | ||
|
|
306ba78b0f | ||
|
|
e33406b4b5 | ||
|
|
a5906f1044 | ||
|
|
ebfeb2fbf9 | ||
|
|
f666e3d835 | ||
|
|
003cb6dec5 | ||
|
|
7fb7207ac7 | ||
|
|
64eced4614 | ||
|
|
8634b97bea | ||
|
|
116a36b943 | ||
|
|
479fdb3dcd | ||
|
|
acf35da699 | ||
|
|
6eb05396e4 | ||
|
|
9fcf34fec7 | ||
|
|
6c1e63258c | ||
|
|
226993eece | ||
|
|
78da5fc37f | ||
|
|
ffef339e2b | ||
|
|
4fa700bb55 | ||
|
|
9907437d93 | ||
|
|
3b7a468f73 | ||
|
|
0b14949d0e | ||
|
|
2237d7c103 | ||
|
|
1eea3bd90e | ||
|
|
20db939501 | ||
|
|
bfa6c9ab1e | ||
|
|
7a7c464b18 | ||
|
|
a62ecc5bf1 | ||
|
|
5f1022917b | ||
|
|
b77dcb2206 | ||
|
|
430048d201 | ||
|
|
4c42a6fbf1 | ||
|
|
243b59c64c | ||
|
|
b0a4748da5 | ||
|
|
9daeb9479b | ||
|
|
07bae15d7c | ||
|
|
778160cf0d | ||
|
|
14106436ca | ||
|
|
4f509e365e | ||
|
|
4ebc8dc014 | ||
|
|
5d3c1f34f4 | ||
|
|
844ba99892 | ||
|
|
715623e790 | ||
|
|
9879aae575 | ||
|
|
cc9827cdda | ||
|
|
4e5a67fc06 | ||
|
|
67b0268e70 | ||
|
|
b1ac479fb6 | ||
|
|
80b10107d9 | ||
|
|
1707941f6e | ||
|
|
d0b75e8b25 | ||
|
|
4fc441b249 | ||
|
|
581d065d7a | ||
|
|
5d2b5202af | ||
|
|
8044ef4f1d | ||
|
|
3d98491ebc | ||
|
|
923654961b | ||
|
|
76c861ed12 | ||
|
|
31cab54861 | ||
|
|
2a16cc4262 | ||
|
|
af89733121 | ||
|
|
baf1240be7 | ||
|
|
6e4626852c | ||
|
|
e8f56d65d2 | ||
|
|
5e7c875b29 | ||
|
|
b2a7c7c223 | ||
|
|
7b4582c1b1 | ||
|
|
5d7b23acef | ||
|
|
3628ec930b | ||
|
|
e22aeca3ff | ||
|
|
cbd6b288eb | ||
|
|
484749e612 | ||
|
|
5b3cdaa83b | ||
|
|
6d3f88b330 |
@@ -18,5 +18,19 @@ 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/.*
|
||||
|
||||
+22
-8
@@ -10,7 +10,7 @@ Please note that if you only want to work on and build a plugin you can save you
|
||||
Overview:
|
||||
---------
|
||||
|
||||
As of December 2013 MO consists of the following subprojects:
|
||||
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
|
||||
@@ -24,13 +24,14 @@ As of December 2013 MO consists of the following subprojects:
|
||||
- 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
|
||||
- installerBCF: no functionality. Supposed to eventually allow installations using bcfs (bain conversion file). python code
|
||||
- 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)
|
||||
@@ -39,7 +40,13 @@ And various plugins:
|
||||
- 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:
|
||||
-------------
|
||||
@@ -50,13 +57,20 @@ Visual C++ compiler 2010 (VC 10.0) or up
|
||||
Note: If you're having trouble installing the windows sdk, you may be affected by this bug: http://support.microsoft.com/kb/2717426
|
||||
|
||||
Qt Libraries 4.8.x (http://qt-project.org/downloads)
|
||||
- i.e. "Qt libraries 4.8.5 for Windows (VS 2010, 235 MB)"
|
||||
- tested: 4.8.5
|
||||
- Qt5 is not yet supported but WIP. You will see a few conditional qt5 pathes
|
||||
- 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/)
|
||||
- tested: 1.49
|
||||
- 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)
|
||||
@@ -105,8 +119,8 @@ Set up (using Qt Creator):
|
||||
2. Open the "Projects" tab, open the "Details" for "Build Environment"
|
||||
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 "7ZIPPATH" with the path of your zlib installation as the value (i.e. C:\code\7zip)
|
||||
3d. Click "Add" to add a variable called "PYTHONPATH" with the path of your zlib installation as the value (i.e. C:\code\python)
|
||||
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?>
|
||||
|
||||
+31
-7
@@ -1,6 +1,5 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
|
||||
SUBDIRS = bsatk \
|
||||
shared \
|
||||
uibase \
|
||||
@@ -13,15 +12,40 @@ SUBDIRS = bsatk \
|
||||
nxmhandler \
|
||||
BossDummy \
|
||||
pythonRunner \
|
||||
esptk \
|
||||
loot_cli
|
||||
esptk
|
||||
|
||||
plugins.depends = pythonRunner
|
||||
pythonRunner.depends = uibase
|
||||
plugins.depends = pythonRunner uibase
|
||||
hookdll.depends = shared
|
||||
organizer.depends = shared uibase plugins loot_cli
|
||||
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
|
||||
|
||||
@@ -35,6 +35,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent)
|
||||
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);
|
||||
@@ -46,6 +47,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent)
|
||||
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
|
||||
|
||||
+2
-1
@@ -48,7 +48,8 @@ private:
|
||||
LICENSE_BSD3,
|
||||
LICENSE_BOOST,
|
||||
LICENSE_CCBY3,
|
||||
LICENSE_ZLIB
|
||||
LICENSE_ZLIB,
|
||||
LICENSE_APACHE2
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -178,6 +178,11 @@
|
||||
<string notr="true">tokcdk (Russian)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ren (Korean)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -214,6 +219,16 @@
|
||||
<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>
|
||||
|
||||
+97
-97
@@ -1,97 +1,97 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
|
||||
ActivateModsDialog::ActivateModsDialog(const std::map<QString, std::vector<QString> > &missingPlugins, QWidget *parent)
|
||||
: TutorableDialog("ActivateMods", parent), ui(new Ui::ActivateModsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
|
||||
QHeaderView *headerView = modsTable->horizontalHeader();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
headerView->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
headerView->setSectionResizeMode(1, QHeaderView::Interactive);
|
||||
#else
|
||||
headerView->setResizeMode(0, QHeaderView::Stretch);
|
||||
headerView->setResizeMode(1, QHeaderView::Interactive);
|
||||
#endif
|
||||
|
||||
int row = 0;
|
||||
|
||||
modsTable->setRowCount(missingPlugins.size());
|
||||
|
||||
for (std::map<QString, std::vector<QString> >::const_iterator espIter = missingPlugins.begin();
|
||||
espIter != missingPlugins.end(); ++espIter, ++row) {
|
||||
modsTable->setCellWidget(row, 0, new QLabel(espIter->first));
|
||||
if (espIter->second.size() == 0) {
|
||||
modsTable->setCellWidget(row, 1, new QLabel(tr("not found")));
|
||||
} else {
|
||||
QComboBox* combo = new QComboBox();
|
||||
for (std::vector<QString>::const_iterator modIter = espIter->second.begin();
|
||||
modIter != espIter->second.end(); ++modIter) {
|
||||
combo->addItem(*modIter);
|
||||
}
|
||||
modsTable->setCellWidget(row, 1, combo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ActivateModsDialog::~ActivateModsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
std::set<QString> ActivateModsDialog::getModsToActivate()
|
||||
{
|
||||
std::set<QString> result;
|
||||
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
|
||||
|
||||
for (int row = 0; row < modsTable->rowCount(); ++row) {
|
||||
QComboBox *comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
|
||||
if (comboBox != NULL) {
|
||||
result.insert(comboBox->currentText());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::set<QString> ActivateModsDialog::getESPsToActivate()
|
||||
{
|
||||
std::set<QString> result;
|
||||
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
|
||||
|
||||
for (int row = 0; row < modsTable->rowCount(); ++row) {
|
||||
QComboBox *comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
|
||||
if (comboBox != NULL) {
|
||||
QLabel *espName = dynamic_cast<QLabel*>(modsTable->cellWidget(row, 0));
|
||||
|
||||
result.insert(espName->text());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
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"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
|
||||
ActivateModsDialog::ActivateModsDialog(const std::map<QString, std::vector<QString> > &missingPlugins, QWidget *parent)
|
||||
: TutorableDialog("ActivateMods", parent), ui(new Ui::ActivateModsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
|
||||
QHeaderView *headerView = modsTable->horizontalHeader();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
headerView->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
headerView->setSectionResizeMode(1, QHeaderView::Interactive);
|
||||
#else
|
||||
headerView->setResizeMode(0, QHeaderView::Stretch);
|
||||
headerView->setResizeMode(1, QHeaderView::Interactive);
|
||||
#endif
|
||||
|
||||
int row = 0;
|
||||
|
||||
modsTable->setRowCount(missingPlugins.size());
|
||||
|
||||
for (std::map<QString, std::vector<QString> >::const_iterator espIter = missingPlugins.begin();
|
||||
espIter != missingPlugins.end(); ++espIter, ++row) {
|
||||
modsTable->setCellWidget(row, 0, new QLabel(espIter->first));
|
||||
if (espIter->second.size() == 0) {
|
||||
modsTable->setCellWidget(row, 1, new QLabel(tr("not found")));
|
||||
} else {
|
||||
QComboBox* combo = new QComboBox();
|
||||
for (std::vector<QString>::const_iterator modIter = espIter->second.begin();
|
||||
modIter != espIter->second.end(); ++modIter) {
|
||||
combo->addItem(*modIter);
|
||||
}
|
||||
modsTable->setCellWidget(row, 1, combo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ActivateModsDialog::~ActivateModsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
std::set<QString> ActivateModsDialog::getModsToActivate()
|
||||
{
|
||||
std::set<QString> result;
|
||||
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
|
||||
|
||||
for (int row = 0; row < modsTable->rowCount(); ++row) {
|
||||
QComboBox *comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
|
||||
if (comboBox != NULL) {
|
||||
result.insert(comboBox->currentText());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::set<QString> ActivateModsDialog::getESPsToActivate()
|
||||
{
|
||||
std::set<QString> result;
|
||||
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
|
||||
|
||||
for (int row = 0; row < modsTable->rowCount(); ++row) {
|
||||
QComboBox *comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
|
||||
if (comboBox != NULL) {
|
||||
QLabel *espName = dynamic_cast<QLabel*>(modsTable->cellWidget(row, 0));
|
||||
|
||||
result.insert(espName->text());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+70
-70
@@ -1,70 +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:
|
||||
|
||||
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
|
||||
|
||||
+274
-234
File diff suppressed because it is too large
Load Diff
+40
-40
@@ -1,40 +1,40 @@
|
||||
/*
|
||||
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
|
||||
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
||||
namespace BBCode {
|
||||
|
||||
/**
|
||||
* @brief convert a string with BB Code-Tags to HTML
|
||||
* @param input the input string with BB tags
|
||||
* @param replaceOccured if not NULL, this parameter will be set to true if any bb tags were replaced
|
||||
* @return the same string in html representation
|
||||
**/
|
||||
QString convertToHTML(const QString &input);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // BBCODE_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 BBCODE_H
|
||||
#define BBCODE_H
|
||||
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
||||
namespace BBCode {
|
||||
|
||||
/**
|
||||
* @brief convert a string with BB Code-Tags to HTML
|
||||
* @param input the input string with BB tags
|
||||
* @param replaceOccured if not NULL, this parameter will be set to true if any bb tags were replaced
|
||||
* @return the same string in html representation
|
||||
**/
|
||||
QString convertToHTML(const QString &input);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // BBCODE_H
|
||||
|
||||
+296
-270
File diff suppressed because it is too large
Load Diff
+128
-124
@@ -1,124 +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 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);
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
|
||||
QString guessFileName(const QString &url);
|
||||
|
||||
BrowserView *getCurrentView();
|
||||
|
||||
void maximizeWidth();
|
||||
|
||||
private:
|
||||
|
||||
Ui::BrowserDialog *ui;
|
||||
|
||||
QNetworkAccessManager *m_AccessManager;
|
||||
|
||||
QTabWidget *m_Tabs;
|
||||
|
||||
};
|
||||
|
||||
#endif // BROWSERDIALOG_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
|
||||
|
||||
+27
-2
@@ -17,7 +17,16 @@
|
||||
<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">
|
||||
|
||||
+75
-76
@@ -1,76 +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 "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);
|
||||
}
|
||||
/*
|
||||
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
-80
@@ -1,80 +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 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
|
||||
/*
|
||||
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
-301
File diff suppressed because it is too large
Load Diff
+200
-198
@@ -1,198 +1,200 @@
|
||||
/*
|
||||
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 CATEGORIES_H
|
||||
#define CATEGORIES_H
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Manage the available mod categories
|
||||
* @warning member functions of this class currently use a wild mix of ids and indexes to look up categories,
|
||||
* optimized to where the request comes from. Therefore be very careful which of the two you have available
|
||||
**/
|
||||
class CategoryFactory {
|
||||
|
||||
friend class CategoriesDialog;
|
||||
|
||||
public:
|
||||
|
||||
static const int CATEGORY_NONE = 0;
|
||||
|
||||
static const int CATEGORY_SPECIAL_FIRST = 10000;
|
||||
static const int CATEGORY_SPECIAL_CHECKED = CATEGORY_SPECIAL_FIRST;
|
||||
static const int CATEGORY_SPECIAL_UNCHECKED = 10001;
|
||||
static const int CATEGORY_SPECIAL_UPDATEAVAILABLE = 10002;
|
||||
static const int CATEGORY_SPECIAL_NOCATEGORY = 10003;
|
||||
static const int CATEGORY_SPECIAL_CONFLICT = 10004;
|
||||
static const int CATEGORY_SPECIAL_NOTENDORSED = 10005;
|
||||
|
||||
public:
|
||||
|
||||
struct Category {
|
||||
Category(int sortValue, int id, const QString &name, const std::vector<int> &nexusIDs, int parentID)
|
||||
: m_SortValue(sortValue), m_ID(id), m_Name(name), m_HasChildren(false),
|
||||
m_NexusIDs(nexusIDs), m_ParentID(parentID) {}
|
||||
int m_SortValue;
|
||||
int m_ID;
|
||||
int m_ParentID;
|
||||
bool m_HasChildren;
|
||||
QString m_Name;
|
||||
std::vector<int> m_NexusIDs;
|
||||
|
||||
friend bool operator<(const Category &LHS, const Category &RHS) {
|
||||
return LHS.m_SortValue < RHS.m_SortValue;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief reset the list of categories
|
||||
**/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief save the categories to the categories.dat file
|
||||
**/
|
||||
void saveCategories();
|
||||
|
||||
/**
|
||||
* @brief retrieve the number of available categories
|
||||
*
|
||||
* @return unsigned int number of categories
|
||||
**/
|
||||
unsigned numCategories() const { return m_Categories.size(); }
|
||||
|
||||
/**
|
||||
* @brief count all categories that match a specified filter
|
||||
* @param filter the filter to test
|
||||
* @return number of matching categories
|
||||
*/
|
||||
unsigned int countCategories(std::tr1::function<bool (const Category &category)> filter);
|
||||
|
||||
/**
|
||||
* @brief get the id of the parent category
|
||||
*
|
||||
* @param index the index to look up
|
||||
* @return int id of the parent category
|
||||
**/
|
||||
int getParentID(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief determine if a category exists (by id)
|
||||
*
|
||||
* @param id the id to check for existance
|
||||
* @return true if the category exists, false otherwise
|
||||
**/
|
||||
bool categoryExists(int id) const;
|
||||
|
||||
/**
|
||||
* @brief test if a category is child of a second one
|
||||
* @param id the presumed child id
|
||||
* @param parentID the parent id to test for
|
||||
* @return true if id is a child of parentID
|
||||
**/
|
||||
bool isDecendantOf(int id, int parentID) const;
|
||||
|
||||
/**
|
||||
* @brief test if the specified category has child categories
|
||||
*
|
||||
* @param index index of the category to look up
|
||||
* @return bool true if the category has child categories
|
||||
**/
|
||||
bool hasChildren(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief retrieve the name of a category
|
||||
*
|
||||
* @param index index of the category to look up
|
||||
* @return QString name of the category
|
||||
**/
|
||||
QString getCategoryName(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief look up the id of a category by its index
|
||||
*
|
||||
* @param index index of the category to look up
|
||||
* @return int id of the category
|
||||
**/
|
||||
int getCategoryID(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief look up the index of a category by its id
|
||||
*
|
||||
* @param id index of the category to look up
|
||||
* @return unsigned int index of the category
|
||||
**/
|
||||
int getCategoryIndex(int ID) const;
|
||||
|
||||
/**
|
||||
* @brief retrieve the index of a category by its nexus id
|
||||
*
|
||||
* @param nexusID nexus id of the category to look up
|
||||
* @return unsigned int index of the category or 0 if no category matches
|
||||
**/
|
||||
unsigned int resolveNexusID(int nexusID) const;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief retrieve a reference to the singleton instance
|
||||
*
|
||||
* @return the reference to the singleton
|
||||
**/
|
||||
static CategoryFactory &instance();
|
||||
|
||||
/**
|
||||
* @return path to the file that contains the categories list
|
||||
*/
|
||||
static QString categoriesFilePath();
|
||||
|
||||
private:
|
||||
|
||||
CategoryFactory();
|
||||
|
||||
void loadDefaultCategories();
|
||||
|
||||
void addCategory(int id, const QString &name, const std::vector<int> &nexusID, int parentID);
|
||||
|
||||
void setParents();
|
||||
|
||||
static void cleanup();
|
||||
|
||||
private:
|
||||
|
||||
static CategoryFactory *s_Instance;
|
||||
|
||||
std::vector<Category> m_Categories;
|
||||
std::map<int, unsigned int> m_IDMap;
|
||||
std::map<int, unsigned int> m_NexusMap;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // CATEGORIES_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 CATEGORIES_H
|
||||
#define CATEGORIES_H
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Manage the available mod categories
|
||||
* @warning member functions of this class currently use a wild mix of ids and indexes to look up categories,
|
||||
* optimized to where the request comes from. Therefore be very careful which of the two you have available
|
||||
**/
|
||||
class CategoryFactory {
|
||||
|
||||
friend class CategoriesDialog;
|
||||
|
||||
public:
|
||||
|
||||
static const int CATEGORY_NONE = 0;
|
||||
|
||||
static const int CATEGORY_SPECIAL_FIRST = 10000;
|
||||
static const int CATEGORY_SPECIAL_CHECKED = CATEGORY_SPECIAL_FIRST;
|
||||
static const int CATEGORY_SPECIAL_UNCHECKED = 10001;
|
||||
static const int CATEGORY_SPECIAL_UPDATEAVAILABLE = 10002;
|
||||
static const int CATEGORY_SPECIAL_NOCATEGORY = 10003;
|
||||
static const int CATEGORY_SPECIAL_CONFLICT = 10004;
|
||||
static const int CATEGORY_SPECIAL_NOTENDORSED = 10005;
|
||||
static const int CATEGORY_SPECIAL_MANAGED = 10006;
|
||||
static const int CATEGORY_SPECIAL_UNMANAGED = 10007;
|
||||
|
||||
public:
|
||||
|
||||
struct Category {
|
||||
Category(int sortValue, int id, const QString &name, const std::vector<int> &nexusIDs, int parentID)
|
||||
: m_SortValue(sortValue), m_ID(id), m_Name(name), m_HasChildren(false),
|
||||
m_NexusIDs(nexusIDs), m_ParentID(parentID) {}
|
||||
int m_SortValue;
|
||||
int m_ID;
|
||||
int m_ParentID;
|
||||
bool m_HasChildren;
|
||||
QString m_Name;
|
||||
std::vector<int> m_NexusIDs;
|
||||
|
||||
friend bool operator<(const Category &LHS, const Category &RHS) {
|
||||
return LHS.m_SortValue < RHS.m_SortValue;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief reset the list of categories
|
||||
**/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief save the categories to the categories.dat file
|
||||
**/
|
||||
void saveCategories();
|
||||
|
||||
/**
|
||||
* @brief retrieve the number of available categories
|
||||
*
|
||||
* @return unsigned int number of categories
|
||||
**/
|
||||
unsigned numCategories() const { return m_Categories.size(); }
|
||||
|
||||
/**
|
||||
* @brief count all categories that match a specified filter
|
||||
* @param filter the filter to test
|
||||
* @return number of matching categories
|
||||
*/
|
||||
unsigned int countCategories(std::tr1::function<bool (const Category &category)> filter);
|
||||
|
||||
/**
|
||||
* @brief get the id of the parent category
|
||||
*
|
||||
* @param index the index to look up
|
||||
* @return int id of the parent category
|
||||
**/
|
||||
int getParentID(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief determine if a category exists (by id)
|
||||
*
|
||||
* @param id the id to check for existance
|
||||
* @return true if the category exists, false otherwise
|
||||
**/
|
||||
bool categoryExists(int id) const;
|
||||
|
||||
/**
|
||||
* @brief test if a category is child of a second one
|
||||
* @param id the presumed child id
|
||||
* @param parentID the parent id to test for
|
||||
* @return true if id is a child of parentID
|
||||
**/
|
||||
bool isDecendantOf(int id, int parentID) const;
|
||||
|
||||
/**
|
||||
* @brief test if the specified category has child categories
|
||||
*
|
||||
* @param index index of the category to look up
|
||||
* @return bool true if the category has child categories
|
||||
**/
|
||||
bool hasChildren(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief retrieve the name of a category
|
||||
*
|
||||
* @param index index of the category to look up
|
||||
* @return QString name of the category
|
||||
**/
|
||||
QString getCategoryName(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief look up the id of a category by its index
|
||||
*
|
||||
* @param index index of the category to look up
|
||||
* @return int id of the category
|
||||
**/
|
||||
int getCategoryID(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief look up the index of a category by its id
|
||||
*
|
||||
* @param id index of the category to look up
|
||||
* @return unsigned int index of the category
|
||||
**/
|
||||
int getCategoryIndex(int ID) const;
|
||||
|
||||
/**
|
||||
* @brief retrieve the index of a category by its nexus id
|
||||
*
|
||||
* @param nexusID nexus id of the category to look up
|
||||
* @return unsigned int index of the category or 0 if no category matches
|
||||
**/
|
||||
unsigned int resolveNexusID(int nexusID) const;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief retrieve a reference to the singleton instance
|
||||
*
|
||||
* @return the reference to the singleton
|
||||
**/
|
||||
static CategoryFactory &instance();
|
||||
|
||||
/**
|
||||
* @return path to the file that contains the categories list
|
||||
*/
|
||||
static QString categoriesFilePath();
|
||||
|
||||
private:
|
||||
|
||||
CategoryFactory();
|
||||
|
||||
void loadDefaultCategories();
|
||||
|
||||
void addCategory(int id, const QString &name, const std::vector<int> &nexusID, int parentID);
|
||||
|
||||
void setParents();
|
||||
|
||||
static void cleanup();
|
||||
|
||||
private:
|
||||
|
||||
static CategoryFactory *s_Instance;
|
||||
|
||||
std::vector<Category> m_Categories;
|
||||
std::map<int, unsigned int> m_IDMap;
|
||||
std::map<int, unsigned int> m_NexusMap;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // CATEGORIES_H
|
||||
|
||||
+243
-243
@@ -1,243 +1,243 @@
|
||||
/*
|
||||
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 "categoriesdialog.h"
|
||||
#include "ui_categoriesdialog.h"
|
||||
#include "categories.h"
|
||||
#include "utility.h"
|
||||
#include <QItemDelegate>
|
||||
#include <QRegExpValidator>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
|
||||
|
||||
class NewIDValidator : public QIntValidator {
|
||||
public:
|
||||
NewIDValidator(const std::set<int> &ids)
|
||||
: m_UsedIDs(ids) {}
|
||||
virtual State validate(QString &input, int &pos) const {
|
||||
State intRes = QIntValidator::validate(input, pos);
|
||||
if (intRes == Acceptable) {
|
||||
bool ok = false;
|
||||
int id = input.toInt(&ok);
|
||||
if (m_UsedIDs.find(id) != m_UsedIDs.end()) {
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
}
|
||||
return intRes;
|
||||
}
|
||||
private:
|
||||
const std::set<int> &m_UsedIDs;
|
||||
};
|
||||
|
||||
|
||||
class ExistingIDValidator : public QIntValidator {
|
||||
public:
|
||||
ExistingIDValidator(const std::set<int> &ids)
|
||||
: m_UsedIDs(ids) {}
|
||||
virtual State validate(QString &input, int &pos) const {
|
||||
State intRes = QIntValidator::validate(input, pos);
|
||||
if (intRes == Acceptable) {
|
||||
bool ok = false;
|
||||
int id = input.toInt(&ok);
|
||||
if ((id == 0) || (m_UsedIDs.find(id) != m_UsedIDs.end())) {
|
||||
return QValidator::Acceptable;
|
||||
} else {
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
} else {
|
||||
return intRes;
|
||||
}
|
||||
}
|
||||
private:
|
||||
const std::set<int> &m_UsedIDs;
|
||||
};
|
||||
|
||||
|
||||
class ValidatingDelegate : public QItemDelegate {
|
||||
|
||||
public:
|
||||
ValidatingDelegate(QObject *parent, QValidator *validator)
|
||||
: QItemDelegate(parent), m_Validator(validator) {}
|
||||
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem&, const QModelIndex&) const
|
||||
{
|
||||
QLineEdit *edit = new QLineEdit(parent);
|
||||
edit->setValidator(m_Validator);
|
||||
return edit;
|
||||
}
|
||||
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
||||
int pos = 0;
|
||||
QString editText = edit->text();
|
||||
if (m_Validator->validate(editText, pos) == QValidator::Acceptable) {
|
||||
QItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
}
|
||||
private:
|
||||
QValidator *m_Validator;
|
||||
};
|
||||
|
||||
|
||||
CategoriesDialog::CategoriesDialog(QWidget *parent)
|
||||
: TutorableDialog("Categories", parent), ui(new Ui::CategoriesDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
fillTable();
|
||||
connect(ui->categoriesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int,int)));
|
||||
}
|
||||
|
||||
CategoriesDialog::~CategoriesDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::cellChanged(int row, int)
|
||||
{
|
||||
int currentID = ui->categoriesTable->item(row, 0)->text().toInt();
|
||||
if (currentID > m_HighestID) {
|
||||
m_HighestID = currentID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::commitChanges()
|
||||
{
|
||||
CategoryFactory &categories = CategoryFactory::instance();
|
||||
categories.reset();
|
||||
|
||||
for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
|
||||
int index = ui->categoriesTable->verticalHeader()->logicalIndex(i);
|
||||
QString nexusIDString = ui->categoriesTable->item(index, 2)->text();
|
||||
QStringList nexusIDStringList = nexusIDString.split(',', QString::SkipEmptyParts);
|
||||
std::vector<int> nexusIDs;
|
||||
for (QStringList::iterator iter = nexusIDStringList.begin();
|
||||
iter != nexusIDStringList.end(); ++iter) {
|
||||
nexusIDs.push_back(iter->toInt());
|
||||
}
|
||||
|
||||
categories.addCategory(
|
||||
ui->categoriesTable->item(index, 0)->text().toInt(),
|
||||
ui->categoriesTable->item(index, 1)->text(),
|
||||
nexusIDs,
|
||||
ui->categoriesTable->item(index, 3)->text().toInt());
|
||||
}
|
||||
categories.setParents();
|
||||
|
||||
categories.saveCategories();
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::refreshIDs()
|
||||
{
|
||||
m_HighestID = 0;
|
||||
for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
|
||||
int id = ui->categoriesTable->item(i, 0)->text().toInt();
|
||||
if (id > m_HighestID) {
|
||||
m_HighestID = id;
|
||||
}
|
||||
m_IDs.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::fillTable()
|
||||
{
|
||||
CategoryFactory &categories = CategoryFactory::instance();
|
||||
QTableWidget *table = ui->categoriesTable;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
table->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
|
||||
table->verticalHeader()->setSectionsMovable(true);
|
||||
table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
||||
#else
|
||||
table->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
|
||||
table->horizontalHeader()->setResizeMode(2, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setResizeMode(3, QHeaderView::Fixed);
|
||||
table->verticalHeader()->setMovable(true);
|
||||
table->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
||||
#endif
|
||||
|
||||
|
||||
table->setItemDelegateForColumn(0, new ValidatingDelegate(this, new NewIDValidator(m_IDs)));
|
||||
table->setItemDelegateForColumn(2, new ValidatingDelegate(this, new QRegExpValidator(QRegExp("([0-9]+)?(,[0-9]+)*"), this)));
|
||||
table->setItemDelegateForColumn(3, new ValidatingDelegate(this, new ExistingIDValidator(m_IDs)));
|
||||
|
||||
int row = 0;
|
||||
for (std::vector<CategoryFactory::Category>::const_iterator iter = categories.m_Categories.begin();
|
||||
iter != categories.m_Categories.end(); ++iter, ++row) {
|
||||
const CategoryFactory::Category &category = *iter;
|
||||
if (category.m_ID == 0) {
|
||||
--row;
|
||||
continue;
|
||||
}
|
||||
table->insertRow(row);
|
||||
// table->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
|
||||
|
||||
QScopedPointer<QTableWidgetItem> idItem(new QTableWidgetItem());
|
||||
idItem->setData(Qt::DisplayRole, category.m_ID);
|
||||
|
||||
QScopedPointer<QTableWidgetItem> nameItem(new QTableWidgetItem(category.m_Name));
|
||||
QScopedPointer<QTableWidgetItem> nexusIDItem(new QTableWidgetItem(MOBase::VectorJoin(category.m_NexusIDs, ",")));
|
||||
QScopedPointer<QTableWidgetItem> parentIDItem(new QTableWidgetItem());
|
||||
parentIDItem->setData(Qt::DisplayRole, category.m_ParentID);
|
||||
|
||||
table->setItem(row, 0, idItem.take());
|
||||
table->setItem(row, 1, nameItem.take());
|
||||
table->setItem(row, 2, nexusIDItem.take());
|
||||
table->setItem(row, 3, parentIDItem.take());
|
||||
}
|
||||
|
||||
refreshIDs();
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::addCategory_clicked()
|
||||
{
|
||||
int row = m_ContextRow >= 0 ? m_ContextRow : 0;
|
||||
ui->categoriesTable->insertRow(row);
|
||||
ui->categoriesTable->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
|
||||
ui->categoriesTable->setItem(row, 0, new QTableWidgetItem(QString::number(++m_HighestID)));
|
||||
ui->categoriesTable->setItem(row, 1, new QTableWidgetItem("new"));
|
||||
ui->categoriesTable->setItem(row, 2, new QTableWidgetItem(""));
|
||||
ui->categoriesTable->setItem(row, 3, new QTableWidgetItem("0"));
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::removeCategory_clicked()
|
||||
{
|
||||
ui->categoriesTable->removeRow(m_ContextRow);
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::on_categoriesTable_customContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
m_ContextRow = ui->categoriesTable->rowAt(pos.y());
|
||||
QMenu menu;
|
||||
menu.addAction(tr("Add"), this, SLOT(addCategory_clicked()));
|
||||
menu.addAction(tr("Remove"), this, SLOT(removeCategory_clicked()));
|
||||
|
||||
menu.exec(ui->categoriesTable->mapToGlobal(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 "categoriesdialog.h"
|
||||
#include "ui_categoriesdialog.h"
|
||||
#include "categories.h"
|
||||
#include "utility.h"
|
||||
#include <QItemDelegate>
|
||||
#include <QRegExpValidator>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
|
||||
|
||||
class NewIDValidator : public QIntValidator {
|
||||
public:
|
||||
NewIDValidator(const std::set<int> &ids)
|
||||
: m_UsedIDs(ids) {}
|
||||
virtual State validate(QString &input, int &pos) const {
|
||||
State intRes = QIntValidator::validate(input, pos);
|
||||
if (intRes == Acceptable) {
|
||||
bool ok = false;
|
||||
int id = input.toInt(&ok);
|
||||
if (m_UsedIDs.find(id) != m_UsedIDs.end()) {
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
}
|
||||
return intRes;
|
||||
}
|
||||
private:
|
||||
const std::set<int> &m_UsedIDs;
|
||||
};
|
||||
|
||||
|
||||
class ExistingIDValidator : public QIntValidator {
|
||||
public:
|
||||
ExistingIDValidator(const std::set<int> &ids)
|
||||
: m_UsedIDs(ids) {}
|
||||
virtual State validate(QString &input, int &pos) const {
|
||||
State intRes = QIntValidator::validate(input, pos);
|
||||
if (intRes == Acceptable) {
|
||||
bool ok = false;
|
||||
int id = input.toInt(&ok);
|
||||
if ((id == 0) || (m_UsedIDs.find(id) != m_UsedIDs.end())) {
|
||||
return QValidator::Acceptable;
|
||||
} else {
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
} else {
|
||||
return intRes;
|
||||
}
|
||||
}
|
||||
private:
|
||||
const std::set<int> &m_UsedIDs;
|
||||
};
|
||||
|
||||
|
||||
class ValidatingDelegate : public QItemDelegate {
|
||||
|
||||
public:
|
||||
ValidatingDelegate(QObject *parent, QValidator *validator)
|
||||
: QItemDelegate(parent), m_Validator(validator) {}
|
||||
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem&, const QModelIndex&) const
|
||||
{
|
||||
QLineEdit *edit = new QLineEdit(parent);
|
||||
edit->setValidator(m_Validator);
|
||||
return edit;
|
||||
}
|
||||
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
||||
int pos = 0;
|
||||
QString editText = edit->text();
|
||||
if (m_Validator->validate(editText, pos) == QValidator::Acceptable) {
|
||||
QItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
}
|
||||
private:
|
||||
QValidator *m_Validator;
|
||||
};
|
||||
|
||||
|
||||
CategoriesDialog::CategoriesDialog(QWidget *parent)
|
||||
: TutorableDialog("Categories", parent), ui(new Ui::CategoriesDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
fillTable();
|
||||
connect(ui->categoriesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int,int)));
|
||||
}
|
||||
|
||||
CategoriesDialog::~CategoriesDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::cellChanged(int row, int)
|
||||
{
|
||||
int currentID = ui->categoriesTable->item(row, 0)->text().toInt();
|
||||
if (currentID > m_HighestID) {
|
||||
m_HighestID = currentID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::commitChanges()
|
||||
{
|
||||
CategoryFactory &categories = CategoryFactory::instance();
|
||||
categories.reset();
|
||||
|
||||
for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
|
||||
int index = ui->categoriesTable->verticalHeader()->logicalIndex(i);
|
||||
QString nexusIDString = ui->categoriesTable->item(index, 2)->text();
|
||||
QStringList nexusIDStringList = nexusIDString.split(',', QString::SkipEmptyParts);
|
||||
std::vector<int> nexusIDs;
|
||||
for (QStringList::iterator iter = nexusIDStringList.begin();
|
||||
iter != nexusIDStringList.end(); ++iter) {
|
||||
nexusIDs.push_back(iter->toInt());
|
||||
}
|
||||
|
||||
categories.addCategory(
|
||||
ui->categoriesTable->item(index, 0)->text().toInt(),
|
||||
ui->categoriesTable->item(index, 1)->text(),
|
||||
nexusIDs,
|
||||
ui->categoriesTable->item(index, 3)->text().toInt());
|
||||
}
|
||||
categories.setParents();
|
||||
|
||||
categories.saveCategories();
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::refreshIDs()
|
||||
{
|
||||
m_HighestID = 0;
|
||||
for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
|
||||
int id = ui->categoriesTable->item(i, 0)->text().toInt();
|
||||
if (id > m_HighestID) {
|
||||
m_HighestID = id;
|
||||
}
|
||||
m_IDs.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::fillTable()
|
||||
{
|
||||
CategoryFactory &categories = CategoryFactory::instance();
|
||||
QTableWidget *table = ui->categoriesTable;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
table->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
|
||||
table->verticalHeader()->setSectionsMovable(true);
|
||||
table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
||||
#else
|
||||
table->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
|
||||
table->horizontalHeader()->setResizeMode(2, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setResizeMode(3, QHeaderView::Fixed);
|
||||
table->verticalHeader()->setMovable(true);
|
||||
table->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
||||
#endif
|
||||
|
||||
|
||||
table->setItemDelegateForColumn(0, new ValidatingDelegate(this, new NewIDValidator(m_IDs)));
|
||||
table->setItemDelegateForColumn(2, new ValidatingDelegate(this, new QRegExpValidator(QRegExp("([0-9]+)?(,[0-9]+)*"), this)));
|
||||
table->setItemDelegateForColumn(3, new ValidatingDelegate(this, new ExistingIDValidator(m_IDs)));
|
||||
|
||||
int row = 0;
|
||||
for (std::vector<CategoryFactory::Category>::const_iterator iter = categories.m_Categories.begin();
|
||||
iter != categories.m_Categories.end(); ++iter, ++row) {
|
||||
const CategoryFactory::Category &category = *iter;
|
||||
if (category.m_ID == 0) {
|
||||
--row;
|
||||
continue;
|
||||
}
|
||||
table->insertRow(row);
|
||||
// table->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
|
||||
|
||||
QScopedPointer<QTableWidgetItem> idItem(new QTableWidgetItem());
|
||||
idItem->setData(Qt::DisplayRole, category.m_ID);
|
||||
|
||||
QScopedPointer<QTableWidgetItem> nameItem(new QTableWidgetItem(category.m_Name));
|
||||
QScopedPointer<QTableWidgetItem> nexusIDItem(new QTableWidgetItem(MOBase::VectorJoin(category.m_NexusIDs, ",")));
|
||||
QScopedPointer<QTableWidgetItem> parentIDItem(new QTableWidgetItem());
|
||||
parentIDItem->setData(Qt::DisplayRole, category.m_ParentID);
|
||||
|
||||
table->setItem(row, 0, idItem.take());
|
||||
table->setItem(row, 1, nameItem.take());
|
||||
table->setItem(row, 2, nexusIDItem.take());
|
||||
table->setItem(row, 3, parentIDItem.take());
|
||||
}
|
||||
|
||||
refreshIDs();
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::addCategory_clicked()
|
||||
{
|
||||
int row = m_ContextRow >= 0 ? m_ContextRow : 0;
|
||||
ui->categoriesTable->insertRow(row);
|
||||
ui->categoriesTable->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
|
||||
ui->categoriesTable->setItem(row, 0, new QTableWidgetItem(QString::number(++m_HighestID)));
|
||||
ui->categoriesTable->setItem(row, 1, new QTableWidgetItem("new"));
|
||||
ui->categoriesTable->setItem(row, 2, new QTableWidgetItem(""));
|
||||
ui->categoriesTable->setItem(row, 3, new QTableWidgetItem("0"));
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::removeCategory_clicked()
|
||||
{
|
||||
ui->categoriesTable->removeRow(m_ContextRow);
|
||||
}
|
||||
|
||||
|
||||
void CategoriesDialog::on_categoriesTable_customContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
m_ContextRow = ui->categoriesTable->rowAt(pos.y());
|
||||
QMenu menu;
|
||||
menu.addAction(tr("Add"), this, SLOT(addCategory_clicked()));
|
||||
menu.addAction(tr("Remove"), this, SLOT(removeCategory_clicked()));
|
||||
|
||||
menu.exec(ui->categoriesTable->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
+71
-71
@@ -1,71 +1,71 @@
|
||||
/*
|
||||
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 CATEGORIESDIALOG_H
|
||||
#define CATEGORIESDIALOG_H
|
||||
|
||||
#include "tutorabledialog.h"
|
||||
#include <set>
|
||||
|
||||
namespace Ui {
|
||||
class CategoriesDialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dialog that allows users to configure mod categories
|
||||
**/
|
||||
class CategoriesDialog : public MOBase::TutorableDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit CategoriesDialog(QWidget *parent = 0);
|
||||
~CategoriesDialog();
|
||||
|
||||
/**
|
||||
* @brief store changes here to the global categories store (categories.h)
|
||||
*
|
||||
**/
|
||||
void commitChanges();
|
||||
|
||||
private slots:
|
||||
|
||||
void on_categoriesTable_customContextMenuRequested(const QPoint &pos);
|
||||
void addCategory_clicked();
|
||||
void removeCategory_clicked();
|
||||
void cellChanged(int row, int column);
|
||||
|
||||
private:
|
||||
|
||||
void refreshIDs();
|
||||
void fillTable();
|
||||
|
||||
private:
|
||||
|
||||
Ui::CategoriesDialog *ui;
|
||||
int m_ContextRow;
|
||||
|
||||
int m_HighestID;
|
||||
std::set<int> m_IDs;
|
||||
|
||||
};
|
||||
|
||||
#endif // CATEGORIESDIALOG_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 CATEGORIESDIALOG_H
|
||||
#define CATEGORIESDIALOG_H
|
||||
|
||||
#include "tutorabledialog.h"
|
||||
#include <set>
|
||||
|
||||
namespace Ui {
|
||||
class CategoriesDialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dialog that allows users to configure mod categories
|
||||
**/
|
||||
class CategoriesDialog : public MOBase::TutorableDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit CategoriesDialog(QWidget *parent = 0);
|
||||
~CategoriesDialog();
|
||||
|
||||
/**
|
||||
* @brief store changes here to the global categories store (categories.h)
|
||||
*
|
||||
**/
|
||||
void commitChanges();
|
||||
|
||||
private slots:
|
||||
|
||||
void on_categoriesTable_customContextMenuRequested(const QPoint &pos);
|
||||
void addCategory_clicked();
|
||||
void removeCategory_clicked();
|
||||
void cellChanged(int row, int column);
|
||||
|
||||
private:
|
||||
|
||||
void refreshIDs();
|
||||
void fillTable();
|
||||
|
||||
private:
|
||||
|
||||
Ui::CategoriesDialog *ui;
|
||||
int m_ContextRow;
|
||||
|
||||
int m_HighestID;
|
||||
std::set<int> m_IDs;
|
||||
|
||||
};
|
||||
|
||||
#endif // CATEGORIESDIALOG_H
|
||||
|
||||
|
||||
+19
-19
@@ -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 "credentialsdialog.h"
|
||||
#include "ui_credentialsdialog.h"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user