mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
63
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0eb1662a0e | ||
|
|
164ec25a75 | ||
|
|
6fb36d6c02 | ||
|
|
ea1f959ad5 | ||
|
|
7cf3b3455b | ||
|
|
84cfa95254 | ||
|
|
264da60929 | ||
|
|
2db33523a1 | ||
|
|
540747177a | ||
|
|
739c3424e7 | ||
|
|
cabed9b268 | ||
|
|
c017f4a0d5 | ||
|
|
b1f1682790 | ||
|
|
28301e7486 | ||
|
|
2d0fab4482 | ||
|
|
c19c4820d8 | ||
|
|
8ab1b47943 | ||
|
|
ff272dcbbd | ||
|
|
98354cd1e7 | ||
|
|
129b76d7d2 | ||
|
|
a82b7e9949 | ||
|
|
0f8f7bf777 | ||
|
|
f4cf992700 | ||
|
|
bec644bac3 | ||
|
|
bb98bfade6 | ||
|
|
00f4e1799f | ||
|
|
35fcf1c25b | ||
|
|
bed3c08a6d | ||
|
|
f9eba9dc15 | ||
|
|
9c8e43853d | ||
|
|
7aadb47637 | ||
|
|
76fbe6effe | ||
|
|
38ee6ccf0a | ||
|
|
7722a9b6df | ||
|
|
48704877ca | ||
|
|
48c944c737 | ||
|
|
af50eedbe2 | ||
|
|
52e5dd3c57 | ||
|
|
ccd5d1294f | ||
|
|
de984a4ef8 | ||
|
|
e597823337 | ||
|
|
e69210b3a7 | ||
|
|
40d20ab294 | ||
|
|
6ed82866b0 | ||
|
|
a083a2d3b6 | ||
|
|
db09b806b9 | ||
|
|
859c0aed98 | ||
|
|
0ea7d99b9f | ||
|
|
6cffbd4f27 | ||
|
|
4dc3538a7d | ||
|
|
e45b747c82 | ||
|
|
2d6bacbb6a | ||
|
|
d029e97724 | ||
|
|
a9435f637e | ||
|
|
e1e35da6fe | ||
|
|
e43f126b03 | ||
|
|
35c9fe3e98 | ||
|
|
82f7b09b40 | ||
|
|
f33d24870f | ||
|
|
14ac234daf | ||
|
|
22b8eb7c5a | ||
|
|
9ee90a35dc | ||
|
|
98e5e57a84 |
@@ -13,3 +13,10 @@ source - Copy/*
|
||||
ModOrganizer-build-*
|
||||
pdbs/*
|
||||
source/NCC/BossDummy.x/*
|
||||
*.ts
|
||||
staging_prepare/*
|
||||
staging_trans/*
|
||||
tools/python_zip/*
|
||||
Makefile
|
||||
syntax: regexp
|
||||
Makefile\.(Debug|Release)
|
||||
|
||||
+158
-15
@@ -1,46 +1,115 @@
|
||||
HOW TO BUILD
|
||||
============
|
||||
|
||||
Intro:
|
||||
------
|
||||
|
||||
Building Mod Organizer can be a rather daunting task especially if you're not very comfortable with C++ development under windows.
|
||||
Please note that if you only want to work on and build a plugin you can save yourself a lot of trouble
|
||||
|
||||
Overview:
|
||||
---------
|
||||
|
||||
As of December 2013 MO consists of the following subprojects:
|
||||
- organizer: The main userinterface. heavy usage of various libraries
|
||||
- hookdll: core library of the virtual file system
|
||||
- uibase: interop between plugins and the main application as well as some reusable functionality
|
||||
- shared: functionality shared between organizer and hookdll. I'm attempting to get rid of this library over time
|
||||
- nxmhandler: tool to pass handling of nxm links to MO or other applications
|
||||
- helper: tool for doing operations requiring elevated priviledges if MO doesn't have them
|
||||
- proxydll: dll used in the "proxy dll" load mechanism
|
||||
- esptk: small library containing functionality to work with esps/esms
|
||||
- bsatk: small library containing functionality to work with bsas. Requires zlib to extract files. Requires boost_thread to provide multi-threaded extraction
|
||||
- archive: small wrapper library around 7zip for dealing with mod archives. Requires 7zip
|
||||
- NCC: extension to NMM to provide a binary with command line interface for fomod installation. This is c# code and does not build with the rest of the project. Requires the rest of NMM
|
||||
- bossdummy: dummy dll that looks like the boss.dll. This is used instead of the real boss dlls in NCC to save some disk space
|
||||
- pythonrunner: library for embedding python code. Requires boost_python, python 2.7 and pyqt4
|
||||
|
||||
And various plugins:
|
||||
- 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)
|
||||
- installerNCC: handles installation of any fomod (requires NCC)
|
||||
- installerQuick: handles very simple one-click installations
|
||||
- NMMImport: importer from existing nmm installation
|
||||
- proxyPython: integrates pythonrunner as a plugin into MO
|
||||
- pyniEdit: more user-friendly ini editor. python code
|
||||
|
||||
|
||||
Requirements:
|
||||
-------------
|
||||
|
||||
Visual C++ compiler 2010 (VC 10.0) or up
|
||||
- Included in visual c++ express 2010 or windows sdk 7.0
|
||||
- Included in visual c++ express 2010 or windows sdk 7.x
|
||||
- Do install windows sdk too if only for the cdb debugger which is included in that package
|
||||
Note: If you're having trouble installing the windows sdk, you may be affected by this bug: http://support.microsoft.com/kb/2717426
|
||||
|
||||
QtSDK 4.8.x (http://qt-project.org/downloads)
|
||||
- Qt5 is not yet supported but WIP
|
||||
Qt Libraries 4.8.x (http://qt-project.org/downloads)
|
||||
- i.e. "Qt libraries 4.8.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
|
||||
- Install according to instruction
|
||||
|
||||
boost libraries (http://www.boost.org/)
|
||||
- Compile 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 lib MO needs (at the time of writing) is
|
||||
boost_thread. You can disable the others to safe yourself compile time (even on a modern system compiling boost can easily take an hour)
|
||||
- tested: 1.49
|
||||
- Build according to their instructions (using vc++): http://www.boost.org/doc/libs/1_54_0/more/getting_started/windows.html
|
||||
- A few of the boost libraries need to be built (the rest is header-only). The only compiled libs MO needs (at the time of writing) are
|
||||
boost_thread (for everything that links agains bsatk) and boost_python (for pythonrunner). You can disable the others to save yourself compile time (even on a modern system compiling boost can easily take an hour)
|
||||
|
||||
zlib (http://www.zlib.net/)
|
||||
- Compile static library according to their instructions
|
||||
- Depending on the version of zlib and how you built you should have a file called zlibstatic.lib or zlibstat.lib in "build" or "x86\ZLibStatRelease".
|
||||
- Please copy that lib file to "build\zlibstatic.lib" (if it doesn't exist) so MO finds it.
|
||||
|
||||
7z.dll (http://www.7-zip.org/download.html)
|
||||
- Part of the 7-zip program
|
||||
- Has to be the 32-bit dll! (approx. 893kb)
|
||||
- If you don't want to install 7-zip (32-bit) you can open the 7z installer (i.e. 7z920.exe) in an archiving tool and unpack only the 7z.dll
|
||||
7z sourcecode (http://www.7-zip.org/download.html)
|
||||
- only for "archive" subproject
|
||||
- no need to compile, will be linked into project
|
||||
|
||||
Python 2.7 (32-bit)
|
||||
- only for pythonrunner
|
||||
|
||||
PyQt4 for Python 2.7
|
||||
- tested: 4.10
|
||||
- only for pythonrunner
|
||||
|
||||
|
||||
Recommended:
|
||||
------------
|
||||
|
||||
Qt Creator
|
||||
- http://qt-project.org/downloads#qt-creator
|
||||
- I.e. "Qt Creator 2.8.1 for Windows (53 MB)"
|
||||
- With Qt Creator usually the rule is "the newer the better"
|
||||
- Start Qt Creator and check if things are set up correctly:
|
||||
1) Go to Tools > Options > Build & Run > Qt Versions
|
||||
2.1) If the QtSDK 4.8.x you installed earlier is not auto-detected, click "Add" to add it manually
|
||||
2.2) Navigate to your <your qt4 installation>\bin\qmake.exe
|
||||
2.3) Restart qt creator
|
||||
3) Go to Tools > Options > Build & Run > Kits
|
||||
3.1) If no Kit is auto-detected (or the auto-detected ones have picked up the wrong qt or vc++ installation) click "Add"
|
||||
3.2) Enter a Name (i.e. "Qt 4.8.5 MSVC2010 32bit")
|
||||
3.3) In Compiler select the visual studio compiler installed earlier (may show up as "Microsoft Windows SDK for Windows x). Make sure you select the x86 variant
|
||||
3.4) CDB should be auto-detected
|
||||
3.5) Select the qt version set up earlier
|
||||
4) Apply and close the options
|
||||
|
||||
Set up (using Qt Creator):
|
||||
--------------------------
|
||||
|
||||
1. Using Qt Creator open source/ModOrganizer.pro from your working copy
|
||||
2. Open the "Projects" tab, open the "Details" for "Build Environment"
|
||||
3. Click "Add" to add a variable called "BOOSTPATH" with the path of your boost installation as the value (i.e. C:\code\boost_1_52_0)
|
||||
4. Click "Add" to add a variable called "ZLIBPATH" with the path of your zlib installation as the value (i.e. C:\code\zlib-1.2.7)
|
||||
5. Switch the build configuration at the very top of the same page from "debug" to "release" (or vice versa) and repeat steps 3 and 4
|
||||
6. Compile the configuration(s) you want to use (debug and/or release) (Build All). This should compile correctly.
|
||||
3a. Click "Add" to add a variable called "BOOSTPATH" with the path of your boost installation as the value (i.e. C:\code\boost_1_49_0)
|
||||
3b. Click "Add" to add a variable called "ZLIBPATH" with the path of your zlib installation as the value (i.e. C:\code\zlib-1.2.7)
|
||||
3c. Click "Add" to add a variable called "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)
|
||||
4. Switch the build configuration at the very top of the same page from "debug" to "release" (or vice versa) and repeat step 3
|
||||
5. Compile the configuration(s) you want to use (debug and/or release) (Build All). This should compile correctly.
|
||||
6. <reserved for future use. Maybe grab a coffee?>
|
||||
7. return to the "projects" tab and switch to "Run Settings"
|
||||
8. Determine the folder of the qt binaries in the package you downloaded. This could be "QtSDK\Desktop\Qt\4.8.5\msvc2010\bin" or "Qt4.8.5\bin"
|
||||
For Release build:
|
||||
@@ -68,4 +137,78 @@ Set up (without Qt Creator):
|
||||
|
||||
I'm not using this workflow so I can't give more detailed instructions.
|
||||
Please note that the primary project format of MO remains qmake, if you work with visual studio and make changes to the project (like adding
|
||||
source files) you have to manually transfer those changes to the .pro file.
|
||||
source files) you have to manually transfer those changes to the .pro file.
|
||||
|
||||
|
||||
|
||||
-----------------
|
||||
Troubleshooting (thanks to Ross):
|
||||
-----------------
|
||||
|
||||
1) When I try to build, I am seeing the error "error: LNK1104: cannot open file 'zlibstatic.lib'"
|
||||
|
||||
a) Make sure you have the following files
|
||||
{ZLIBPATH}\build\zconf.h
|
||||
{ZLIBPATH}\build\zlib.h
|
||||
{ZLIBPATH}\build\zlibstatic.lib
|
||||
|
||||
b) make sure "zlibstat.lib" was renamed to "zlibstatic.lib"
|
||||
c) currently, there are references to zlibstatic in the following 2 project files:
|
||||
./bsatk/bsatk.pro
|
||||
./hookdll/hookdll.pro
|
||||
|
||||
2) After building, I try to open {MOPROJECTPATH}\outputd\ModOragnizer.exe and get this error
|
||||
"The program can't start because QtDeclaratived4.dll is missing from your computer. Try reinstalling the program to fix this problem."
|
||||
|
||||
-> When setting up Qt4.8.x, make sure you copied the "d" (debug) versions of the dll files to {MOPROJECTPATH}\outputd\dlls
|
||||
If you copied the release version or did not copy the dlls at all, you may see this error.
|
||||
The *.dll files can be found in {QT48xPATH}\bin
|
||||
|
||||
Similiar:
|
||||
http://stackoverflow.com/questions/11196416/cant-start-qt-exe-file-on-windows-7
|
||||
|
||||
3) I am getting one or more of the the following compiler warnings...
|
||||
|
||||
"{MOPROJECTPATH}\source\bsatk\bsaexception.cpp:32: warning: C4996: 'vsnprintf': This function or variable may be unsafe.
|
||||
Consider using vsnprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details."
|
||||
-> Ignore/suppress warning like this and make be ultra-careful using printf-style functions. vsnprintf_s is a visual-c++ only function so using those would make porting (i.e. to mingw) harder
|
||||
|
||||
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\stdio.h:354: see declaration of 'vsnprintf'"
|
||||
-> see previous
|
||||
|
||||
"debug\bsaarchive.obj:-1: warning: LNK4042: object specified more than once; extras ignored"
|
||||
|
||||
-> This appears to be an issue when using VC++ 2010 as the compiler. There are some posts on StackOverflow
|
||||
which suggest fixes when using VC++ as the IDE, but not sure how to apply them to Qt Creator.
|
||||
http://stackoverflow.com/questions/3729515
|
||||
http://stackoverflow.com/questions/3695174
|
||||
|
||||
-> Also, not sure if this affects VC++ 2012 / VC++ 2013 / GCC via cygwin/mingw.
|
||||
Not even sure if the project would successfully compile on these.
|
||||
|
||||
"{MOPROJECTPATH}\source\organizer\mainwindow.cpp:3995: warning: C4428: universal-character-name encountered in source"
|
||||
|
||||
-> very pointless warning.
|
||||
http://stackoverflow.com/questions/11589571
|
||||
http://stackoverflow.com/questions/7078013
|
||||
|
||||
the best solution I saw was to just disable the warning altogether...
|
||||
#pragma warning( disable : 4428 )
|
||||
|
||||
"warning: LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library"
|
||||
|
||||
-> You can always add a #pragma to ignore them :P
|
||||
http://msdn.microsoft.com/en-us/library/2c8f766e%28v=vs.80%29.aspx
|
||||
|
||||
4) I got the following error while building...
|
||||
"error: LNK1201: error writing to program database
|
||||
'{MOPROJECTPATH}\{whatever-your-build-directory-name-is}\organizer\debug\ModOrganizer.pdb';
|
||||
check for insufficient disk space, invalid path, or insufficient privilege"
|
||||
|
||||
-> I had this happen after trying to look at something in memory via Process Explorer.
|
||||
To resolve, I killed and restarted PE. Alternatively, you could probably use the
|
||||
Unlocker utility. After unlocking, I manually deleted everything in the directory.
|
||||
|
||||
Unlocker: http://www.filehippo.com/download_unlocker/ or http://www.emptyloop.com/unlocker/
|
||||
Warning: With Unlocker v1.9.2, you must select "Advanced" then uncheck everything to
|
||||
avoid having some Delta toolbar garbage installed...
|
||||
|
||||
@@ -13,11 +13,12 @@ SUBDIRS = bsatk \
|
||||
nxmhandler \
|
||||
BossDummy \
|
||||
pythonRunner \
|
||||
esptk
|
||||
esptk \
|
||||
loot_cli
|
||||
|
||||
plugins.depends = pythonRunner
|
||||
hookdll.depends = shared
|
||||
organizer.depends = shared uibase plugins
|
||||
organizer.depends = shared uibase plugins loot_cli
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
DESTDIR = outputd
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright (C) 2014 Sebastian Herbord. All rights reserved.
|
||||
|
||||
This file is part of Mod Organizer.
|
||||
|
||||
Mod Organizer is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Mod Organizer is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "aboutdialog.h"
|
||||
#include "ui_aboutdialog.h"
|
||||
#include <utility.h>
|
||||
|
||||
|
||||
AboutDialog::AboutDialog(const QString &version, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::AboutDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_LicenseFiles[LICENSE_LGPL3] = "lgpl-3.0.txt";
|
||||
m_LicenseFiles[LICENSE_GPL3] = "gpl-3.0.txt";
|
||||
m_LicenseFiles[LICENSE_BSD3] = "bsd3.txt";
|
||||
m_LicenseFiles[LICENSE_BOOST] = "boost.txt";
|
||||
m_LicenseFiles[LICENSE_CCBY3] = "by-sa3.txt";
|
||||
m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt";
|
||||
|
||||
addLicense("Qt 4.8.5", LICENSE_LGPL3);
|
||||
addLicense("Qt Json", LICENSE_GPL3);
|
||||
addLicense("Boost Library", LICENSE_BOOST);
|
||||
addLicense("Tango Icon Theme", LICENSE_NONE);
|
||||
addLicense("RRZE Icon Set", LICENSE_CCBY3);
|
||||
addLicense("7-zip", LICENSE_LGPL3);
|
||||
addLicense("ZLib", LICENSE_ZLIB);
|
||||
addLicense("NIF File Format Library", LICENSE_BSD3);
|
||||
addLicense("BOSS (modified)", LICENSE_GPL3);
|
||||
addLicense("Alphanum Algorithm", LICENSE_ZLIB);
|
||||
|
||||
ui->nameLabel->setText(QString("<span style=\"font-size:12pt; font-weight:600;\">%1 %2</span>").arg(ui->nameLabel->text()).arg(version));
|
||||
#ifdef HGID
|
||||
ui->revisionLabel->setText(ui->revisionLabel->text() + " " + HGID);
|
||||
#else
|
||||
ui->revisionLabel->setText(ui->revisionLabel->text() + " unknown");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
AboutDialog::~AboutDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void AboutDialog::addLicense(const QString &name, Licenses license)
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem(name);
|
||||
item->setData(Qt::UserRole, license);
|
||||
ui->creditsList->addItem(item);
|
||||
}
|
||||
|
||||
|
||||
void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem*)
|
||||
{
|
||||
auto iter = m_LicenseFiles.find(current->data(Qt::UserRole).toInt());
|
||||
if (iter != m_LicenseFiles.end()) {
|
||||
QString filePath = qApp->applicationDirPath() + "/license/" + iter->second;
|
||||
QString text = MOBase::readFileText(filePath);
|
||||
ui->licenseText->setText(text);
|
||||
} else {
|
||||
ui->licenseText->setText(tr("No license"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef ABOUTDIALOG_H
|
||||
/*
|
||||
Copyright (C) 2014 Sebastian Herbord. All rights reserved.
|
||||
|
||||
This file is part of Mod Organizer.
|
||||
|
||||
Mod Organizer is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Mod Organizer is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#define ABOUTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidgetItem>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace Ui {
|
||||
class AboutDialog;
|
||||
}
|
||||
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AboutDialog(const QString &version, QWidget *parent = 0);
|
||||
~AboutDialog();
|
||||
|
||||
private:
|
||||
|
||||
enum Licenses {
|
||||
LICENSE_NONE,
|
||||
LICENSE_LGPL3,
|
||||
LICENSE_GPL3,
|
||||
LICENSE_BSD3,
|
||||
LICENSE_BOOST,
|
||||
LICENSE_CCBY3,
|
||||
LICENSE_ZLIB
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void addLicense(const QString &name, Licenses license);
|
||||
|
||||
private slots:
|
||||
void on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
|
||||
private:
|
||||
|
||||
Ui::AboutDialog *ui;
|
||||
|
||||
std::map<int, QString> m_LicenseFiles;
|
||||
|
||||
};
|
||||
|
||||
#endif // ABOUTDIALOG_H
|
||||
@@ -0,0 +1,295 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AboutDialog</class>
|
||||
<widget class="QDialog" name="AboutDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>508</width>
|
||||
<height>335</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="iconLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="resources.qrc">:/MO/gui/mo_icon.ico</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="about">
|
||||
<attribute name="title">
|
||||
<string>About</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string notr="true">Mod Organizer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="revisionLabel">
|
||||
<property name="text">
|
||||
<string>Revision:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string notr="true">Copyright 2011-2014 Sebastian Herbord</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string notr="true"><html><head/><body><p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p><p>See the GNU General Public License for more details.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="software">
|
||||
<attribute name="title">
|
||||
<string>Used Software</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QListWidget" name="creditsList"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="licenseText"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="credits">
|
||||
<attribute name="title">
|
||||
<string>Credits</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Translators</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget_2">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">pndrev (German)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">DaWul (Spanish)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Fiama (Spanish)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Alyndiar (French)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Jlkawaii (French)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Rigoletto (French)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Scythe1912 (Chinese)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">yc0620shen (Chinese)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">miraclefreak (Czech)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">tokcdk (Russian)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Others</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">blacksol</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">DoubleYou</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">deathneko11</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Bridger</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">GSDFan</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Uhuru</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Wolverine2710</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">z929669</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>closeButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AboutDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>460</x>
|
||||
<y>313</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>253</x>
|
||||
<y>167</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
+24
-8
@@ -22,6 +22,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QRegExp>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <boost/assign.hpp>
|
||||
|
||||
|
||||
namespace BBCode {
|
||||
@@ -43,7 +44,6 @@ public:
|
||||
// extract the tag name
|
||||
m_TagNameExp.indexIn(input, 1, QRegExp::CaretAtOffset);
|
||||
QString tagName = m_TagNameExp.cap(0).toLower();
|
||||
//qDebug("tag name %s", tagName.toUtf8().constData());
|
||||
TagMap::iterator tagIter = m_TagMap.find(tagName);
|
||||
if (tagIter != m_TagMap.end()) {
|
||||
// recognized tag
|
||||
@@ -60,7 +60,21 @@ public:
|
||||
length = closeTagPos + closeTag.length();
|
||||
QString temp = input.mid(0, length);
|
||||
if (tagIter->second.first.indexIn(temp) == 0) {
|
||||
return temp.replace(tagIter->second.first, tagIter->second.second);
|
||||
if (tagIter->second.second.isEmpty()) {
|
||||
if (tagName == "color") {
|
||||
QString color = tagIter->second.first.cap(1);
|
||||
QString content = tagIter->second.first.cap(2);
|
||||
auto colIter = m_ColorMap.find(color.toLower());
|
||||
if (colIter != m_ColorMap.end()) {
|
||||
color = colIter->second;
|
||||
}
|
||||
return temp.replace(tagIter->second.first, QString("<font style=\"color: #%1;\">%2</font>").arg(color, content));
|
||||
} else {
|
||||
qWarning("don't know how to deal with tag %s", qPrintable(tagName));
|
||||
}
|
||||
} else {
|
||||
return temp.replace(tagIter->second.first, tagIter->second.second);
|
||||
}
|
||||
} else {
|
||||
// expression doesn't match. either the input string is invalid
|
||||
// or the expression is
|
||||
@@ -96,7 +110,7 @@ private:
|
||||
m_TagMap["size="] = std::make_pair(QRegExp("\\[size=([^\\]]*)\\](.*)\\[/size\\]"),
|
||||
"<font size=\"\\1\">\\2</font>");
|
||||
m_TagMap["color="] = std::make_pair(QRegExp("\\[color=([^\\]]*)\\](.*)\\[/color\\]"),
|
||||
"<font style=\"color: #\\1;\">\\2</font>");
|
||||
"");
|
||||
m_TagMap["font="] = std::make_pair(QRegExp("\\[font=([^\\]]*)\\](.*)\\[/font\\]"),
|
||||
"<font face=\\1>\\2</font>");
|
||||
m_TagMap["center"] = std::make_pair(QRegExp("\\[center\\](.*)\\[/center\\]"),
|
||||
@@ -139,10 +153,6 @@ private:
|
||||
"<a href=\"\\1\">\\1</a>");
|
||||
m_TagMap["url="] = std::make_pair(QRegExp("\\[url=([^\\]]*)\\](.*)\\[/url\\]"),
|
||||
"<a href=\"\\1\">\\2</a>");
|
||||
/* m_TagMap["img"] = std::make_pair(QRegExp("\\[img\\](.*)\\[/img\\]"),
|
||||
"<img src=\"\\1\"/>");
|
||||
m_TagMap["img="] = std::make_pair(QRegExp("\\[img=([^\\]]*)\\](.*)\\[/img\\]"),
|
||||
"<img src=\"\\2\" align=\"\\1\" />");*/
|
||||
m_TagMap["img"] = std::make_pair(QRegExp("\\[img\\](.*)\\[/img\\]"), "");
|
||||
m_TagMap["img="] = std::make_pair(QRegExp("\\[img=([^\\]]*)\\](.*)\\[/img\\]"), "");
|
||||
m_TagMap["email="] = std::make_pair(QRegExp("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"),
|
||||
@@ -150,6 +160,11 @@ private:
|
||||
m_TagMap["youtube"] = std::make_pair(QRegExp("\\[youtube\\](.*)\\[/youtube\\]"),
|
||||
"<a href=\"http://www.youtube.com/v/\\1\">http://www.youtube.com/v/\\1</a>");
|
||||
|
||||
m_ColorMap = boost::assign::map_list_of("red", "FF0000")("green", "00FF00")("blue", "0000FF")
|
||||
("black", "000000")("gray", "7F7F7F")("white", "FFFFFF")
|
||||
("yellow", "FFFF00")("cyan", "00FFFF")("magenta", "FF00FF")
|
||||
("brown", "A52A2A")("orange", "FFCC00");
|
||||
|
||||
// make all patterns non-greedy and case-insensitive
|
||||
for (TagMap::iterator iter = m_TagMap.begin(); iter != m_TagMap.end(); ++iter) {
|
||||
iter->second.first.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
@@ -157,10 +172,11 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
QRegExp m_TagNameExp;
|
||||
TagMap m_TagMap;
|
||||
std::map<QString, QString> m_ColorMap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
|
||||
|
||||
This file is part of Mod Organizer.
|
||||
|
||||
Mod Organizer is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Mod Organizer is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "browserdialog.h"
|
||||
#include "ui_browserdialog.h"
|
||||
|
||||
#include "messagedialog.h"
|
||||
#include "report.h"
|
||||
#include "json.h"
|
||||
#include "persistentcookiejar.h"
|
||||
|
||||
#include <gameinfo.h>
|
||||
|
||||
#include <utility.h>
|
||||
#include <gameinfo.h>
|
||||
#include <QNetworkCookieJar>
|
||||
#include <QNetworkCookie>
|
||||
#include <QMenu>
|
||||
#include <QInputDialog>
|
||||
#include <QWebHistory>
|
||||
#include <QDir>
|
||||
#include <QWebFrame>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
|
||||
|
||||
BrowserDialog::BrowserDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::BrowserDialog)
|
||||
, m_AccessManager(new QNetworkAccessManager)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_AccessManager->setCookieJar(new PersistentCookieJar(
|
||||
QDir::fromNativeSeparators(MOBase::ToQString(MOShared::GameInfo::instance().getCacheDir())) + "/cookies.dat", this));
|
||||
|
||||
Qt::WindowFlags flags = windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint;
|
||||
Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
|
||||
flags = flags & (~helpFlag);
|
||||
setWindowFlags(flags);
|
||||
|
||||
m_Tabs = this->findChild<QTabWidget*>("browserTabWidget");
|
||||
|
||||
connect(m_Tabs, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int)));
|
||||
}
|
||||
|
||||
|
||||
BrowserDialog::~BrowserDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void BrowserDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
// m_AccessManager->showCookies();
|
||||
QDialog::closeEvent(event);
|
||||
}
|
||||
|
||||
void BrowserDialog::initTab(BrowserView *newView)
|
||||
{
|
||||
newView->page()->setNetworkAccessManager(m_AccessManager);
|
||||
newView->page()->setForwardUnsupportedContent(true);
|
||||
|
||||
connect(newView, SIGNAL(loadProgress(int)), this, SLOT(progress(int)));
|
||||
connect(newView, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged(QString)));
|
||||
connect(newView, SIGNAL(initTab(BrowserView*)), this, SLOT(initTab(BrowserView*)));
|
||||
connect(newView, SIGNAL(startFind()), this, SLOT(startSearch()));
|
||||
connect(newView, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl)));
|
||||
connect(newView, SIGNAL(openUrlInNewTab(QUrl)), this, SLOT(openInNewTab(QUrl)));
|
||||
connect(newView->page(), SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest)));
|
||||
connect(newView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedContent(QNetworkReply*)));
|
||||
|
||||
ui->backBtn->setEnabled(false);
|
||||
ui->fwdBtn->setEnabled(false);
|
||||
m_Tabs->addTab(newView, tr("new"));
|
||||
newView->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
|
||||
newView->settings()->setAttribute(QWebSettings::AutoLoadImages, true);
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::openInNewTab(const QUrl &url)
|
||||
{
|
||||
BrowserView *newView = new BrowserView(this);
|
||||
initTab(newView);
|
||||
newView->setUrl(url);
|
||||
}
|
||||
|
||||
|
||||
BrowserView *BrowserDialog::getCurrentView()
|
||||
{
|
||||
return qobject_cast<BrowserView*>(m_Tabs->currentWidget());
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::urlChanged(const QUrl&)
|
||||
{
|
||||
BrowserView *currentView = getCurrentView();
|
||||
if (currentView != NULL) {
|
||||
ui->backBtn->setEnabled(currentView->history()->canGoBack());
|
||||
ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::openUrl(const QUrl &url)
|
||||
{
|
||||
if (isHidden()) {
|
||||
show();
|
||||
}
|
||||
openInNewTab(url);
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::maximizeWidth()
|
||||
{
|
||||
int viewportWidth = getCurrentView()->page()->viewportSize().width();
|
||||
int frameWidth = width() - viewportWidth;
|
||||
|
||||
int contentWidth = getCurrentView()->page()->mainFrame()->contentsSize().width();
|
||||
|
||||
QDesktopWidget screen;
|
||||
int currentScreen = screen.screenNumber(this);
|
||||
int screenWidth = screen.screenGeometry(currentScreen).size().width();
|
||||
|
||||
int targetWidth = std::min<int>(std::max<int>(viewportWidth, contentWidth) + frameWidth, screenWidth);
|
||||
this->resize(targetWidth, height());
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::progress(int value)
|
||||
{
|
||||
ui->loadProgress->setValue(value);
|
||||
if (value == 100) {
|
||||
maximizeWidth();
|
||||
ui->loadProgress->setVisible(false);
|
||||
} else {
|
||||
ui->loadProgress->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::titleChanged(const QString &title)
|
||||
{
|
||||
BrowserView *view = qobject_cast<BrowserView*>(sender());
|
||||
for (int i = 0; i < m_Tabs->count(); ++i) {
|
||||
if (m_Tabs->widget(i) == view) {
|
||||
m_Tabs->setTabText(i, title.mid(0, 15));
|
||||
m_Tabs->setTabToolTip(i, title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString BrowserDialog::guessFileName(const QString &url)
|
||||
{
|
||||
QRegExp uploadsExp(QString("http://.+/uploads/([^/]+)$"));
|
||||
if (uploadsExp.indexIn(url) != -1) {
|
||||
// these seem to be premium downloads
|
||||
return uploadsExp.cap(1);
|
||||
}
|
||||
|
||||
QRegExp filesExp(QString("http://.+\\?file=([^&]+)"));
|
||||
if (filesExp.indexIn(url) != -1) {
|
||||
// a regular manual download?
|
||||
return filesExp.cap(1);
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void BrowserDialog::unsupportedContent(QNetworkReply *reply)
|
||||
{
|
||||
try {
|
||||
QWebPage *page = qobject_cast<QWebPage*>(sender());
|
||||
if (page == NULL) {
|
||||
qCritical("sender not a page");
|
||||
return;
|
||||
}
|
||||
BrowserView *view = qobject_cast<BrowserView*>(page->view());
|
||||
if (view == NULL) {
|
||||
qCritical("no view?");
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("unsupported: %s - %s", view->url().toString().toUtf8().constData(), reply->url().toString().toUtf8().constData());
|
||||
emit requestDownload(view->url(), reply);
|
||||
} catch (const std::exception &e) {
|
||||
if (isVisible()) {
|
||||
MessageDialog::showMessage(tr("failed to start download"), this);
|
||||
}
|
||||
qCritical("exception downloading unsupported content: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::downloadRequested(const QNetworkRequest &request)
|
||||
{
|
||||
qCritical("download request %s ignored", request.url().toString().toUtf8().constData());
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::tabCloseRequested(int index)
|
||||
{
|
||||
if (m_Tabs->count() == 1) {
|
||||
this->close();
|
||||
} else {
|
||||
m_Tabs->widget(index)->deleteLater();
|
||||
m_Tabs->removeTab(index);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserDialog::on_backBtn_clicked()
|
||||
{
|
||||
BrowserView *currentView = getCurrentView();
|
||||
if (currentView != NULL) {
|
||||
currentView->back();
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserDialog::on_fwdBtn_clicked()
|
||||
{
|
||||
BrowserView *currentView = getCurrentView();
|
||||
if (currentView != NULL) {
|
||||
currentView->forward();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::startSearch()
|
||||
{
|
||||
ui->searchEdit->setFocus();
|
||||
}
|
||||
|
||||
|
||||
void BrowserDialog::on_searchEdit_returnPressed()
|
||||
{
|
||||
BrowserView *currentView = getCurrentView();
|
||||
if (currentView != NULL) {
|
||||
currentView->findText(ui->searchEdit->text(), QWebPage::FindWrapsAroundDocument);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserDialog::on_browserTabWidget_currentChanged(QWidget *current)
|
||||
{
|
||||
BrowserView *currentView = qobject_cast<BrowserView*>(current);
|
||||
if (currentView != NULL) {
|
||||
ui->backBtn->setEnabled(currentView->history()->canGoBack());
|
||||
ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserDialog::on_refreshBtn_clicked()
|
||||
{
|
||||
getCurrentView()->reload();
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
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_browserTabWidget_currentChanged(QWidget *arg1);
|
||||
|
||||
void on_refreshBtn_clicked();
|
||||
|
||||
private:
|
||||
|
||||
QString guessFileName(const QString &url);
|
||||
|
||||
BrowserView *getCurrentView();
|
||||
|
||||
void maximizeWidth();
|
||||
|
||||
private:
|
||||
|
||||
Ui::BrowserDialog *ui;
|
||||
|
||||
QNetworkAccessManager *m_AccessManager;
|
||||
|
||||
QTabWidget *m_Tabs;
|
||||
|
||||
};
|
||||
|
||||
#endif // BROWSERDIALOG_H
|
||||
@@ -0,0 +1,289 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BrowserDialog</class>
|
||||
<widget class="QDialog" name="BrowserDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1008</width>
|
||||
<height>750</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Some Page</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="toolBar" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>226</red>
|
||||
<green>226</green>
|
||||
<blue>226</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Button">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>106</red>
|
||||
<green>106</green>
|
||||
<blue>106</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="ButtonText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>199</red>
|
||||
<green>199</green>
|
||||
<blue>199</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Base">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>81</red>
|
||||
<green>81</green>
|
||||
<blue>81</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>226</red>
|
||||
<green>226</green>
|
||||
<blue>226</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Button">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>106</red>
|
||||
<green>106</green>
|
||||
<blue>106</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="ButtonText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>199</red>
|
||||
<green>199</green>
|
||||
<blue>199</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Base">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>81</red>
|
||||
<green>81</green>
|
||||
<blue>81</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>120</red>
|
||||
<green>120</green>
|
||||
<blue>120</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Button">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>106</red>
|
||||
<green>106</green>
|
||||
<blue>106</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="ButtonText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>120</red>
|
||||
<green>120</green>
|
||||
<blue>120</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Base">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>81</red>
|
||||
<green>81</green>
|
||||
<blue>81</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
<colorrole role="Window">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>81</red>
|
||||
<green>81</green>
|
||||
<blue>81</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="backBtn">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/MO/gui/previous</normaloff>:/MO/gui/previous</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="fwdBtn">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/MO/gui/next</normaloff>:/MO/gui/next</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="refreshBtn">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/MO/gui/refresh</normaloff>:/MO/gui/refresh</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Search</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="searchEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="browserTabWidget">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::DefaultContextMenu</enum>
|
||||
</property>
|
||||
<property name="tabsClosable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="loadProgress">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +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
|
||||
@@ -103,6 +103,7 @@ CategoryFactory &CategoryFactory::instance()
|
||||
void CategoryFactory::reset()
|
||||
{
|
||||
m_Categories.clear();
|
||||
m_IDMap.clear();
|
||||
addCategory(0, "None", MakeVector<int>(2, 28, 87), 0);
|
||||
}
|
||||
|
||||
|
||||
+12
-7
@@ -34,9 +34,10 @@ DownloadList::DownloadList(DownloadManager *manager, QObject *parent)
|
||||
|
||||
int DownloadList::rowCount(const QModelIndex&) const
|
||||
{
|
||||
return m_Manager->numTotalDownloads();
|
||||
return m_Manager->numTotalDownloads() + m_Manager->numPendingDownloads();
|
||||
}
|
||||
|
||||
|
||||
int DownloadList::columnCount(const QModelIndex&) const
|
||||
{
|
||||
return 3;
|
||||
@@ -75,14 +76,18 @@ QVariant DownloadList::data(const QModelIndex &index, int role) const
|
||||
if (role == Qt::DisplayRole) {
|
||||
return index.row();
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
QString text = m_Manager->getFileName(index.row()) + "\n";
|
||||
if (m_Manager->isInfoIncomplete(index.row())) {
|
||||
text += tr("Information missing, please select \"Query Info\" from the context menu to re-retrieve.");
|
||||
if (index.row() < m_Manager->numTotalDownloads()) {
|
||||
QString text = m_Manager->getFileName(index.row()) + "\n";
|
||||
if (m_Manager->isInfoIncomplete(index.row())) {
|
||||
text += tr("Information missing, please select \"Query Info\" from the context menu to re-retrieve.");
|
||||
} else {
|
||||
const MOBase::ModRepositoryFileInfo *info = m_Manager->getFileInfo(index.row());
|
||||
return QString("%1 (ID %2) %3<br><span>%4</span>").arg(info->modName).arg(m_Manager->getModID(index.row())).arg(info->version.canonicalString()).arg(info->description);
|
||||
}
|
||||
return text;
|
||||
} else {
|
||||
NexusInfo info = m_Manager->getNexusInfo(index.row());
|
||||
text += QString("%1 (ID %2) %3").arg(info.m_ModName).arg(m_Manager->getModID(index.row())).arg(info.m_Version);
|
||||
return tr("pending download");
|
||||
}
|
||||
return text;
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
@@ -37,13 +37,16 @@ bool DownloadListSortProxy::lessThan(const QModelIndex &left,
|
||||
{
|
||||
int leftIndex = sourceModel()->data(left).toInt();
|
||||
int rightIndex = sourceModel()->data(right).toInt();
|
||||
|
||||
if (left.column() == DownloadList::COL_NAME) {
|
||||
return m_Manager->getFileName(leftIndex).compare(m_Manager->getFileName(rightIndex), Qt::CaseInsensitive) < 0;
|
||||
} else if (left.column() == DownloadList::COL_FILETIME) {
|
||||
return m_Manager->getFileTime(leftIndex) < m_Manager->getFileTime(rightIndex);
|
||||
} else if (left.column() == DownloadList::COL_STATUS) {
|
||||
return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
|
||||
if (leftIndex < m_Manager->numTotalDownloads()) {
|
||||
if (left.column() == DownloadList::COL_NAME) {
|
||||
return m_Manager->getFileName(leftIndex).compare(m_Manager->getFileName(rightIndex), Qt::CaseInsensitive) < 0;
|
||||
} else if (left.column() == DownloadList::COL_FILETIME) {
|
||||
return m_Manager->getFileTime(leftIndex) < m_Manager->getFileTime(rightIndex);
|
||||
} else if (left.column() == DownloadList::COL_STATUS) {
|
||||
return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
|
||||
} else {
|
||||
return leftIndex < rightIndex;
|
||||
}
|
||||
} else {
|
||||
return leftIndex < rightIndex;
|
||||
}
|
||||
@@ -54,6 +57,9 @@ bool DownloadListSortProxy::filterAcceptsRow(int source_row, const QModelIndex&)
|
||||
{
|
||||
if (m_CurrentFilter.length() == 0) {
|
||||
return true;
|
||||
} else if (source_row < m_Manager->numTotalDownloads()) {
|
||||
return m_Manager->getFileName(source_row).contains(m_CurrentFilter, Qt::CaseInsensitive);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return m_Manager->getFileName(source_row).contains(m_CurrentFilter, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
+110
-82
@@ -40,8 +40,13 @@ DownloadListWidget::~DownloadListWidget()
|
||||
}
|
||||
|
||||
|
||||
DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager, QTreeView *view, QObject *parent)
|
||||
: QItemDelegate(parent), m_Manager(manager), m_ItemWidget(new DownloadListWidget), m_ContextRow(0), m_View(view)
|
||||
DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent)
|
||||
: QItemDelegate(parent)
|
||||
, m_Manager(manager)
|
||||
, m_MetaDisplay(metaDisplay)
|
||||
, m_ItemWidget(new DownloadListWidget)
|
||||
, m_ContextRow(0)
|
||||
, m_View(view)
|
||||
{
|
||||
m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
|
||||
m_SizeLabel = m_ItemWidget->findChild<QLabel*>("sizeLabel");
|
||||
@@ -82,6 +87,83 @@ void DownloadListWidgetDelegate::drawCache(QPainter *painter, const QStyleOption
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const
|
||||
{
|
||||
std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
|
||||
m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
|
||||
m_SizeLabel->setText("???");
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_InstallLabel->setText(tr("Pending"));
|
||||
m_Progress->setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetDelegate::paintRegularDownload(int downloadIndex) const
|
||||
{
|
||||
QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex);
|
||||
if (name.length() > 53) {
|
||||
name.truncate(50);
|
||||
name.append("...");
|
||||
}
|
||||
m_NameLabel->setText(name);
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1024));
|
||||
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkRed);
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 1"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 2"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
|
||||
// of DownloadListWidgetDelegate?
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::lightGray);
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
|
||||
}
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\" /> " + m_NameLabel->text());
|
||||
}
|
||||
} else {
|
||||
m_InstallLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
try {
|
||||
@@ -95,67 +177,10 @@ void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionView
|
||||
|
||||
int downloadIndex = index.data().toInt();
|
||||
|
||||
QString name = m_Manager->getFileName(downloadIndex);
|
||||
if (name.length() > 53) {
|
||||
name.truncate(50);
|
||||
name.append("...");
|
||||
}
|
||||
m_NameLabel->setText(name);
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1024));
|
||||
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkRed);
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 1"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_InstallLabel->setText(tr("Fetching Info 2"));
|
||||
m_Progress->setVisible(false);
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
QPalette labelPalette;
|
||||
m_InstallLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
|
||||
// of DownloadListWidgetDelegate?
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::lightGray);
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
|
||||
#else
|
||||
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8));
|
||||
#endif
|
||||
labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
|
||||
}
|
||||
m_InstallLabel->setPalette(labelPalette);
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\" /> " + m_NameLabel->text());
|
||||
}
|
||||
if (downloadIndex >= m_Manager->numTotalDownloads()) {
|
||||
paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
|
||||
} else {
|
||||
m_InstallLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
|
||||
paintRegularDownload(downloadIndex);
|
||||
}
|
||||
|
||||
#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly")
|
||||
@@ -280,29 +305,32 @@ bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton) {
|
||||
QMenu menu(m_View);
|
||||
bool hidden = false;
|
||||
m_ContextRow = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index).row();
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
|
||||
bool hidden = m_Manager->isHidden(m_ContextRow);
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextRow)) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
if (m_ContextRow < m_Manager->numTotalDownloads()) {
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
|
||||
hidden = m_Manager->isHidden(m_ContextRow);
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextRow)) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addSeparator();
|
||||
}
|
||||
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
|
||||
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
|
||||
if (!hidden) {
|
||||
|
||||
@@ -54,12 +54,15 @@ class DownloadListWidgetDelegate : public QItemDelegate
|
||||
|
||||
public:
|
||||
|
||||
DownloadListWidgetDelegate(DownloadManager *manager, QTreeView *view, QObject *parent = 0);
|
||||
DownloadListWidgetDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent = 0);
|
||||
~DownloadListWidgetDelegate();
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
void paintPendingDownload(int downloadIndex) const;
|
||||
void paintRegularDownload(int downloadIndex) const;
|
||||
|
||||
signals:
|
||||
|
||||
void installDownload(int index);
|
||||
@@ -102,6 +105,8 @@ private:
|
||||
DownloadListWidget *m_ItemWidget;
|
||||
DownloadManager *m_Manager;
|
||||
|
||||
bool m_MetaDisplay;
|
||||
|
||||
QLabel *m_NameLabel;
|
||||
QLabel *m_SizeLabel;
|
||||
QProgressBar *m_Progress;
|
||||
|
||||
@@ -40,8 +40,12 @@ DownloadListWidgetCompact::~DownloadListWidgetCompact()
|
||||
}
|
||||
|
||||
|
||||
DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadManager *manager, QTreeView *view, QObject *parent)
|
||||
: QItemDelegate(parent), m_Manager(manager), m_ItemWidget(new DownloadListWidgetCompact), m_View(view)
|
||||
DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent)
|
||||
: QItemDelegate(parent)
|
||||
, m_Manager(manager)
|
||||
, m_MetaDisplay(metaDisplay)
|
||||
, m_ItemWidget(new DownloadListWidgetCompact)
|
||||
, m_View(view)
|
||||
{
|
||||
m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
|
||||
m_SizeLabel = m_ItemWidget->findChild<QLabel*>("sizeLabel");
|
||||
@@ -82,6 +86,66 @@ void DownloadListWidgetCompactDelegate::drawCache(QPainter *painter, const QStyl
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const
|
||||
{
|
||||
std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
|
||||
m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
|
||||
if (m_SizeLabel != NULL) {
|
||||
m_SizeLabel->setText("???");
|
||||
}
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_DoneLabel->setText(tr("Pending"));
|
||||
m_Progress->setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex) const
|
||||
{
|
||||
QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex);
|
||||
if (name.length() > 53) {
|
||||
name.truncate(50);
|
||||
name.append("...");
|
||||
}
|
||||
m_NameLabel->setText(name);
|
||||
|
||||
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
|
||||
|
||||
if ((m_SizeLabel != NULL) && (state >= DownloadManager::STATE_READY)) {
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576));
|
||||
}
|
||||
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
m_DoneLabel->setText(tr("Paused"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Link);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 1"));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 2"));
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
m_DoneLabel->setText(tr("Installed"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Mid);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
m_DoneLabel->setText(tr("Uninstalled"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Dark);
|
||||
} else {
|
||||
m_DoneLabel->setText(tr("Done"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::WindowText);
|
||||
}
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\"/> " + m_NameLabel->text());
|
||||
}
|
||||
} else {
|
||||
m_DoneLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
#pragma message("This is quite costy - room for optimization?")
|
||||
@@ -100,49 +164,10 @@ void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOpt
|
||||
}
|
||||
|
||||
int downloadIndex = index.data().toInt();
|
||||
|
||||
QString name = m_Manager->getFileName(downloadIndex);
|
||||
if (name.length() > 53) {
|
||||
name.truncate(50);
|
||||
name.append("...");
|
||||
}
|
||||
m_NameLabel->setText(name);
|
||||
|
||||
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
|
||||
|
||||
if ((m_SizeLabel != NULL) && (state >= DownloadManager::STATE_READY)) {
|
||||
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576));
|
||||
}
|
||||
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
m_DoneLabel->setText(tr("Paused"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Link);
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 1"));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 2"));
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
m_DoneLabel->setText(tr("Installed"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Mid);
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
m_DoneLabel->setText(tr("Uninstalled"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Dark);
|
||||
} else {
|
||||
m_DoneLabel->setText(tr("Done"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::WindowText);
|
||||
}
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\"/> " + m_NameLabel->text());
|
||||
}
|
||||
if (downloadIndex >= m_Manager->numTotalDownloads()) {
|
||||
paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
|
||||
} else {
|
||||
m_DoneLabel->setVisible(false);
|
||||
m_Progress->setVisible(true);
|
||||
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
|
||||
paintRegularDownload(downloadIndex);
|
||||
}
|
||||
|
||||
#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly")
|
||||
@@ -268,29 +293,32 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton) {
|
||||
QMenu menu;
|
||||
bool hidden = false;
|
||||
m_ContextIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
|
||||
bool hidden = m_Manager->isHidden(m_ContextIndex.row());
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
if (m_ContextIndex.row() < m_Manager->numTotalDownloads()) {
|
||||
DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
|
||||
hidden = m_Manager->isHidden(m_ContextIndex.row());
|
||||
if (state >= DownloadManager::STATE_READY) {
|
||||
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
|
||||
if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
|
||||
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
|
||||
if (hidden) {
|
||||
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
|
||||
} else {
|
||||
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
|
||||
}
|
||||
} else if (state == DownloadManager::STATE_DOWNLOADING){
|
||||
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
|
||||
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
|
||||
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
|
||||
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addSeparator();
|
||||
}
|
||||
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
|
||||
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
|
||||
if (!hidden) {
|
||||
|
||||
@@ -54,7 +54,7 @@ class DownloadListWidgetCompactDelegate : public QItemDelegate
|
||||
|
||||
public:
|
||||
|
||||
DownloadListWidgetCompactDelegate(DownloadManager *manager, QTreeView *view, QObject *parent = 0);
|
||||
DownloadListWidgetCompactDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent = 0);
|
||||
~DownloadListWidgetCompactDelegate();
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
@@ -78,6 +78,8 @@ protected:
|
||||
private:
|
||||
|
||||
void drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const;
|
||||
void paintPendingDownload(int downloadIndex) const;
|
||||
void paintRegularDownload(int downloadIndex) const;
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -101,6 +103,8 @@ private:
|
||||
DownloadListWidgetCompact *m_ItemWidget;
|
||||
DownloadManager *m_Manager;
|
||||
|
||||
bool m_MetaDisplay;
|
||||
|
||||
QLabel *m_NameLabel;
|
||||
QLabel *m_SizeLabel;
|
||||
QProgressBar *m_Progress;
|
||||
|
||||
+243
-94
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