mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
637d4089e2
* Following the principle of least surprise, color tends to be more commonly used in APIs and graphics code even outside the USA.
699 lines
24 KiB
C++
699 lines
24 KiB
C++
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2016-2017 Baldur Karlsson
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#include <QDebug>
|
|
#include <QFileDialog>
|
|
#include <QMessageBox>
|
|
#include <QProcess>
|
|
#include <QSemaphore>
|
|
#include <QSortFilterProxyModel>
|
|
#include "renderdoc_replay.h"
|
|
|
|
template <typename T>
|
|
inline T AlignUp(T x, T a)
|
|
{
|
|
return (x + (a - 1)) & (~(a - 1));
|
|
}
|
|
|
|
#ifndef ARRAY_COUNT
|
|
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
|
|
#endif
|
|
|
|
// total hack, expose the same basic interface as on renderdoc side.
|
|
// Eventually we want to move the code in the main project into header-only
|
|
// and .inl implementations for at least the public API, so it can be compiled
|
|
// directly without duplication
|
|
|
|
struct ToStr
|
|
{
|
|
static std::string Get(const ResourceId &el)
|
|
{
|
|
// super inefficient to convert to qstr then std::string then back to qstr
|
|
// but this is just a temporary measure
|
|
uint64_t num = 0;
|
|
memcpy(&num, &el, sizeof(num));
|
|
return QString::number(num).toStdString();
|
|
}
|
|
|
|
static std::string Get(const ReplayStatus &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case ReplayStatus::Succeeded: return "Success";
|
|
case ReplayStatus::UnknownError: return "Unknown error";
|
|
case ReplayStatus::InternalError: return "Internal error";
|
|
case ReplayStatus::FileNotFound: return "File not found";
|
|
case ReplayStatus::InjectionFailed: return "RenderDoc injection failed";
|
|
case ReplayStatus::IncompatibleProcess: return "Process is incompatible";
|
|
case ReplayStatus::NetworkIOFailed: return "Network I/O operation failed";
|
|
case ReplayStatus::NetworkRemoteBusy: return "Remote side of network connection is busy";
|
|
case ReplayStatus::NetworkVersionMismatch: return "Version mismatch between network clients";
|
|
case ReplayStatus::FileIOFailed: return "File I/O failed";
|
|
case ReplayStatus::FileIncompatibleVersion: return "File of incompatible version";
|
|
case ReplayStatus::FileCorrupted: return "File corrupted";
|
|
case ReplayStatus::APIUnsupported: return "API unsupported";
|
|
case ReplayStatus::APIInitFailed: return "API initialisation failed";
|
|
case ReplayStatus::APIIncompatibleVersion: return "API incompatible version";
|
|
case ReplayStatus::APIHardwareUnsupported: return "API hardware unsupported";
|
|
default: break;
|
|
}
|
|
return "Invalid error code";
|
|
}
|
|
|
|
static std::string Get(const CompType &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case CompType::Typeless: return "Typeless";
|
|
case CompType::Float: return "Float";
|
|
case CompType::UNorm: return "UNorm";
|
|
case CompType::SNorm: return "SNorm";
|
|
case CompType::UInt: return "UInt";
|
|
case CompType::SInt: return "SInt";
|
|
case CompType::UScaled: return "UScaled";
|
|
case CompType::SScaled: return "SScaled";
|
|
case CompType::Depth: return "Depth/Stencil";
|
|
case CompType::Double: return "Double";
|
|
default: break;
|
|
}
|
|
return "Invalid component type";
|
|
}
|
|
|
|
static std::string Get(const FileType &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case FileType::DDS: return "DDS";
|
|
case FileType::PNG: return "PNG";
|
|
case FileType::JPG: return "JPG";
|
|
case FileType::BMP: return "BMP";
|
|
case FileType::TGA: return "TGA";
|
|
case FileType::HDR: return "HDR";
|
|
case FileType::EXR: return "EXR";
|
|
default: break;
|
|
}
|
|
return "Invalid file type";
|
|
}
|
|
|
|
static std::string Get(const AlphaMapping &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case AlphaMapping::Discard: return "Discard";
|
|
case AlphaMapping::BlendToColor: return "Blend to Color";
|
|
case AlphaMapping::BlendToCheckerboard: return "Blend to Checkerboard";
|
|
case AlphaMapping::Preserve: return "Preserve";
|
|
default: break;
|
|
}
|
|
return "Invalid mapping";
|
|
}
|
|
|
|
static std::string Get(const EnvMod &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case EnvMod::Set: return "Set";
|
|
case EnvMod::Append: return "Append";
|
|
case EnvMod::Prepend: return "Prepend";
|
|
default: break;
|
|
}
|
|
return "Invalid modification";
|
|
}
|
|
|
|
static std::string Get(const EnvSep &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case EnvSep::Platform: return "Platform style";
|
|
case EnvSep::SemiColon: return "Semi-colon (;)";
|
|
case EnvSep::Colon: return "Colon (:)";
|
|
case EnvSep::NoSep: return "No Separator";
|
|
default: break;
|
|
}
|
|
return "Invalid separator";
|
|
}
|
|
|
|
static std::string Get(const Topology &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case Topology::Unknown: return "Unknown";
|
|
case Topology::PointList: return "Point List";
|
|
case Topology::LineList: return "Line List";
|
|
case Topology::LineStrip: return "Line Strip";
|
|
case Topology::LineLoop: return "Line Loop";
|
|
case Topology::TriangleList: return "Triangle List";
|
|
case Topology::TriangleStrip: return "Triangle Strip";
|
|
case Topology::TriangleFan: return "Triangle Fan";
|
|
case Topology::LineList_Adj: return "Line List with Adjacency";
|
|
case Topology::LineStrip_Adj: return "Line Strip with Adjacency";
|
|
case Topology::TriangleList_Adj: return "Triangle List with Adjacency";
|
|
case Topology::TriangleStrip_Adj: return "Triangle Strip with Adjacency";
|
|
case Topology::PatchList_1CPs:
|
|
case Topology::PatchList_2CPs:
|
|
case Topology::PatchList_3CPs:
|
|
case Topology::PatchList_4CPs:
|
|
case Topology::PatchList_5CPs:
|
|
case Topology::PatchList_6CPs:
|
|
case Topology::PatchList_7CPs:
|
|
case Topology::PatchList_8CPs:
|
|
case Topology::PatchList_9CPs:
|
|
case Topology::PatchList_10CPs:
|
|
case Topology::PatchList_11CPs:
|
|
case Topology::PatchList_12CPs:
|
|
case Topology::PatchList_13CPs:
|
|
case Topology::PatchList_14CPs:
|
|
case Topology::PatchList_15CPs:
|
|
case Topology::PatchList_16CPs:
|
|
case Topology::PatchList_17CPs:
|
|
case Topology::PatchList_18CPs:
|
|
case Topology::PatchList_19CPs:
|
|
case Topology::PatchList_20CPs:
|
|
case Topology::PatchList_21CPs:
|
|
case Topology::PatchList_22CPs:
|
|
case Topology::PatchList_23CPs:
|
|
case Topology::PatchList_24CPs:
|
|
case Topology::PatchList_25CPs:
|
|
case Topology::PatchList_26CPs:
|
|
case Topology::PatchList_27CPs:
|
|
case Topology::PatchList_28CPs:
|
|
case Topology::PatchList_29CPs:
|
|
case Topology::PatchList_30CPs:
|
|
case Topology::PatchList_31CPs:
|
|
case Topology::PatchList_32CPs: return "Patch List";
|
|
default: break;
|
|
}
|
|
return "Unknown topology";
|
|
}
|
|
|
|
static std::string Get(const FillMode &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case FillMode::Solid: return "Solid";
|
|
case FillMode::Wireframe: return "Wireframe";
|
|
case FillMode::Point: return "Point";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const CullMode &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case CullMode::NoCull: return "None";
|
|
case CullMode::Front: return "Front";
|
|
case CullMode::Back: return "Back";
|
|
case CullMode::FrontAndBack: return "Front & Back";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const TextureDim &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case TextureDim::Unknown: return "Unknown";
|
|
case TextureDim::Buffer: return "Buffer";
|
|
case TextureDim::Texture1D: return "Texture 1D";
|
|
case TextureDim::Texture1DArray: return "Texture 1D Array";
|
|
case TextureDim::Texture2D: return "Texture 2D";
|
|
case TextureDim::TextureRect: return "Texture Rect";
|
|
case TextureDim::Texture2DArray: return "Texture 2D Array";
|
|
case TextureDim::Texture2DMS: return "Texture 2D MS";
|
|
case TextureDim::Texture2DMSArray: return "Texture 2D MS Array";
|
|
case TextureDim::Texture3D: return "Texture 3D";
|
|
case TextureDim::TextureCube: return "Texture Cube";
|
|
case TextureDim::TextureCubeArray: return "Texture Cube Array";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const ShaderBuiltin &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case ShaderBuiltin::Undefined: return "Undefined";
|
|
case ShaderBuiltin::Position: return "Position";
|
|
case ShaderBuiltin::PointSize: return "Point Size";
|
|
case ShaderBuiltin::ClipDistance: return "Clip Distance";
|
|
case ShaderBuiltin::CullDistance: return "Cull Distance";
|
|
case ShaderBuiltin::RTIndex: return "RT Index";
|
|
case ShaderBuiltin::ViewportIndex: return "Viewport Index";
|
|
case ShaderBuiltin::VertexIndex: return "Vertex Index";
|
|
case ShaderBuiltin::PrimitiveIndex: return "Primitive Index";
|
|
case ShaderBuiltin::InstanceIndex: return "Instance Index";
|
|
case ShaderBuiltin::DispatchSize: return "Dispatch Size";
|
|
case ShaderBuiltin::DispatchThreadIndex: return "Dispatch Thread Index";
|
|
case ShaderBuiltin::GroupIndex: return "Group Index";
|
|
case ShaderBuiltin::GroupFlatIndex: return "Group Flat Index";
|
|
case ShaderBuiltin::GroupThreadIndex: return "Group Thread Index";
|
|
case ShaderBuiltin::GSInstanceIndex: return "GS Instance Index";
|
|
case ShaderBuiltin::OutputControlPointIndex: return "Output Control Point Index";
|
|
case ShaderBuiltin::DomainLocation: return "Domain Location";
|
|
case ShaderBuiltin::IsFrontFace: return "Is FrontFace";
|
|
case ShaderBuiltin::MSAACoverage: return "MSAA Coverage";
|
|
case ShaderBuiltin::MSAASamplePosition: return "MSAA Sample Position";
|
|
case ShaderBuiltin::MSAASampleIndex: return "MSAA Sample Index";
|
|
case ShaderBuiltin::PatchNumVertices: return "Patch NumVertices";
|
|
case ShaderBuiltin::OuterTessFactor: return "Outer TessFactor";
|
|
case ShaderBuiltin::InsideTessFactor: return "Inside TessFactor";
|
|
case ShaderBuiltin::ColorOutput: return "Color Output";
|
|
case ShaderBuiltin::DepthOutput: return "Depth Output";
|
|
case ShaderBuiltin::DepthOutputGreaterEqual: return "Depth Output (GEqual)";
|
|
case ShaderBuiltin::DepthOutputLessEqual: return "Depth Output (LEqual)";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const BindType &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case BindType::ConstantBuffer: return "Constants";
|
|
case BindType::Sampler: return "Sampler";
|
|
case BindType::ImageSampler: return "Image&Sampler";
|
|
case BindType::ReadOnlyImage: return "Image";
|
|
case BindType::ReadWriteImage: return "RW Image";
|
|
case BindType::ReadOnlyTBuffer: return "TexBuffer";
|
|
case BindType::ReadWriteTBuffer: return "RW TexBuffer";
|
|
case BindType::ReadOnlyBuffer: return "Buffer";
|
|
case BindType::ReadWriteBuffer: return "RW Buffer";
|
|
case BindType::InputAttachment: return "Input";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const MessageSource &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case MessageSource::API: return "API";
|
|
case MessageSource::RedundantAPIUse: return "Redundant API Use";
|
|
case MessageSource::IncorrectAPIUse: return "Incorrect API Use";
|
|
case MessageSource::GeneralPerformance: return "General Performance";
|
|
case MessageSource::GCNPerformance: return "GCN Performance";
|
|
case MessageSource::RuntimeWarning: return "Runtime Warning";
|
|
case MessageSource::UnsupportedConfiguration: return "Unsupported Configuration";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const MessageSeverity &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case MessageSeverity::High: return "High";
|
|
case MessageSeverity::Medium: return "Medium";
|
|
case MessageSeverity::Low: return "Low";
|
|
case MessageSeverity::Info: return "Info";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const MessageCategory &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case MessageCategory::Application_Defined: return "Application Defined";
|
|
case MessageCategory::Miscellaneous: return "Miscellaneous";
|
|
case MessageCategory::Initialization: return "Initialization";
|
|
case MessageCategory::Cleanup: return "Cleanup";
|
|
case MessageCategory::Compilation: return "Compilation";
|
|
case MessageCategory::State_Creation: return "State Creation";
|
|
case MessageCategory::State_Setting: return "State Setting";
|
|
case MessageCategory::State_Getting: return "State Getting";
|
|
case MessageCategory::Resource_Manipulation: return "Resource Manipulation";
|
|
case MessageCategory::Execution: return "Execution";
|
|
case MessageCategory::Shaders: return "Shaders";
|
|
case MessageCategory::Deprecated: return "Deprecated";
|
|
case MessageCategory::Undefined: return "Undefined";
|
|
case MessageCategory::Portability: return "Portability";
|
|
case MessageCategory::Performance: return "Performance";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const TextureSwizzle &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case TextureSwizzle::Red: return "R";
|
|
case TextureSwizzle::Green: return "G";
|
|
case TextureSwizzle::Blue: return "B";
|
|
case TextureSwizzle::Alpha: return "A";
|
|
case TextureSwizzle::Zero: return "0";
|
|
case TextureSwizzle::One: return "1";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
static std::string Get(const VarType &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
case VarType::Float: return "float";
|
|
case VarType::Int: return "int";
|
|
case VarType::UInt: return "uint";
|
|
case VarType::Double: return "double";
|
|
case VarType::Unknown: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
};
|
|
|
|
// this will be here to lighten the burden of converting from std::string to
|
|
// QString everywhere.
|
|
|
|
template <typename T>
|
|
inline QString ToQStr(const T &el)
|
|
{
|
|
return QString::fromStdString(ToStr::Get(el));
|
|
}
|
|
|
|
// overload for rdctype::str
|
|
template <>
|
|
inline QString ToQStr(const rdctype::str &el)
|
|
{
|
|
return QString::fromUtf8(el.elems, el.count);
|
|
}
|
|
|
|
// overload for a couple of things that need to know the pipeline type when converting
|
|
QString ToQStr(const ResourceUsage usage, const GraphicsAPI apitype);
|
|
|
|
// overload for a couple of things that need to know the pipeline type when converting
|
|
QString ToQStr(const ShaderStage stage, const GraphicsAPI apitype);
|
|
|
|
struct FormatElement
|
|
{
|
|
FormatElement();
|
|
FormatElement(const QString &Name, int buf, uint offs, bool perInst, int instRate, bool rowMat,
|
|
uint matDim, ResourceFormat f, bool hexDisplay);
|
|
|
|
static QList<FormatElement> ParseFormatString(const QString &formatString, uint64_t maxLen,
|
|
bool tightPacking, QString &errors);
|
|
|
|
QVariantList GetVariants(const byte *&data, const byte *end) const;
|
|
ShaderVariable GetShaderVar(const byte *&data, const byte *end) const;
|
|
|
|
QString ElementString(const QVariant &var);
|
|
|
|
uint32_t byteSize() const;
|
|
|
|
QString name;
|
|
int buffer;
|
|
uint32_t offset;
|
|
bool perinstance;
|
|
int instancerate;
|
|
bool rowmajor;
|
|
uint32_t matrixdim;
|
|
ResourceFormat format;
|
|
bool hex;
|
|
ShaderBuiltin systemValue;
|
|
};
|
|
|
|
QString TypeString(const ShaderVariable &v);
|
|
QString RowString(const ShaderVariable &v, uint32_t row, VarType type = VarType::Unknown);
|
|
QString VarString(const ShaderVariable &v);
|
|
QString RowTypeString(const ShaderVariable &v);
|
|
|
|
QString TypeString(const SigParameter &sig);
|
|
QString D3DSemanticString(const SigParameter &sig);
|
|
QString GetComponentString(byte mask);
|
|
|
|
struct Formatter
|
|
{
|
|
static void setParams(int minFigures, int maxFigures, int expNegCutoff, int expPosCutoff);
|
|
|
|
static QString Format(double f, bool hex = false);
|
|
static QString Format(uint64_t u, bool hex = false)
|
|
{
|
|
return QString("%1").arg(u, hex ? 16 : 0, hex ? 16 : 10, QChar('0'));
|
|
}
|
|
static QString Format(uint32_t u, bool hex = false)
|
|
{
|
|
return QString("%1").arg(u, hex ? 8 : 0, hex ? 16 : 10, QChar('0'));
|
|
}
|
|
static QString Format(uint16_t u, bool hex = false)
|
|
{
|
|
return QString("%1").arg(u, hex ? 4 : 0, hex ? 16 : 10, QChar('0'));
|
|
}
|
|
static QString Format(int32_t i, bool hex = false) { return QString::number(i); }
|
|
private:
|
|
static int m_minFigures, m_maxFigures, m_expNegCutoff, m_expPosCutoff;
|
|
static double m_expNegValue, m_expPosValue;
|
|
};
|
|
|
|
bool SaveToJSON(QVariantMap &data, QIODevice &f, const char *magicIdentifier, uint32_t magicVersion);
|
|
bool LoadFromJSON(QVariantMap &data, QIODevice &f, const char *magicIdentifier,
|
|
uint32_t magicVersion);
|
|
|
|
// implementation of QOverload, to avoid depending on 5.7.
|
|
// From: http://stackoverflow.com/a/16795664/4070143
|
|
template <typename... Args>
|
|
struct OverloadedSlot
|
|
{
|
|
template <typename C, typename R>
|
|
static constexpr auto of(R (C::*pmf)(Args...)) -> decltype(pmf)
|
|
{
|
|
return pmf;
|
|
}
|
|
};
|
|
|
|
// Utility class for invoking a lambda on the GUI thread.
|
|
// This is supported by QTimer::singleShot on Qt 5.4 but it's probably
|
|
// wise not to require a higher version that necessary.
|
|
#include <functional>
|
|
|
|
class GUIInvoke : public QObject
|
|
{
|
|
private:
|
|
Q_OBJECT
|
|
GUIInvoke(const std::function<void()> &f) : func(f) {}
|
|
GUIInvoke() {}
|
|
std::function<void()> func;
|
|
|
|
static int methodIndex;
|
|
|
|
public:
|
|
static void init();
|
|
static void call(const std::function<void()> &f);
|
|
static void blockcall(const std::function<void()> &f);
|
|
|
|
protected slots:
|
|
void doInvoke()
|
|
{
|
|
func();
|
|
deleteLater();
|
|
}
|
|
};
|
|
|
|
// Utility class for calling a lambda on a new thread.
|
|
#include <QThread>
|
|
|
|
class LambdaThread : public QObject
|
|
{
|
|
private:
|
|
Q_OBJECT
|
|
|
|
std::function<void()> m_func;
|
|
QThread *m_Thread;
|
|
QSemaphore completed;
|
|
bool m_SelfDelete = false;
|
|
|
|
public slots:
|
|
void process()
|
|
{
|
|
m_func();
|
|
m_Thread->quit();
|
|
m_Thread = NULL;
|
|
if(m_SelfDelete)
|
|
deleteLater();
|
|
completed.acquire();
|
|
}
|
|
|
|
void selfDelete(bool d) { m_SelfDelete = d; }
|
|
public:
|
|
explicit LambdaThread(std::function<void()> f)
|
|
{
|
|
completed.release();
|
|
m_Thread = new QThread();
|
|
m_func = f;
|
|
moveToThread(m_Thread);
|
|
QObject::connect(m_Thread, &QThread::started, this, &LambdaThread::process);
|
|
QObject::connect(m_Thread, &QThread::finished, m_Thread, &QThread::deleteLater);
|
|
}
|
|
|
|
void start(QThread::Priority prio = QThread::InheritPriority) { m_Thread->start(prio); }
|
|
bool isRunning() { return completed.available(); }
|
|
bool wait(unsigned long time = ULONG_MAX)
|
|
{
|
|
if(m_Thread)
|
|
return m_Thread->wait(time);
|
|
return true;
|
|
}
|
|
|
|
bool isCurrentThread() { return QThread::currentThread() == m_Thread; }
|
|
};
|
|
|
|
class RDProcess : public QProcess
|
|
{
|
|
public:
|
|
RDProcess(QObject *parent = NULL) : QProcess(parent) {}
|
|
void detach() { setProcessState(QProcess::NotRunning); }
|
|
};
|
|
|
|
class QFileFilterModel : public QSortFilterProxyModel
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit QFileFilterModel(QObject *parent = Q_NULLPTR) : QSortFilterProxyModel(parent) {}
|
|
void setRequirePermissions(QDir::Filters mask) { m_requireMask = mask; }
|
|
void setExcludePermissions(QDir::Filters mask) { m_excludeMask = mask; }
|
|
protected:
|
|
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
|
|
|
private:
|
|
QDir::Filters m_requireMask, m_excludeMask;
|
|
};
|
|
|
|
class QMenu;
|
|
|
|
// helper for doing a manual blocking invoke of a dialog
|
|
struct RDDialog
|
|
{
|
|
static const QMessageBox::StandardButtons YesNoCancel;
|
|
|
|
static void show(QMenu *menu, QPoint pos);
|
|
static int show(QDialog *dialog);
|
|
static QMessageBox::StandardButton messageBox(
|
|
QMessageBox::Icon, QWidget *parent, const QString &title, const QString &text,
|
|
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
|
|
|
static QMessageBox::StandardButton information(
|
|
QWidget *parent, const QString &title, const QString &text,
|
|
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton)
|
|
{
|
|
return messageBox(QMessageBox::Information, parent, title, text, buttons, defaultButton);
|
|
}
|
|
|
|
static QMessageBox::StandardButton question(
|
|
QWidget *parent, const QString &title, const QString &text,
|
|
QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons(QMessageBox::Yes |
|
|
QMessageBox::No),
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton)
|
|
{
|
|
return messageBox(QMessageBox::Question, parent, title, text, buttons, defaultButton);
|
|
}
|
|
|
|
static QMessageBox::StandardButton warning(
|
|
QWidget *parent, const QString &title, const QString &text,
|
|
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton)
|
|
{
|
|
return messageBox(QMessageBox::Warning, parent, title, text, buttons, defaultButton);
|
|
}
|
|
|
|
static QMessageBox::StandardButton critical(
|
|
QWidget *parent, const QString &title, const QString &text,
|
|
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton)
|
|
{
|
|
return messageBox(QMessageBox::Critical, parent, title, text, buttons, defaultButton);
|
|
}
|
|
|
|
static QString getExistingDirectory(QWidget *parent = NULL, const QString &caption = QString(),
|
|
const QString &dir = QString(),
|
|
QFileDialog::Options options = QFileDialog::ShowDirsOnly);
|
|
|
|
static QString getOpenFileName(QWidget *parent = NULL, const QString &caption = QString(),
|
|
const QString &dir = QString(), const QString &filter = QString(),
|
|
QString *selectedFilter = NULL,
|
|
QFileDialog::Options options = QFileDialog::Options());
|
|
|
|
static QString getExecutableFileName(QWidget *parent = NULL, const QString &caption = QString(),
|
|
const QString &dir = QString(),
|
|
QFileDialog::Options options = QFileDialog::Options());
|
|
|
|
static QString getSaveFileName(QWidget *parent = NULL, const QString &caption = QString(),
|
|
const QString &dir = QString(), const QString &filter = QString(),
|
|
QString *selectedFilter = NULL,
|
|
QFileDialog::Options options = QFileDialog::Options());
|
|
};
|
|
|
|
// useful delegate for enforcing a given size
|
|
#include <QItemDelegate>
|
|
|
|
class SizeDelegate : public QItemDelegate
|
|
{
|
|
private:
|
|
Q_OBJECT
|
|
|
|
QSize m_Size;
|
|
|
|
public:
|
|
SizeDelegate(QSize size) : m_Size(size) {}
|
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
{
|
|
return m_Size;
|
|
}
|
|
};
|
|
|
|
class QGridLayout;
|
|
|
|
void addGridLines(QGridLayout *grid);
|
|
|
|
class QTreeWidgetItem;
|
|
|
|
QTreeWidgetItem *makeTreeNode(const std::initializer_list<QVariant> &values);
|
|
QTreeWidgetItem *makeTreeNode(const QVariantList &values);
|
|
void deleteChildren(QTreeWidgetItem *item);
|
|
|
|
class QProgressDialog;
|
|
|
|
typedef std::function<float()> ProgressUpdateMethod;
|
|
typedef std::function<bool()> ProgressFinishedMethod;
|
|
|
|
QStringList ParseArgsList(const QString &args);
|
|
bool RunProcessAsAdmin(const QString &fullExecutablePath, const QStringList ¶ms,
|
|
std::function<void()> finishedCallback = std::function<void()>());
|
|
|
|
void ShowProgressDialog(QWidget *window, const QString &labelText, ProgressFinishedMethod finished,
|
|
ProgressUpdateMethod update = ProgressUpdateMethod());
|
|
|
|
QString GetSystemUsername();
|