Commit 467def69 authored by Eike Ziller's avatar Eike Ziller

Merge remote-tracking branch 'origin/4.0'

Change-Id: I3f28f1f53cf2b2228928fbd7accf25d87bb40243
parents 61411f94 50b1bf62
......@@ -37,20 +37,18 @@
\title Analyzing Code
You can use the code analysis tools in the \uicontrol Analyze mode. To
switch to \uicontrol Analyze mode, select \uicontrol Analyze in the mode
You can use the code analysis tools in the \uicontrol Debug mode. To
switch to \uicontrol Debug mode, select \uicontrol Debug in the mode
selector, or select the \uicontrol {Analyze} menu and then select a tool.
When you are in the \uicontrol Analyze mode, you can switch between tools by
When you are in the \uicontrol Debug mode, you can switch between tools by
selecting them in the menu on the toolbar.
\image qtcreator-analyze-menu.png "Analyze mode menu"
You can drag and drop the views in the \uicontrol Analyze mode to new
You can drag and drop the views in the \uicontrol Debug mode to new
positions on the screen. The size and position of views are saved for future
sessions. Select \uicontrol {Window > Views > Reset to Default Layout} to
reset the views to their original sizes and positions.
You can use the following code analysis tools in the \uicontrol Analyze
You can use the following code analysis tools in the \uicontrol Debug
mode:
\list
......
......@@ -74,8 +74,8 @@
\uicontrol Analyze > \uicontrol {Clang Static Analyzer} on the menu bar. The
Clang Static Analyzer starts automatically.
However, if you select \uicontrol Analyze in the mode selector to open the
\uicontrol Analyze mode and then select \uicontrol {Clang Static Analyzer},
However, if you select \uicontrol Debug in the mode selector to open the
\uicontrol Debug mode and then select \uicontrol {Clang Static Analyzer},
you must start the Clang Static Analyzer by selecting the
\inlineimage qtcreator-analyze-start-button.png
(\uicontrol Start) button.
......
......@@ -195,12 +195,9 @@
\row
\li Switch to \uicontrol Projects mode
\li Ctrl+5
\row
\li Switch to \uicontrol Analyze mode
\li Ctrl+6
\row
\li Switch to \uicontrol Help mode
\li Ctrl+7
\li Ctrl+6
\row
\li Toggle \uicontrol{Issues} pane
\li Alt+1 (Cmd+1 on OS X)
......
......@@ -49,8 +49,7 @@
\li \uicontrol Design mode \key Ctrl+3
\li \uicontrol Debug mode \key Ctrl+4
\li \uicontrol Projects mode \key Ctrl+5
\li \uicontrol Analyze mode \key Ctrl+6
\li \uicontrol Help mode \key Ctrl+7
\li \uicontrol Help mode \key Ctrl+6
\endlist
......
......@@ -93,15 +93,13 @@
UI files.
\li \uicontrol{\l{Debugging}{Debug}} mode for inspecting the state of your
application while debugging.
application while debugging and for using code analysis tools
to detect memory leaks and profile C++ or QML code.
\li \uicontrol{\l{Specifying Build Settings}{Projects}} mode for configuring
project building and execution. This mode is available when a
project is open.
\li \uicontrol{\l{Analyzing Code}{Analyze}} mode for using code analysis tools
to detect memory leaks and profile C++ or QML code.
\li \uicontrol{\l{Getting Help}{Help}} mode for viewing Qt documentation.
\endlist
......@@ -375,9 +373,6 @@
\list
\li \uicontrol Analyzer - Errors encountered while running the
\l{Analyzing Code}{Valgrind code analysis tools}.
\li \uicontrol {Build System} - Errors and warnings encountered during a
build.
......@@ -387,6 +382,9 @@
\li \uicontrol{Debug Information} - Lists debug information packages that might
be missing.
\li \uicontrol Debugger - Errors encountered while running the
\l{Analyzing Code}{Valgrind code analysis tools}.
\li \uicontrol{Debugger Runtime} - Errors encountered when starting \QC. For
example, information about missing DLLs.
......
......@@ -119,7 +119,11 @@
\li Qt Quick Controls Application
Create a Qt Quick application using Qt Quick Controls
Create a Qt Quick application using
\l{http://doc.qt.io/qt-5/qtquickcontrols-index.html}
{Qt Quick Controls} or
\l{http://doc.qt.io/qt-5/qtlabscontrols-index.html}
{Qt Labs Controls}
\li Qt Canvas 3D Application
......
......@@ -84,6 +84,12 @@
creating classic desktop-style user interfaces using Qt Quick 2.1. You can
use the Qt Quick Controls Styles to customize Qt Quick Controls.
Since Qt 5.6, Qt Labs Controls provide lightweight QML types for creating
performant user interfaces for embedded and mobile devices. These controls
achieve improved efficiency by employing a simplified styling architecture
when compared to Qt Quick Controls, on which the module is based. These
types work in conjunction with Qt Quick and Qt Quick Layouts.
Some ready-made controls, such as a gauge, dial, status indicator, and
tumbler, are provided by the \l {Qt Quick Extras} module.
......
......@@ -50,8 +50,13 @@
a QQuickView. You can build the application and deploy it to desktop,
embedded, and mobile target platforms.
\li \uicontrol {Qt Quick Controls Application} is like
\uicontrol {Qt Quick Application}, but using Qt Quick Controls.
\li \uicontrol {Qt Quick Controls Application} and
\uicontrol {Qt Labs Controls Application} are like
\uicontrol {Qt Quick Application}, but using
\l{http://doc.qt.io/qt-5/qtquickcontrols-index.html}
{Qt Quick Controls} or
\l{http://doc.qt.io/qt-5/qtlabscontrols-index.html}
{Qt Labs Controls}
\li \uicontrol {Qt Canvas 3D Application} creates a Qt Quick application
that imports the Qt Canvas 3D module and, optionally, includes
......@@ -80,8 +85,9 @@
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol Application > \uicontrol {Qt Quick Application} or
\uicontrol {Qt Quick Controls Application} > \uicontrol Choose.
\uicontrol Application > \uicontrol {Qt Quick Application},
\uicontrol {Qt Quick Controls Application}, or
\uicontrol {Qt Labs Controls Application} > \uicontrol Choose.
\li In the \uicontrol {Minimal required Qt version} field, select the Qt
version to develop with. The Qt version determines the Qt Quick
......
......@@ -51,6 +51,12 @@
creating classic desktop-style user interfaces using Qt Quick 2.1. You can
use the Qt Quick Controls Styles to customize Qt Quick Controls.
Since Qt 5.6, Qt Labs Controls provide lightweight QML types for creating
performant user interfaces for embedded and mobile devices. These controls
achieve improved efficiency by employing a simplified styling architecture
when compared to Qt Quick Controls, on which the module is based. These
types work in conjunction with Qt Quick and Qt Quick Layouts.
\section1 Adding Components to Screens
\list 1
......
......@@ -1106,6 +1106,8 @@ class DumperBase:
typeName = str(value.type)
(dereferencable, pointerValue) = self.pointerInfo(value)
self.putAddress(pointerValue)
self.putOriginalAddress(value)
if not dereferencable:
# Failure to dereference a pointer should at least
# show the value of a pointer.
......
......@@ -168,13 +168,15 @@ class PlainDumper:
self.typeCache = {}
def __call__(self, d, value):
printer = self.printer.invoke(value)
printer = self.printer.gen_printer(value)
lister = getattr(printer, "children", None)
children = [] if lister is None else list(lister())
d.putType(self.printer.name)
val = printer.to_string()
if isinstance(val, str):
d.putValue(val)
elif sys.version_info[0] <= 2 and isinstance(val, unicode):
d.putValue(val)
else: # Assuming LazyString
d.putCharArrayHelper(val.address, val.length, val.type.sizeof)
......
......@@ -814,14 +814,8 @@ QObject *ObjectNodeInstance::parent() const
QObject *ObjectNodeInstance::parentObject(QObject *object)
{
QQuickItem *quickItem = qobject_cast<QQuickItem*>(object);
if (quickItem && quickItem->parentItem()) {
//QQuickRootItem is used by Window and we want to return the Window as parent
if (strcmp(quickItem->metaObject()->className(), "QQuickRootItem"))
return object->parent();
if (quickItem && quickItem->parentItem())
return quickItem->parentItem();
}
return object->parent();
}
......
......@@ -131,7 +131,7 @@ Debugger_LogWindow_LogTime=ffbf0303
Debugger_WatchItem_ValueNormal=text
Debugger_WatchItem_ValueInvalid=textDisabled
Debugger_WatchItem_ValueChanged=ffbf0303
Debugger_WatchItem_ValueChanged=ffff6666
Debugger_Breakpoint_TextMarkColor=ffff4040
......
......@@ -253,7 +253,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
}
// pop up arrow next to icon
if (!icon().isNull()) {
if (isEnabled() && !icon().isNull()) {
QStyleOption opt;
opt.initFrom(this);
opt.rect = rect().adjusted(rect().width() - 16, 0, -8, 0);
......
......@@ -70,9 +70,13 @@ namespace Internal {
static char outputPaneSettingsKeyC[] = "OutputPaneVisibility";
static char outputPaneIdKeyC[] = "id";
static char outputPaneVisibleKeyC[] = "visible";
static const int numberAreaWidth = 19;
static const int buttonBorderWidth = 3;
static int numberAreaWidth()
{
return creatorTheme()->widgetStyle() == Theme::StyleDefault ? 19 : 15;
}
////
// OutputPaneManager
////
......@@ -185,7 +189,8 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) :
m_buttonsWidget = new QWidget;
m_buttonsWidget->setLayout(new QHBoxLayout);
m_buttonsWidget->layout()->setContentsMargins(5,0,0,0);
m_buttonsWidget->layout()->setSpacing(4);
m_buttonsWidget->layout()->setSpacing(
creatorTheme()->widgetStyle() == Theme::StyleDefault ? 4 : 9);
}
OutputPaneManager::~OutputPaneManager()
......@@ -634,11 +639,12 @@ OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text,
auto updateSlot = static_cast<void (QWidget::*)()>(&QWidget::update);
connect(m_flashTimer, &QTimeLine::valueChanged, this, updateSlot);
connect(m_flashTimer, &QTimeLine::finished, this, updateSlot);
updateToolTip();
}
void OutputPaneToggleButton::updateToolTip()
{
Q_ASSERT(m_action);
QTC_ASSERT(m_action, return);
setToolTip(m_action->toolTip());
}
......@@ -649,7 +655,7 @@ QSize OutputPaneToggleButton::sizeHint() const
QSize s = fontMetrics().size(Qt::TextSingleLine, m_text);
// Expand to account for border image
s.rwidth() += numberAreaWidth + 1 + buttonBorderWidth + buttonBorderWidth;
s.rwidth() += numberAreaWidth() + 1 + buttonBorderWidth + buttonBorderWidth;
if (!m_badgeNumberLabel.text().isNull())
s.rwidth() += m_badgeNumberLabel.sizeHint().width() + 1;
......@@ -684,7 +690,7 @@ void OutputPaneToggleButton::paintEvent(QPaintEvent*)
else
image = hovered ? &panelButtonHover : &panelButton;
if (image)
StyleHelper::drawCornerImage(*image, &p, rect(), numberAreaWidth, buttonBorderWidth, buttonBorderWidth, buttonBorderWidth);
StyleHelper::drawCornerImage(*image, &p, rect(), numberAreaWidth(), buttonBorderWidth, buttonBorderWidth, buttonBorderWidth);
} else {
Theme::Color c = Theme::BackgroundColorDark;
......@@ -702,16 +708,16 @@ void OutputPaneToggleButton::paintEvent(QPaintEvent*)
QColor c = creatorTheme()->color(Theme::OutputPaneButtonFlashColor);
c.setAlpha (m_flashTimer->currentFrame());
QRect r = (creatorTheme()->widgetStyle() == Theme::StyleFlat)
? rect() : rect().adjusted(numberAreaWidth, 1, -1, -1);
? rect() : rect().adjusted(numberAreaWidth(), 1, -1, -1);
p.fillRect(r, c);
}
p.setFont(font());
p.setPen(creatorTheme()->color(Theme::OutputPaneToggleButtonTextColorChecked));
p.drawText((numberAreaWidth - numberWidth) / 2, baseLine, m_number);
p.drawText((numberAreaWidth() - numberWidth) / 2, baseLine, m_number);
if (!isChecked())
p.setPen(creatorTheme()->color(Theme::OutputPaneToggleButtonTextColorUnchecked));
int leftPart = numberAreaWidth + buttonBorderWidth;
int leftPart = numberAreaWidth() + buttonBorderWidth;
int labelWidth = 0;
if (!m_badgeNumberLabel.text().isEmpty()) {
const QSize labelSize = m_badgeNumberLabel.sizeHint();
......@@ -764,7 +770,7 @@ OutputPaneManageButton::OutputPaneManageButton()
QSize OutputPaneManageButton::sizeHint() const
{
ensurePolished();
return QSize(numberAreaWidth, QApplication::globalStrut().height());
return QSize(numberAreaWidth(), QApplication::globalStrut().height());
}
void OutputPaneManageButton::paintEvent(QPaintEvent*)
......
This diff is collapsed.
......@@ -15,13 +15,13 @@ QtcPlugin {
}
files: [
"exportdialog.cpp",
"exportdialog.h",
"imageview.cpp",
"imageview.h",
"imageviewer.cpp",
"imageviewer.h",
"imageviewer.qrc",
"imagevieweractionhandler.cpp",
"imagevieweractionhandler.h",
"imageviewerconstants.h",
"imageviewerfactory.cpp",
"imageviewerfactory.h",
......
......@@ -29,9 +29,11 @@
#include "ioutputparser.h"
#include "osparser.h"
#include "projectexplorerconstants.h"
#include "projectexplorericons.h"
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/icon.h>
#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
......@@ -83,7 +85,7 @@ public:
m_id = Id::fromString(QUuid::createUuid().toString());
m_unexpandedDisplayName = QCoreApplication::translate("ProjectExplorer::Kit", "Unnamed");
m_iconPath = FileName::fromLatin1(":///DESKTOP///");
m_iconPath = FileName::fromLatin1(Constants::DESKTOP_DEVICE_ICON);
m_macroExpander.setDisplayName(tr("Kit"));
m_macroExpander.setAccumulating(true);
......@@ -373,8 +375,12 @@ QIcon Kit::icon(const FileName &path)
{
if (path.isEmpty())
return QIcon();
if (path == FileName::fromLatin1(":///DESKTOP///"))
return qApp->style()->standardIcon(QStyle::SP_ComputerIcon);
if (path == FileName::fromLatin1(Constants::DESKTOP_DEVICE_ICON))
return creatorTheme()->flag(Theme::FlatSideBarIcons)
? Icon::combinedIcon({Icons::DESKTOP_DEVICE.icon(),
Icons::DESKTOP_DEVICE_SMALL.icon()})
: QApplication::style()->standardIcon(QStyle::SP_ComputerIcon);
QFileInfo fi = path.toFileInfo();
if (fi.isFile() && fi.isReadable())
......
......@@ -30,6 +30,7 @@
#include "kitfeatureprovider.h"
#include "kitmanagerconfigwidget.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "task.h"
#include <coreplugin/icore.h>
......@@ -207,7 +208,7 @@ void KitManager::restoreKits()
defaultKit->setUnexpandedDisplayName(tr("Desktop"));
defaultKit->setSdkProvided(false);
defaultKit->setAutoDetected(false);
defaultKit->setIconPath(FileName::fromLatin1(":///DESKTOP///"));
defaultKit->setIconPath(FileName::fromLatin1(ProjectExplorer::Constants::DESKTOP_DEVICE_ICON));
defaultKit->setup();
......
......@@ -28,6 +28,7 @@
#include "kitconfigwidget.h"
#include "kitmanager.h"
#include "target.h"
#include "projectexplorericons.h"
#include <utils/algorithm.h>
#include <utils/styledbar.h>
......@@ -664,7 +665,9 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi
setContentsMargins(QMargins(0, 1, 1, 8));
setWindowFlags(Qt::Popup);
targetSelectorAction->setIcon(style()->standardIcon(QStyle::SP_ComputerIcon));
targetSelectorAction->setIcon(creatorTheme()->flag(Theme::FlatSideBarIcons)
? Icons::DESKTOP_DEVICE.icon()
: style()->standardIcon(QStyle::SP_ComputerIcon));
targetSelectorAction->setProperty("titledAction", true);
m_kitAreaWidget = new KitAreaWidget(this);
......@@ -1500,7 +1503,9 @@ void MiniProjectTargetSelector::updateActionAndSummary()
QString buildConfig;
QString deployConfig;
QString runConfig;
QIcon targetIcon = style()->standardIcon(QStyle::SP_ComputerIcon);
QIcon targetIcon = creatorTheme()->flag(Theme::FlatSideBarIcons)
? Icons::DESKTOP_DEVICE.icon()
: style()->standardIcon(QStyle::SP_ComputerIcon);
Project *project = SessionManager::startupProject();
if (project) {
......
......@@ -795,7 +795,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
// session menu
ActionContainer *msession = ActionManager::createMenu(Constants::M_SESSION);
msession->menu()->setTitle(tr("Sessions"));
msession->menu()->setTitle(tr("S&essions"));
msession->setOnAllDisabledBehavior(ActionContainer::Show);
mfile->addMenu(msession, Core::Constants::G_FILE_OPEN);
dd->m_sessionMenu = msession->menu();
......
......@@ -69,5 +69,9 @@
<file>images/targetchangebutton@2x.png</file>
<file>images/targetchangebutton2.png</file>
<file>images/targetchangebutton2@2x.png</file>
<file>images/desktopdevice.png</file>
<file>images/desktopdevice@2x.png</file>
<file>images/desktopdevicesmall.png</file>
<file>images/desktopdevicesmall@2x.png</file>
</qresource>
</RCC>
......@@ -223,6 +223,7 @@ const char DEFAULT_WORKING_DIR_ALTERNATE[] = "%{sourceDir}";
// Desktop Device related ids:
const char DESKTOP_DEVICE_ID[] = "Desktop Device";
const char DESKTOP_DEVICE_TYPE[] = "Desktop";
const char DESKTOP_DEVICE_ICON[] = ":///DESKTOP///";
const int DESKTOP_PORT_START = 30000;
const int DESKTOP_PORT_END = 31000;
......
......@@ -67,6 +67,11 @@ const Utils::Icon BUILDSTEP_DISABLE({
const Utils::Icon BUILDSTEP_REMOVE({
{QLatin1String(":/projectexplorer/images/buildstepremove.png"), Utils::Theme::PanelTextColorDark}}, Utils::Icon::Tint);
const Utils::Icon DESKTOP_DEVICE({
{QLatin1String(":/projectexplorer/images/desktopdevice.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon DESKTOP_DEVICE_SMALL({
{QLatin1String(":/projectexplorer/images/desktopdevicesmall.png"), Utils::Theme::PanelTextColorDark}}, Utils::Icon::Tint);
const Utils::Icon RUN_SMALL({
{QLatin1String(":/projectexplorer/images/run_small.png"), Utils::Theme::IconsRunColor}});
const Utils::Icon STOP_SMALL({
......
......@@ -41,7 +41,7 @@ public:
QString commandLineArguments;
QString workingDirectory;
Utils::Environment environment;
ApplicationLauncher::Mode runMode;
ApplicationLauncher::Mode runMode = ApplicationLauncher::Gui;
};
PROJECTEXPLORER_EXPORT bool operator==(const StandardRunnable &r1, const StandardRunnable &r2);
......
......@@ -2096,7 +2096,7 @@ QVariantMap UserFileVersion11Upgrader::upgrade(const QVariantMap &map)
tmpKit->setValue("PE.Profile.DeviceType", QString::fromLatin1("Desktop"));
tmpKit->setValue("PE.Profile.Device", QString());
} else if (oldTargetId == QLatin1String("RemoteLinux.EmbeddedLinuxTarget")) {
tmpKit->setIconPath(FileName::fromLatin1(":///DESKTOP///"));
tmpKit->setIconPath(FileName::fromLatin1(Constants::DESKTOP_DEVICE_ICON));
tmpKit->setValue("PE.Profile.DeviceType", QString::fromLatin1("GenericLinuxOsType"));
tmpKit->setValue("PE.Profile.Device", QString());
} else if (oldTargetId == QLatin1String("Qt4ProjectManager.Target.HarmattanDeviceTarget")) {
......@@ -2120,7 +2120,7 @@ QVariantMap UserFileVersion11Upgrader::upgrade(const QVariantMap &map)
tmpKit->setValue("PE.Profile.DeviceType", QString::fromLatin1("Desktop"));
tmpKit->setValue("PE.Profile.Device", QString::fromLatin1("Desktop Device"));
} else {
tmpKit->setIconPath(FileName::fromLatin1(":///DESKTOP///"));
tmpKit->setIconPath(FileName::fromLatin1(Constants::DESKTOP_DEVICE_ICON));
tmpKit->setValue("PE.Profile.DeviceType", QString::fromLatin1("Desktop"));
tmpKit->setValue("PE.Profile.Device", QString::fromLatin1("Desktop Device"));
}
......
......@@ -133,9 +133,9 @@ static QColor checkColorText(const QString &str)
// looks backwards through a string for the opening brace of a function
static int findOpeningBrace(const QString &s, int startIndex)
{
QTC_ASSERT(startIndex >= 0 && startIndex < s.length(), return -1);
QTC_ASSERT(startIndex >= 0 && startIndex <= s.length(), return -1);
int index = startIndex;
int index = startIndex == s.length() ? startIndex - 1 : startIndex;
while (index > 0) {
const QChar c = s[index];
if (c == QLatin1Char('(') || c == QLatin1Char('{'))
......@@ -149,9 +149,9 @@ static int findOpeningBrace(const QString &s, int startIndex)
static int findClosingBrace(const QString &s, int startIndex)
{
QTC_ASSERT(startIndex >= 0 && startIndex < s.length(), return -1);
QTC_ASSERT(startIndex >= 0 && startIndex <= s.length(), return -1);
int index = startIndex;
int index = startIndex == s.length() ? startIndex - 1 : startIndex;
const int len = s.length();
while (index < len) {
const QChar c = s[index];
......@@ -167,9 +167,9 @@ static int findClosingBrace(const QString &s, int startIndex)
// returns the index of the first character of the func, or negative if not valid
static int findFuncStart(const QString &s, int startIndex)
{
QTC_ASSERT(startIndex >= 0 && startIndex < s.length(), return -1);
QTC_ASSERT(startIndex >= 0 && startIndex <= s.length(), return -1);
int index = startIndex;
int index = startIndex == s.length() ? startIndex - 1 : startIndex;
while (index >= 0) {
const QChar c = s[index];
if (!c.isLetterOrNumber()) {
......
......@@ -4173,5 +4173,36 @@
id="polygon5757-3-4" />
</g>
</g>
<g
transform="translate(6.5,297)"
id="src/plugins/projectexplorer/images/desktopdevice">
<rect
style="display:inline;fill:#ffffff;fill-opacity:1"
x="499.5"
y="50"
width="32"
height="32"
id="rect5759-5-9-0" />
<path
d="m 525.5,54 -20,0 c -1.1,0 -2,0.9 -2,2 l 0,14 c 0,1.1 0.9,2 2,2 l 20,0 c 1.1,0 2,-0.9 2,-2 l 0,-14 c 0,-1.1 -0.9,-2 -2,-2 l 0,0 z"
id="path5514" />
<path
d="m 521,78 -3.5,-7 -4,0 -3.5,7 z"
id="polygon5516"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
d="m 525.5,56 0,14 -20,0 0,-14 20,0"
id="path4825"
style="fill:#b3b3b3" />
</g>
<use
x="0"
y="0"
xlink:href="#src/plugins/projectexplorer/images/desktopdevice"
id="src/plugins/projectexplorer/images/desktopdevicesmall"
transform="matrix(0.5,0,0,0.5,285,189.5)"
width="100%"
height="100%" />
</g>
</svg>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment