mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
9
Commits
release_v1.1.1
...
1.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb98bfade6 | ||
|
|
00f4e1799f | ||
|
|
35fcf1c25b | ||
|
|
bed3c08a6d | ||
|
|
f9eba9dc15 | ||
|
|
9c8e43853d | ||
|
|
7aadb47637 | ||
|
|
76fbe6effe | ||
|
|
38ee6ccf0a |
@@ -106,7 +106,7 @@ const Executable &ExecutablesList::find(const QString &title) const
|
||||
Executable &ExecutablesList::find(const QString &title)
|
||||
{
|
||||
for (std::vector<Executable>::iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
|
||||
if (iter->m_Title == title) {
|
||||
if (QString::compare(iter->m_Title, title, Qt::CaseInsensitive) == 0) {
|
||||
return *iter;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-6
@@ -21,6 +21,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
IconDelegate::IconDelegate(QObject *parent)
|
||||
@@ -37,25 +38,33 @@ void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
|
||||
int x = 4;
|
||||
painter->save();
|
||||
|
||||
int iconWidth = icons.size() > 0 ? ((option.rect.width() / icons.size()) - 4) : 16;
|
||||
iconWidth = std::min(16, iconWidth);
|
||||
|
||||
painter->translate(option.rect.topLeft());
|
||||
for (auto iter = icons.begin(); iter != icons.end(); ++iter) {
|
||||
painter->drawPixmap(x, 2, 16, 16, iter->pixmap(QSize(16, 16)));
|
||||
x += 20;
|
||||
painter->drawPixmap(x, 2, iconWidth, iconWidth, iter->pixmap(QSize(iconWidth, iconWidth)));
|
||||
x += iconWidth + 4;
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
QSize IconDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex &modelIndex) const
|
||||
QSize IconDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &modelIndex) const
|
||||
{
|
||||
int count = getNumIcons(modelIndex);
|
||||
unsigned int index = modelIndex.data(Qt::UserRole + 1).toInt();
|
||||
QSize result;
|
||||
if (index < ModInfo::getNumMods()) {
|
||||
ModInfo::Ptr info = ModInfo::getByIndex(index);
|
||||
return QSize(info->getFlags().size() * 20, 20);
|
||||
result = QSize(count * 40, 20);
|
||||
} else {
|
||||
return QSize(1, 20);
|
||||
result = QSize(1, 20);
|
||||
}
|
||||
if (option.rect.width() > 0) {
|
||||
result.setWidth(std::min(option.rect.width(), result.width()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QSplashScreen>
|
||||
#include <QDirIterator>
|
||||
#include <QDesktopServices>
|
||||
#include <ShellAPI.h>
|
||||
#include <eh.h>
|
||||
#include <windows_error.h>
|
||||
#include <boost/scoped_array.hpp>
|
||||
@@ -277,6 +278,59 @@ void registerMetaTypes()
|
||||
registerExecutable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool HaveWriteAccess(const std::wstring &path)
|
||||
{
|
||||
bool writable = false;
|
||||
|
||||
const static SECURITY_INFORMATION requestedFileInformation = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
|
||||
|
||||
DWORD length = 0;
|
||||
if (!::GetFileSecurityW(path.c_str(), requestedFileInformation, NULL, NULL, &length)
|
||||
&& (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
||||
std::string tempBuffer;
|
||||
tempBuffer.reserve(length);
|
||||
PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)tempBuffer.data();
|
||||
if (security
|
||||
&& ::GetFileSecurity(path.c_str(), requestedFileInformation, security, length, &length)) {
|
||||
HANDLE token = NULL;
|
||||
const static DWORD tokenDesiredAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ;
|
||||
if (!::OpenThreadToken(::GetCurrentThread(), tokenDesiredAccess, TRUE, &token)) {
|
||||
if (!::OpenProcessToken(::GetCurrentProcess(), tokenDesiredAccess, &token)) {
|
||||
throw std::runtime_error("Unable to get any thread or process token");
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE impersonatedToken = NULL;
|
||||
if (::DuplicateToken(token, SecurityImpersonation, &impersonatedToken)) {
|
||||
GENERIC_MAPPING mapping = { 0xFFFFFFFF };
|
||||
mapping.GenericRead = FILE_GENERIC_READ;
|
||||
mapping.GenericWrite = FILE_GENERIC_WRITE;
|
||||
mapping.GenericExecute = FILE_GENERIC_EXECUTE;
|
||||
mapping.GenericAll = FILE_ALL_ACCESS;
|
||||
|
||||
DWORD genericAccessRights = FILE_GENERIC_WRITE;
|
||||
::MapGenericMask(&genericAccessRights, &mapping);
|
||||
|
||||
PRIVILEGE_SET privileges = { 0 };
|
||||
DWORD grantedAccess = 0;
|
||||
DWORD privilegesLength = sizeof(privileges);
|
||||
BOOL result = 0;
|
||||
if (::AccessCheck(security, impersonatedToken, genericAccessRights, &mapping, &privileges, &privilegesLength, &grantedAccess, &result)) {
|
||||
writable = result != 0;
|
||||
}
|
||||
::CloseHandle(impersonatedToken);
|
||||
}
|
||||
|
||||
::CloseHandle(token);
|
||||
}
|
||||
}
|
||||
return writable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MOApplication application(argc, argv);
|
||||
@@ -285,6 +339,16 @@ int main(int argc, char *argv[])
|
||||
|
||||
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
|
||||
|
||||
if (!HaveWriteAccess(ToWString(application.applicationDirPath()))) {
|
||||
QStringList arguments = application.arguments();
|
||||
arguments.pop_front();
|
||||
::ShellExecuteW( NULL
|
||||
, L"runas"
|
||||
, ToWString(QString("\"%1\"").arg(QCoreApplication::applicationFilePath())).c_str()
|
||||
, ToWString(arguments.join(" ")).c_str()
|
||||
, ToWString(QDir::currentPath()).c_str(), SW_SHOWNORMAL);
|
||||
return 1;
|
||||
}
|
||||
LogBuffer::init(200, QtDebugMsg, application.applicationDirPath() + "/logs/mo_interface.log");
|
||||
|
||||
qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath())));
|
||||
|
||||
+52
-34
@@ -58,6 +58,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "problemsdialog.h"
|
||||
#include "previewdialog.h"
|
||||
#include "aboutdialog.h"
|
||||
#include "safewritefile.h"
|
||||
#include <gameinfo.h>
|
||||
#include <appconfig.h>
|
||||
#include <utility.h>
|
||||
@@ -216,6 +217,9 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
|
||||
|
||||
ui->bsaList->setLocalMoveOnly(true);
|
||||
|
||||
ui->splitter->setStretchFactor(0, 3);
|
||||
ui->splitter->setStretchFactor(1, 2);
|
||||
|
||||
resizeLists(initSettings.contains("mod_list_state"), initSettings.contains("plugin_list_state"));
|
||||
|
||||
QMenu *linkMenu = new QMenu(this);
|
||||
@@ -294,6 +298,10 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
|
||||
m_CheckBSATimer.setSingleShot(true);
|
||||
connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList()));
|
||||
|
||||
m_SaveMetaTimer.setSingleShot(false);
|
||||
connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas()));
|
||||
m_SaveMetaTimer.start(5000);
|
||||
|
||||
m_DirectoryRefresher.moveToThread(&m_RefresherThread);
|
||||
m_RefresherThread.start();
|
||||
|
||||
@@ -623,22 +631,18 @@ void MainWindow::createHelpWidget()
|
||||
void MainWindow::saveArchiveList()
|
||||
{
|
||||
if (m_ArchivesInit) {
|
||||
QFile archiveFile(m_CurrentProfile->getArchivesFileName());
|
||||
if (archiveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *tlItem = ui->bsaList->topLevelItem(i);
|
||||
for (int j = 0; j < tlItem->childCount(); ++j) {
|
||||
QTreeWidgetItem *item = tlItem->child(j);
|
||||
if (item->checkState(0) == Qt::Checked) {
|
||||
archiveFile.write(item->text(0).toUtf8().append("\r\n"));
|
||||
}
|
||||
SafeWriteFile archiveFile(m_CurrentProfile->getArchivesFileName());
|
||||
for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *tlItem = ui->bsaList->topLevelItem(i);
|
||||
for (int j = 0; j < tlItem->childCount(); ++j) {
|
||||
QTreeWidgetItem *item = tlItem->child(j);
|
||||
if (item->checkState(0) == Qt::Checked) {
|
||||
archiveFile->write(item->text(0).toUtf8().append("\r\n"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reportError(tr("failed to save archives order, do you have write access "
|
||||
"to \"%1\"?").arg(m_CurrentProfile->getArchivesFileName()));
|
||||
}
|
||||
archiveFile.close();
|
||||
archiveFile.commit();
|
||||
qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_CurrentProfile->getArchivesFileName())));
|
||||
} else {
|
||||
qWarning("archive list not initialised");
|
||||
}
|
||||
@@ -701,18 +705,13 @@ bool MainWindow::saveCurrentLists()
|
||||
return false;
|
||||
}
|
||||
|
||||
// save plugin list
|
||||
try {
|
||||
savePluginList();
|
||||
saveArchiveList();
|
||||
} catch (const std::exception &e) {
|
||||
reportError(tr("failed to save load order: %1").arg(e.what()));
|
||||
}
|
||||
|
||||
// save only if the file doesn't exist at all, changes made in the ui are saved immediately
|
||||
if (!QFile::exists(m_CurrentProfile->getArchivesFileName())) {
|
||||
saveArchiveList();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1216,10 +1215,10 @@ IModInterface *MainWindow::createMod(GuessedValue<QString> &name)
|
||||
QSettings settingsFile(targetDirectory.mid(0).append("/meta.ini"), QSettings::IniFormat);
|
||||
|
||||
settingsFile.setValue("modid", 0);
|
||||
settingsFile.setValue("version", 0);
|
||||
settingsFile.setValue("newestVersion", 0);
|
||||
settingsFile.setValue("version", "");
|
||||
settingsFile.setValue("newestVersion", "");
|
||||
settingsFile.setValue("category", 0);
|
||||
settingsFile.setValue("installationFile", 0);
|
||||
settingsFile.setValue("installationFile", "");
|
||||
return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure).data();
|
||||
// }
|
||||
}
|
||||
@@ -1559,18 +1558,21 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director
|
||||
columns.append("");
|
||||
if (!(*current)->isEmpty()) {
|
||||
QTreeWidgetItem *directoryChild = new QTreeWidgetItem(columns);
|
||||
QTreeWidgetItem *onDemandLoad = new QTreeWidgetItem(QStringList());
|
||||
onDemandLoad->setData(0, Qt::UserRole + 0, "__loaded_on_demand__");
|
||||
onDemandLoad->setData(0, Qt::UserRole + 1, ToQString(temp.str()));
|
||||
onDemandLoad->setData(0, Qt::UserRole + 2, conflictsOnly);
|
||||
directoryChild->addChild(onDemandLoad);
|
||||
subTree->addChild(directoryChild);
|
||||
/* updateTo(directoryChild, temp.str(), **current, conflictsOnly);
|
||||
if (directoryChild->childCount() != 0) {
|
||||
subTree->addChild(directoryChild);
|
||||
if (conflictsOnly) {
|
||||
updateTo(directoryChild, temp.str(), **current, conflictsOnly);
|
||||
if (directoryChild->childCount() != 0) {
|
||||
subTree->addChild(directoryChild);
|
||||
} else {
|
||||
delete directoryChild;
|
||||
}
|
||||
} else {
|
||||
delete directoryChild;
|
||||
}*/
|
||||
QTreeWidgetItem *onDemandLoad = new QTreeWidgetItem(QStringList());
|
||||
onDemandLoad->setData(0, Qt::UserRole + 0, "__loaded_on_demand__");
|
||||
onDemandLoad->setData(0, Qt::UserRole + 1, ToQString(temp.str()));
|
||||
onDemandLoad->setData(0, Qt::UserRole + 2, conflictsOnly);
|
||||
directoryChild->addChild(onDemandLoad);
|
||||
subTree->addChild(directoryChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1964,6 +1966,15 @@ void MainWindow::checkBSAList()
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::saveModMetas()
|
||||
{
|
||||
for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
|
||||
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
|
||||
modInfo->saveMeta();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::fixCategories()
|
||||
{
|
||||
for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
|
||||
@@ -2709,6 +2720,8 @@ void MainWindow::modorder_changed()
|
||||
m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority);
|
||||
}
|
||||
}
|
||||
refreshBSAList();
|
||||
saveArchiveList();
|
||||
m_DirectoryStructure->getFileRegister()->sortOrigins();
|
||||
}
|
||||
|
||||
@@ -3003,8 +3016,9 @@ void MainWindow::modlistChanged(const QModelIndex &index, int role)
|
||||
MessageDialog::showMessage(tr("Multiple esps activated, please check that they don't conflict."), this);
|
||||
}
|
||||
m_PluginList.refreshLoadOrder();
|
||||
// immediately save plugin list
|
||||
// immediately save affected lists
|
||||
savePluginList();
|
||||
saveArchiveList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3150,6 +3164,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index,
|
||||
dialog->activateWindow();
|
||||
connect(dialog, SIGNAL(finished(int)), this, SLOT(overwriteClosed(int)));
|
||||
} else {
|
||||
modInfo->saveMeta();
|
||||
ModInfoDialog dialog(modInfo, m_DirectoryStructure, this);
|
||||
connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString)));
|
||||
connect(&dialog, SIGNAL(downloadRequest(QString)), this, SLOT(downloadRequestedNXM(QString)));
|
||||
@@ -3160,7 +3175,10 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index,
|
||||
connect(&dialog, SIGNAL(endorseMod(ModInfo::Ptr)), this, SLOT(endorseMod(ModInfo::Ptr)));
|
||||
|
||||
dialog.openTab(tab);
|
||||
dialog.restoreTabState(m_Settings.directInterface().value("mod_info_tabs").toByteArray());
|
||||
dialog.exec();
|
||||
m_Settings.directInterface().setValue("mod_info_tabs", dialog.saveTabState());
|
||||
|
||||
modInfo->saveMeta();
|
||||
emit modInfoDisplayed();
|
||||
m_ModList.modInfoChanged(modInfo);
|
||||
|
||||
@@ -352,6 +352,7 @@ private:
|
||||
bool m_DirectoryUpdate;
|
||||
bool m_ArchivesInit;
|
||||
QTimer m_CheckBSATimer;
|
||||
QTimer m_SaveMetaTimer;
|
||||
|
||||
QTime m_StartTime;
|
||||
SaveGameInfoWidget *m_CurrentSaveView;
|
||||
@@ -495,6 +496,8 @@ private slots:
|
||||
void startExeAction();
|
||||
|
||||
void checkBSAList();
|
||||
void saveModMetas();
|
||||
|
||||
void updateStyle(const QString &style);
|
||||
|
||||
void modlistChanged(const QModelIndex &index, int role);
|
||||
|
||||
+4
-4
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>868</width>
|
||||
<height>701</height>
|
||||
<width>926</width>
|
||||
<height>710</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -602,7 +602,7 @@ p, li { white-space: pre-wrap; }
|
||||
</size>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string notr="true">Plugins</string>
|
||||
<string>Plugins</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="leftMargin">
|
||||
@@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
<widget class="QWidget" name="bsaTab">
|
||||
<attribute name="title">
|
||||
<string notr="true">Archives</string>
|
||||
<string>Archives</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<property name="leftMargin">
|
||||
|
||||
@@ -79,12 +79,13 @@ void MessageDialog::resizeEvent(QResizeEvent *event)
|
||||
}
|
||||
|
||||
|
||||
void MessageDialog::showMessage(const QString &text, QWidget *reference)
|
||||
void MessageDialog::showMessage(const QString &text, QWidget *reference, bool bringToFront)
|
||||
{
|
||||
qDebug("%s", qPrintable(text));
|
||||
if (reference != NULL) {
|
||||
MessageDialog *dialog = new MessageDialog(text, reference);
|
||||
dialog->show();
|
||||
reference->activateWindow();
|
||||
if (bringToFront || (qApp->activeWindow() != NULL)) {
|
||||
MessageDialog *dialog = new MessageDialog(text, reference);
|
||||
dialog->show();
|
||||
reference->activateWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+48
-47
@@ -17,50 +17,51 @@ 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 MESSAGEDIALOG_H
|
||||
#define MESSAGEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class MessageDialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* borderless dialog used to display short messages that will automatically
|
||||
* vanish after a moment
|
||||
**/
|
||||
class MessageDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief constructor
|
||||
*
|
||||
* @param text the message to display
|
||||
* @param reference parent widget. This will also be used to position the message at the bottom center of the dialog
|
||||
**/
|
||||
|
||||
explicit MessageDialog(const QString &text, QWidget *reference);
|
||||
|
||||
~MessageDialog();
|
||||
|
||||
/**
|
||||
* factory function for message dialogs. This can be used as a fire-and-forget. The message
|
||||
* will automatically positioned to the reference dialog and get a reasonable view time
|
||||
*
|
||||
* @param text the text to display. The length of this text is used to determine how long the dialog is to be shown
|
||||
* @param reference the reference widget on top of which the message should be displayed
|
||||
**/
|
||||
static void showMessage(const QString &text, QWidget *reference);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
private:
|
||||
Ui::MessageDialog *ui;
|
||||
};
|
||||
|
||||
#endif // MESSAGEDIALOG_H
|
||||
#ifndef MESSAGEDIALOG_H
|
||||
#define MESSAGEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class MessageDialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* borderless dialog used to display short messages that will automatically
|
||||
* vanish after a moment
|
||||
**/
|
||||
class MessageDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief constructor
|
||||
*
|
||||
* @param text the message to display
|
||||
* @param reference parent widget. This will also be used to position the message at the bottom center of the dialog
|
||||
**/
|
||||
|
||||
explicit MessageDialog(const QString &text, QWidget *reference);
|
||||
|
||||
~MessageDialog();
|
||||
|
||||
/**
|
||||
* factory function for message dialogs. This can be used as a fire-and-forget. The message
|
||||
* will automatically positioned to the reference dialog and get a reasonable view time
|
||||
*
|
||||
* @param text the text to display. The length of this text is used to determine how long the dialog is to be shown
|
||||
* @param reference the reference widget on top of which the message should be displayed
|
||||
* @param true if the message should bring MO to front to ensure this message is visible
|
||||
**/
|
||||
static void showMessage(const QString &text, QWidget *reference, bool bringToFront = true);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
private:
|
||||
Ui::MessageDialog *ui;
|
||||
};
|
||||
|
||||
#endif // MESSAGEDIALOG_H
|
||||
|
||||
+48
-3
@@ -25,6 +25,50 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QStringList>
|
||||
#include <QPlastiqueStyle>
|
||||
#include <QCleanlooksStyle>
|
||||
#include <QProxyStyle>
|
||||
#include <QStyleFactory>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
class ProxyStyle : public QProxyStyle {
|
||||
public:
|
||||
ProxyStyle(QStyle *baseStyle = 0)
|
||||
: QProxyStyle(baseStyle)
|
||||
{
|
||||
}
|
||||
|
||||
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const {
|
||||
if(element == QStyle::PE_IndicatorItemViewItemDrop) {
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
QColor col(option->palette.foreground().color());
|
||||
QPen pen(col);
|
||||
pen.setWidth(2);
|
||||
col.setAlpha(50);
|
||||
QBrush brush(col);
|
||||
|
||||
painter->setPen(pen);
|
||||
painter->setBrush(brush);
|
||||
if(option->rect.height() == 0) {
|
||||
QPoint tri[3] = {
|
||||
option->rect.topLeft(),
|
||||
option->rect.topLeft() + QPoint(-5, 5),
|
||||
option->rect.topLeft() + QPoint(-5, -5)
|
||||
};
|
||||
painter->drawPolygon(tri, 3);
|
||||
painter->drawLine(QPoint(option->rect.topLeft().x(), option->rect.topLeft().y()), option->rect.topRight());
|
||||
} else {
|
||||
painter->drawRoundedRect(option->rect, 5, 5);
|
||||
}
|
||||
} else {
|
||||
QProxyStyle::drawPrimitive(element, option, painter, widget);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MOApplication::MOApplication(int argc, char **argv)
|
||||
@@ -32,6 +76,7 @@ MOApplication::MOApplication(int argc, char **argv)
|
||||
{
|
||||
connect(&m_StyleWatcher, SIGNAL(fileChanged(QString)), SLOT(updateStyle(QString)));
|
||||
m_DefaultStyle = style()->objectName();
|
||||
setStyle(new ProxyStyle(style()));
|
||||
}
|
||||
|
||||
|
||||
@@ -79,13 +124,13 @@ bool MOApplication::notify(QObject *receiver, QEvent *event)
|
||||
void MOApplication::updateStyle(const QString &fileName)
|
||||
{
|
||||
if (fileName == "Plastique") {
|
||||
setStyle(new QPlastiqueStyle);
|
||||
setStyle(new ProxyStyle(new QPlastiqueStyle));
|
||||
setStyleSheet("");
|
||||
} else if (fileName == "Cleanlooks") {
|
||||
setStyle(new QCleanlooksStyle);
|
||||
setStyle(new ProxyStyle(new QCleanlooksStyle));
|
||||
setStyleSheet("");
|
||||
} else {
|
||||
setStyle(m_DefaultStyle);
|
||||
setStyle(new ProxyStyle(QStyleFactory::create(m_DefaultStyle)));
|
||||
if (QFile::exists(fileName)) {
|
||||
setStyleSheet(QString("file:///%1").arg(fileName));
|
||||
} else {
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
#include <QList>
|
||||
|
||||
|
||||
ModInfo::EFlag ModFlagIconDelegate::m_ConflictFlags[4] = { ModInfo::FLAG_CONFLICT_MIXED
|
||||
, ModInfo::FLAG_CONFLICT_OVERWRITE
|
||||
, ModInfo::FLAG_CONFLICT_OVERWRITTEN
|
||||
, ModInfo::FLAG_CONFLICT_REDUNDANT };
|
||||
|
||||
ModFlagIconDelegate::ModFlagIconDelegate(QObject *parent)
|
||||
: IconDelegate(parent)
|
||||
{
|
||||
@@ -15,6 +20,16 @@ QList<QIcon> ModFlagIconDelegate::getIcons(const QModelIndex &index) const
|
||||
ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt());
|
||||
std::vector<ModInfo::EFlag> flags = info->getFlags();
|
||||
|
||||
{ // insert conflict icon first to provide nicer alignment
|
||||
auto iter = std::find_first_of(flags.begin(), flags.end(), m_ConflictFlags, m_ConflictFlags + 4);
|
||||
if (iter != flags.end()) {
|
||||
result.append(getFlagIcon(*iter));
|
||||
flags.erase(iter);
|
||||
} else {
|
||||
result.append(QIcon());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto iter = flags.begin(); iter != flags.end(); ++iter) {
|
||||
result.append(getFlagIcon(*iter));
|
||||
}
|
||||
@@ -42,7 +57,12 @@ size_t ModFlagIconDelegate::getNumIcons(const QModelIndex &index) const
|
||||
unsigned int modIdx = index.data(Qt::UserRole + 1).toInt();
|
||||
if (modIdx < ModInfo::getNumMods()) {
|
||||
ModInfo::Ptr info = ModInfo::getByIndex(modIdx);
|
||||
return info->getFlags().size();
|
||||
std::vector<ModInfo::EFlag> flags = info->getFlags();
|
||||
int count = flags.size();
|
||||
if (std::find_first_of(flags.begin(), flags.end(), m_ConflictFlags, m_ConflictFlags + 4) == flags.end()) {
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ private:
|
||||
virtual size_t getNumIcons(const QModelIndex &index) const;
|
||||
|
||||
QIcon getFlagIcon(ModInfo::EFlag flag) const;
|
||||
|
||||
private:
|
||||
static ModInfo::EFlag m_ConflictFlags[4];
|
||||
};
|
||||
|
||||
#endif // MODFLAGICONDELEGATE_H
|
||||
|
||||
+67
-53
@@ -300,48 +300,7 @@ ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStruc
|
||||
testValid();
|
||||
m_CreationTime = QFileInfo(path.absolutePath()).created();
|
||||
// read out the meta-file for information
|
||||
QString metaFileName = path.absoluteFilePath("meta.ini");
|
||||
QSettings metaFile(metaFileName, QSettings::IniFormat);
|
||||
|
||||
m_Notes = metaFile.value("notes", "").toString();
|
||||
m_NexusID = metaFile.value("modid", -1).toInt();
|
||||
m_Version.parse(metaFile.value("version", "").toString());
|
||||
m_NewestVersion = metaFile.value("newestVersion", "").toString();
|
||||
m_IgnoredVersion = metaFile.value("ignoredVersion", "").toString();
|
||||
m_InstallationFile = metaFile.value("installationFile", "").toString();
|
||||
m_NexusDescription = metaFile.value("nexusDescription", "").toString();
|
||||
m_LastNexusQuery = QDateTime::fromString(metaFile.value("lastNexusQuery", "").toString(), Qt::ISODate);
|
||||
if (metaFile.contains("endorsed")) {
|
||||
if (metaFile.value("endorsed").canConvert<int>()) {
|
||||
switch (metaFile.value("endorsed").toInt()) {
|
||||
case ENDORSED_FALSE: m_EndorsedState = ENDORSED_FALSE; break;
|
||||
case ENDORSED_TRUE: m_EndorsedState = ENDORSED_TRUE; break;
|
||||
case ENDORSED_NEVER: m_EndorsedState = ENDORSED_NEVER; break;
|
||||
default: m_EndorsedState = ENDORSED_UNKNOWN; break;
|
||||
}
|
||||
} else {
|
||||
m_EndorsedState = metaFile.value("endorsed", false).toBool() ? ENDORSED_TRUE : ENDORSED_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString categoriesString = metaFile.value("category", "").toString();
|
||||
|
||||
QStringList categories = categoriesString.split(',', QString::SkipEmptyParts);
|
||||
for (QStringList::iterator iter = categories.begin(); iter != categories.end(); ++iter) {
|
||||
bool ok = false;
|
||||
int categoryID = iter->toInt(&ok);
|
||||
if (categoryID < 0) {
|
||||
// ignore invalid id
|
||||
continue;
|
||||
}
|
||||
if (ok && (categoryID != 0) && (CategoryFactory::instance().categoryExists(categoryID))) {
|
||||
m_Categories.insert(categoryID);
|
||||
if (iter == categories.begin()) {
|
||||
m_PrimaryCategory = categoryID;
|
||||
}
|
||||
}
|
||||
}
|
||||
readMeta();
|
||||
|
||||
connect(&m_NexusBridge, SIGNAL(descriptionAvailable(int,QVariant,QVariant)), this, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant)));
|
||||
connect(&m_NexusBridge, SIGNAL(endorsementToggled(int,QVariant,QVariant)), this, SLOT(nxmEndorsementToggled(int,QVariant,QVariant)));
|
||||
@@ -369,6 +328,52 @@ bool ModInfoRegular::isEmpty() const
|
||||
}
|
||||
|
||||
|
||||
void ModInfoRegular::readMeta()
|
||||
{
|
||||
QSettings metaFile(m_Path + "/meta.ini", QSettings::IniFormat);
|
||||
|
||||
m_Notes = metaFile.value("notes", "").toString();
|
||||
m_NexusID = metaFile.value("modid", -1).toInt();
|
||||
m_Version.parse(metaFile.value("version", "").toString());
|
||||
m_NewestVersion = metaFile.value("newestVersion", "").toString();
|
||||
m_IgnoredVersion = metaFile.value("ignoredVersion", "").toString();
|
||||
m_InstallationFile = metaFile.value("installationFile", "").toString();
|
||||
m_NexusDescription = metaFile.value("nexusDescription", "").toString();
|
||||
m_LastNexusQuery = QDateTime::fromString(metaFile.value("lastNexusQuery", "").toString(), Qt::ISODate);
|
||||
if (metaFile.contains("endorsed")) {
|
||||
if (metaFile.value("endorsed").canConvert<int>()) {
|
||||
switch (metaFile.value("endorsed").toInt()) {
|
||||
case ENDORSED_FALSE: m_EndorsedState = ENDORSED_FALSE; break;
|
||||
case ENDORSED_TRUE: m_EndorsedState = ENDORSED_TRUE; break;
|
||||
case ENDORSED_NEVER: m_EndorsedState = ENDORSED_NEVER; break;
|
||||
default: m_EndorsedState = ENDORSED_UNKNOWN; break;
|
||||
}
|
||||
} else {
|
||||
m_EndorsedState = metaFile.value("endorsed", false).toBool() ? ENDORSED_TRUE : ENDORSED_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
QString categoriesString = metaFile.value("category", "").toString();
|
||||
|
||||
QStringList categories = categoriesString.split(',', QString::SkipEmptyParts);
|
||||
for (QStringList::iterator iter = categories.begin(); iter != categories.end(); ++iter) {
|
||||
bool ok = false;
|
||||
int categoryID = iter->toInt(&ok);
|
||||
if (categoryID < 0) {
|
||||
// ignore invalid id
|
||||
continue;
|
||||
}
|
||||
if (ok && (categoryID != 0) && (CategoryFactory::instance().categoryExists(categoryID))) {
|
||||
m_Categories.insert(categoryID);
|
||||
if (iter == categories.begin()) {
|
||||
m_PrimaryCategory = categoryID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_MetaInfoChanged = false;
|
||||
}
|
||||
|
||||
void ModInfoRegular::saveMeta()
|
||||
{
|
||||
// only write meta data if the mod directory exists
|
||||
@@ -381,7 +386,9 @@ void ModInfoRegular::saveMeta()
|
||||
metaFile.setValue("newestVersion", m_NewestVersion.canonicalString());
|
||||
metaFile.setValue("ignoredVersion", m_IgnoredVersion.canonicalString());
|
||||
metaFile.setValue("version", m_Version.canonicalString());
|
||||
metaFile.setValue("modid", m_NexusID);
|
||||
if (m_NexusID != -1) {
|
||||
metaFile.setValue("modid", m_NexusID);
|
||||
}
|
||||
metaFile.setValue("notes", m_Notes);
|
||||
metaFile.setValue("nexusDescription", m_NexusDescription);
|
||||
metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate));
|
||||
@@ -389,10 +396,15 @@ void ModInfoRegular::saveMeta()
|
||||
metaFile.setValue("endorsed", m_EndorsedState);
|
||||
}
|
||||
metaFile.sync(); // sync needs to be called to ensure the file is created
|
||||
|
||||
if (metaFile.status() == QSettings::NoError) {
|
||||
m_MetaInfoChanged = false;
|
||||
} else {
|
||||
reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status()));
|
||||
}
|
||||
} else {
|
||||
reportError(tr("failed to write %1/meta.ini: %2").arg(absolutePath()).arg(metaFile.status()));
|
||||
reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status()));
|
||||
}
|
||||
m_MetaInfoChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,6 +568,10 @@ void ModInfoRegular::setVersion(const VersionInfo &version)
|
||||
m_MetaInfoChanged = true;
|
||||
}
|
||||
|
||||
void ModInfoRegular::setNewestVersion(const VersionInfo &version) {
|
||||
m_NewestVersion = version;
|
||||
}
|
||||
|
||||
void ModInfoRegular::setNexusDescription(const QString &description)
|
||||
{
|
||||
m_NexusDescription = description;
|
||||
@@ -621,12 +637,6 @@ void ModInfoRegular::ignoreUpdate(bool ignore)
|
||||
std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const
|
||||
{
|
||||
std::vector<ModInfo::EFlag> result;
|
||||
if (!isValid()) {
|
||||
result.push_back(ModInfo::FLAG_INVALID);
|
||||
}
|
||||
if ((m_NexusID != -1) && (endorsedState() == ENDORSED_FALSE)) {
|
||||
result.push_back(ModInfo::FLAG_NOTENDORSED);
|
||||
}
|
||||
switch (isConflicted()) {
|
||||
case CONFLICT_MIXED: {
|
||||
result.push_back(ModInfo::FLAG_CONFLICT_MIXED);
|
||||
@@ -642,6 +652,12 @@ std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const
|
||||
} break;
|
||||
default: { /* NOP */ }
|
||||
}
|
||||
if ((m_NexusID != -1) && (endorsedState() == ENDORSED_FALSE)) {
|
||||
result.push_back(ModInfo::FLAG_NOTENDORSED);
|
||||
}
|
||||
if (!isValid()) {
|
||||
result.push_back(ModInfo::FLAG_INVALID);
|
||||
}
|
||||
if (m_Notes.length() != 0) {
|
||||
result.push_back(ModInfo::FLAG_NOTES);
|
||||
}
|
||||
@@ -691,13 +707,11 @@ QString ModInfoRegular::getNexusDescription() const
|
||||
return m_NexusDescription;
|
||||
}
|
||||
|
||||
|
||||
ModInfoRegular::EEndorsedState ModInfoRegular::endorsedState() const
|
||||
{
|
||||
return m_EndorsedState;
|
||||
}
|
||||
|
||||
|
||||
ModInfoRegular::EConflictType ModInfoRegular::isConflicted() const
|
||||
{
|
||||
// this is costy so cache the result
|
||||
|
||||
+7
-1
@@ -431,6 +431,11 @@ public:
|
||||
*/
|
||||
void testValid();
|
||||
|
||||
/**
|
||||
* @brief reads meta information from disk
|
||||
*/
|
||||
virtual void readMeta() {}
|
||||
|
||||
/**
|
||||
* @brief stores meta information back to disk
|
||||
*/
|
||||
@@ -592,7 +597,7 @@ public:
|
||||
* @todo this function should be made obsolete. All queries for mod information should go through
|
||||
* this class so no public function for this change is required
|
||||
**/
|
||||
void setNewestVersion(const MOBase::VersionInfo &version) { m_NewestVersion = version; }
|
||||
void setNewestVersion(const MOBase::VersionInfo &version);
|
||||
|
||||
/**
|
||||
* @brief changes/updates the nexus description text
|
||||
@@ -748,6 +753,7 @@ public:
|
||||
*/
|
||||
virtual void saveMeta();
|
||||
|
||||
void readMeta();
|
||||
private:
|
||||
|
||||
enum EConflictType {
|
||||
|
||||
+64
-13
@@ -69,7 +69,6 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
|
||||
ui->setupUi(this);
|
||||
this->setWindowTitle(modInfo->name());
|
||||
this->setWindowModality(Qt::WindowModal);
|
||||
|
||||
m_UTF8Codec = QTextCodec::codecForName("utf-8");
|
||||
|
||||
QListWidget *textFileList = findChild<QListWidget*>("textFileList");
|
||||
@@ -143,7 +142,6 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
|
||||
|
||||
QTabWidget *tabWidget = findChild<QTabWidget*>("tabWidget");
|
||||
tabWidget->setTabEnabled(TAB_TEXTFILES, textFileList->count() != 0);
|
||||
//tabWidget->setTabEnabled(TAB_INIFILES, (iniFileList->count() != 0) || (iniTweaksList->count() != 0));
|
||||
tabWidget->setTabEnabled(TAB_IMAGES, thumbnailArea->count() != 0);
|
||||
tabWidget->setTabEnabled(TAB_ESPS, (inactiveESPList->count() != 0) || (activeESPList->count() != 0));
|
||||
tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != NULL);
|
||||
@@ -160,14 +158,69 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
|
||||
ModInfoDialog::~ModInfoDialog()
|
||||
{
|
||||
m_ModInfo->setNotes(ui->notesEdit->toPlainText());
|
||||
saveIniTweaks();
|
||||
saveCategories(ui->categoriesTree->invisibleRootItem());
|
||||
|
||||
saveIniTweaks(); // ini tweaks are written to the ini file directly. This is the only information not managed by ModInfo
|
||||
delete ui;
|
||||
delete m_Settings;
|
||||
}
|
||||
|
||||
|
||||
int ModInfoDialog::tabIndex(const QString &tabId)
|
||||
{
|
||||
for (int i = 0; i < ui->tabWidget->count(); ++i) {
|
||||
if (ui->tabWidget->widget(i)->objectName() == tabId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void ModInfoDialog::restoreTabState(const QByteArray &state)
|
||||
{
|
||||
QDataStream stream(state);
|
||||
int count = 0;
|
||||
stream >> count;
|
||||
|
||||
QStringList tabIds;
|
||||
|
||||
// first, only determine the new mapping
|
||||
for (int newPos = 0; newPos < count; ++newPos) {
|
||||
QString tabId;
|
||||
stream >> tabId;
|
||||
tabIds.append(tabId);
|
||||
int oldPos = tabIndex(tabId);
|
||||
if (oldPos != -1) {
|
||||
m_RealTabPos[newPos] = oldPos;
|
||||
} else {
|
||||
m_RealTabPos[newPos] = newPos;
|
||||
}
|
||||
}
|
||||
// then actually move the tabs
|
||||
QTabBar *tabBar = ui->tabWidget->findChild<QTabBar*>("qt_tabwidget_tabbar"); // magic name = bad
|
||||
ui->tabWidget->blockSignals(true);
|
||||
for (int newPos = 0; newPos < count; ++newPos) {
|
||||
QString tabId = tabIds.at(newPos);
|
||||
int oldPos = tabIndex(tabId);
|
||||
tabBar->moveTab(oldPos, newPos);
|
||||
}
|
||||
ui->tabWidget->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
QByteArray ModInfoDialog::saveTabState() const
|
||||
{
|
||||
QByteArray result;
|
||||
QDataStream stream(&result, QIODevice::WriteOnly);
|
||||
stream << ui->tabWidget->count();
|
||||
for (int i = 0; i < ui->tabWidget->count(); ++i) {
|
||||
stream << ui->tabWidget->widget(i)->objectName();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void ModInfoDialog::refreshLists()
|
||||
{
|
||||
int numNonConflicting = 0;
|
||||
@@ -331,7 +384,6 @@ void ModInfoDialog::openTab(int tab)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ModInfoDialog::thumbnailClicked(const QString &fileName)
|
||||
{
|
||||
QLabel *imageLabel = findChild<QLabel*>("imageLabel");
|
||||
@@ -421,18 +473,15 @@ void ModInfoDialog::openIniFile(const QString &fileName)
|
||||
|
||||
void ModInfoDialog::saveIniTweaks()
|
||||
{
|
||||
QListWidget *iniTweaksList = findChild<QListWidget*>("iniTweaksList");
|
||||
|
||||
m_Settings->beginWriteArray("INI Tweaks");
|
||||
|
||||
int countEnabled = 0;
|
||||
for (int i = 0; i < iniTweaksList->count(); ++i) {
|
||||
if (iniTweaksList->item(i)->checkState() == Qt::Checked) {
|
||||
for (int i = 0; i < ui->iniTweaksList->count(); ++i) {
|
||||
if (ui->iniTweaksList->item(i)->checkState() == Qt::Checked) {
|
||||
m_Settings->setArrayIndex(countEnabled++);
|
||||
m_Settings->setValue("name", iniTweaksList->item(i)->text());
|
||||
m_Settings->setValue("name", ui->iniTweaksList->item(i)->text());
|
||||
}
|
||||
}
|
||||
|
||||
m_Settings->endArray();
|
||||
}
|
||||
|
||||
@@ -784,7 +833,7 @@ void ModInfoDialog::activateNexusTab()
|
||||
|
||||
void ModInfoDialog::on_tabWidget_currentChanged(int index)
|
||||
{
|
||||
if (index == TAB_NEXUS) {
|
||||
if (m_RealTabPos[index] == TAB_NEXUS) {
|
||||
activateNexusTab();
|
||||
}
|
||||
}
|
||||
@@ -1175,8 +1224,10 @@ void ModInfoDialog::createTweak()
|
||||
return;
|
||||
}
|
||||
|
||||
QListWidgetItem *newTweak = new QListWidgetItem(name);
|
||||
QListWidgetItem *newTweak = new QListWidgetItem(name + ".ini");
|
||||
newTweak->setData(Qt::UserRole, "INI Tweaks/" + name + ".ini");
|
||||
newTweak->setFlags(newTweak->flags() | Qt::ItemIsUserCheckable);
|
||||
newTweak->setCheckState(Qt::Unchecked);
|
||||
ui->iniTweaksList->addItem(newTweak);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,10 @@ public:
|
||||
**/
|
||||
void openTab(int tab);
|
||||
|
||||
void restoreTabState(const QByteArray &state);
|
||||
|
||||
QByteArray saveTabState() const;
|
||||
|
||||
signals:
|
||||
|
||||
void thumbnailClickedSignal(const QString &filename);
|
||||
@@ -142,6 +146,8 @@ private:
|
||||
void addCheckedCategories(QTreeWidgetItem *tree);
|
||||
void refreshPrimaryCategoriesBox();
|
||||
|
||||
int tabIndex(const QString &tabId);
|
||||
|
||||
private slots:
|
||||
|
||||
void hideConflictFile();
|
||||
@@ -221,6 +227,8 @@ private:
|
||||
MOShared::FilesOrigin *m_Origin;
|
||||
QTextCodec *m_UTF8Codec;
|
||||
|
||||
std::map<int, int> m_RealTabPos;
|
||||
|
||||
};
|
||||
|
||||
#endif // MODINFODIALOG_H
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabText">
|
||||
<attribute name="title">
|
||||
<string>Textfiles</string>
|
||||
@@ -209,7 +212,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>668</width>
|
||||
<width>676</width>
|
||||
<height>126</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -546,7 +549,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabNexus_2">
|
||||
<widget class="QWidget" name="tabNexus">
|
||||
<attribute name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/MO/gui/resources/internet-web-browser.png</normaloff>:/MO/gui/resources/internet-web-browser.png</iconset>
|
||||
@@ -666,8 +669,8 @@ p, li { white-space: pre-wrap; }
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextBrowserInteraction</set>
|
||||
|
||||
+818
-634
File diff suppressed because it is too large
Load Diff
+814
-634
File diff suppressed because it is too large
Load Diff
+816
-640
File diff suppressed because it is too large
Load Diff
+813
-637
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
Reference in New Issue
Block a user