Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
236 KB
Referenced Files
None
Subscribers
None
This document is not UTF8. It was detected as JIS and converted to UTF8 for display.
diff --git a/dialogs/areadialog.cpp b/dialogs/areadialog.cpp
index 5e4ee48..346abc0 100644
--- a/dialogs/areadialog.cpp
+++ b/dialogs/areadialog.cpp
@@ -1,587 +1,585 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
******
*
* Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann <lucag@student.ethz.ch>
* released under the GNU LGPL <http://www.gnu.org/licenses/old-licenses/library.txt>
*
*/
#include "areadialog.h"
#include "../tools/os.h"
#include "../tools/screenshot.h"
#include "../tools/screenshotmanager.h"
-#include <QPainter>
-#include <QMouseEvent>
#include <QApplication>
#include <QDesktopWidget>
-#include <QToolTip>
+#include <QHBoxLayout>
+#include <QMouseEvent>
+#include <QPainter>
#include <QPushButton>
#include <QSettings>
-#include <QHBoxLayout>
#include <QTimer>
+#include <QToolTip>
#include <QDebug>
AreaDialog::AreaDialog(Screenshot *screenshot) :
QDialog(0), mScreenshot(screenshot), mMouseDown(false), mMouseMagnifier(false),
mNewSelection(false), mHandleSize(10), mMouseOverHandle(0), mIdleTimer(),
mShowHelp(true), mGrabbing(false), mOverlayAlpha(1), mAutoclose(false),
mTLHandle(0, 0, mHandleSize, mHandleSize), mTRHandle(0, 0, mHandleSize, mHandleSize),
mBLHandle(0, 0, mHandleSize, mHandleSize), mBRHandle(0, 0, mHandleSize, mHandleSize),
mLHandle(0, 0, mHandleSize, mHandleSize), mTHandle(0, 0, mHandleSize, mHandleSize),
mRHandle(0, 0, mHandleSize, mHandleSize), mBHandle(0, 0, mHandleSize, mHandleSize)
{
mHandles << &mTLHandle << &mTRHandle << &mBLHandle << &mBRHandle
<< &mLHandle << &mTHandle << &mRHandle << &mBHandle;
mMouseOverHandle = 0;
setMouseTracking(true);
setWindowTitle(tr("Lightscreen Area Mode"));
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
setCursor(Qt::CrossCursor);
connect(&mIdleTimer, SIGNAL(timeout()), this, SLOT(displayHelp()));
mIdleTimer.start(2000);
mAutoclose = ScreenshotManager::instance()->settings()->value("options/areaAutoclose").toBool();
if (mAutoclose)
return; // Avoid creating the accept widget if it's not going to get used.
// Creating accept widget:
mAcceptWidget = new QWidget(this);
mAcceptWidget->resize(110, 60);
mAcceptWidget->setWindowOpacity(0.4);
mAcceptWidget->setGraphicsEffect(os::shadow(QColor(50, 50, 50, 255), 8));
mAcceptWidget->setStyleSheet("QWidget { background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(140, 140, 140, 230), stop:1 rgba(80, 80, 80, 230)); padding: 6px 10px; border: 1px solid rgba(0, 0, 0, 200); border-radius: 8px; } QPushButton { background: transparent; border: none; height: 50px; color: white; padding: 0; } QPushButton:hover { cursor: hand; }");
QPushButton *awAcceptButton = new QPushButton(QIcon(":/icons/yes.big"), "", this);
connect(awAcceptButton, SIGNAL(clicked()), this, SLOT(grabRect()));
awAcceptButton->setCursor(Qt::PointingHandCursor);
awAcceptButton->setIconSize(QSize(48, 48));
awAcceptButton->setGraphicsEffect(os::shadow(QColor(50, 50, 50, 255)));
QPushButton *awRejectButton = new QPushButton(QIcon(":/icons/no.big"), "", this);
connect(awRejectButton, SIGNAL(clicked()), this, SLOT(cancel()));
awRejectButton->setCursor(Qt::PointingHandCursor);
awRejectButton->setIconSize(QSize(48, 48));
awRejectButton->setGraphicsEffect(os::shadow(QColor(50, 50, 50, 255)));
QHBoxLayout *awLayout = new QHBoxLayout(this);
awLayout->addWidget(awAcceptButton);
awLayout->addWidget(awRejectButton);
awLayout->setMargin(0);
awLayout->setSpacing(0);
mAcceptWidget->setLayout(awLayout);
mAcceptWidget->setVisible(false);
}
QRect &AreaDialog::resultRect()
{
return mSelection;
}
+void AreaDialog::animationTick(int frame)
+{
+ mOverlayAlpha = frame;
+ update();
+}
+
+void AreaDialog::cancel()
+{
+ reject();
+}
+
void AreaDialog::displayHelp()
{
mShowHelp = true;
update();
}
+void AreaDialog::grabRect()
+{
+ QRect r = mSelection.normalized();
+ if (!r.isNull() && r.isValid()) {
+ mGrabbing = true;
+ accept();
+ }
+}
+
+void AreaDialog::keyPressEvent(QKeyEvent* e)
+{
+ if (e->key() == Qt::Key_Escape) {
+ cancel();
+ }
+ else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
+ grabRect();
+ }
+ else {
+ e->ignore();
+ }
+}
+
+void AreaDialog::mouseDoubleClickEvent(QMouseEvent*)
+{
+ grabRect();
+}
+
+void AreaDialog::mouseMoveEvent(QMouseEvent* e)
+{
+ mMouseMagnifier = false;
+
+ if (mMouseDown) {
+
+ mMousePos = e->pos();
+
+ if (mNewSelection) {
+ QRect r = rect();
+
+ mSelection = QRect(mDragStartPoint, limitPointToRect(mMousePos, r)).normalized();
+ }
+ else if (mMouseOverHandle == 0) { // moving the whole selection
+ QRect r = rect().normalized(), s = mSelectionBeforeDrag.normalized();
+ QPoint p = s.topLeft() + e->pos() - mDragStartPoint;
+ r.setBottomRight(r.bottomRight() - QPoint(s.width(), s.height()));
+
+ if (!r.isNull() && r.isValid())
+ mSelection.moveTo(limitPointToRect(p, r));
+ }
+ else {// dragging a handle
+ QRect r = mSelectionBeforeDrag;
+ QPoint offset = e->pos() - mDragStartPoint;
+
+ if (mMouseOverHandle == &mTLHandle || mMouseOverHandle == &mTHandle
+ || mMouseOverHandle == &mTRHandle) // dragging one of the top handles
+ {
+ r.setTop(r.top() + offset.y());
+ }
+
+ if (mMouseOverHandle == &mTLHandle || mMouseOverHandle == &mLHandle
+ || mMouseOverHandle == &mBLHandle) // dragging one of the left handles
+ {
+ r.setLeft(r.left() + offset.x());
+ }
+
+ if (mMouseOverHandle == &mBLHandle || mMouseOverHandle == &mBHandle
+ || mMouseOverHandle == &mBRHandle) // dragging one of the bottom handles
+ {
+ r.setBottom(r.bottom() + offset.y());
+ }
+
+ if (mMouseOverHandle == &mTRHandle || mMouseOverHandle == &mRHandle
+ || mMouseOverHandle == &mBRHandle) // dragging one of the right handles
+ {
+ r.setRight(r.right() + offset.x());
+ }
+
+ r = r.normalized();
+ r.setTopLeft(limitPointToRect(r.topLeft(), rect()));
+ r.setBottomRight(limitPointToRect(r.bottomRight(), rect()));
+ mSelection = r;
+ }
+
+ if (qApp->keyboardModifiers() & Qt::ControlModifier)
+ {
+ // The lazy 1:1 aspect ratio approach!
+ mSelection.setHeight(mSelection.width());
+ }
+
+ if (mAcceptWidget) {
+ QPoint acceptPos = e->pos();
+ QRect acceptRect = QRect(acceptPos, QSize(120, 70));
+
+ if ((acceptPos.x()+120) > mScreenshot->pixmap().rect().width())
+ acceptPos.setX(acceptPos.x()-120);
+
+ if ((acceptPos.y()+70) > mScreenshot->pixmap().rect().height())
+ acceptPos.setY(acceptPos.y()-70);
+
+ // Prevent the widget from overlapping the handles
+ if (acceptRect.intersects(mTLHandle)) {
+ acceptPos = mTLHandle.bottomRight() + QPoint(2, 2); // Corner case
+ }
+
+ if (acceptRect.intersects(mBRHandle)) {
+ acceptPos = mBRHandle.bottomRight();
+ }
+
+ if (acceptRect.intersects(mBHandle)) {
+ acceptPos = mBHandle.bottomRight();
+ }
+
+ if (acceptRect.intersects(mRHandle)) {
+ acceptPos = mRHandle.topRight();
+ }
+
+ mAcceptWidget->move(acceptPos);
+ }
+
+ update();
+ }
+ else
+ {
+ if (mSelection.isNull()) {
+ mMouseMagnifier = true;
+ update();
+ return;
+ }
+
+ bool found = false;
+ foreach(QRect* r, mHandles) {
+
+ if (r->contains(e->pos())) {
+ mMouseOverHandle = r;
+ found = true;
+ break;
+ }
+
+ }
+
+ if (!found) {
+ mMouseOverHandle = 0;
+ if (mSelection.contains(e->pos()))
+ setCursor(Qt::OpenHandCursor);
+ else if (mAcceptWidget && QRect(mAcceptWidget->mapToParent(mAcceptWidget->pos()), QSize(100, 60)).contains(e->pos()))
+ setCursor(Qt::PointingHandCursor);
+ else
+ setCursor(Qt::CrossCursor);
+ }
+ else {
+ if (mMouseOverHandle == &mTLHandle || mMouseOverHandle == &mBRHandle)
+ setCursor(Qt::SizeFDiagCursor);
+ if (mMouseOverHandle == &mTRHandle || mMouseOverHandle == &mBLHandle)
+ setCursor(Qt::SizeBDiagCursor);
+ if (mMouseOverHandle == &mLHandle || mMouseOverHandle == &mRHandle)
+ setCursor(Qt::SizeHorCursor);
+ if (mMouseOverHandle == &mTHandle || mMouseOverHandle == &mBHandle)
+ setCursor(Qt::SizeVerCursor);
+ }
+ }
+}
+
+void AreaDialog::mousePressEvent(QMouseEvent* e)
+{
+ mShowHelp = false;
+ mIdleTimer.stop();
+
+ if (mAcceptWidget)
+ mAcceptWidget->hide();
+
+ if (e->button() == Qt::LeftButton) {
+ mMouseDown = true;
+ mDragStartPoint = e->pos();
+ mSelectionBeforeDrag = mSelection;
+ if (!mSelection.contains(e->pos())) {
+ mNewSelection = true;
+ mSelection = QRect();
+ mShowHelp = true;
+ setCursor(Qt::CrossCursor);
+ }
+ else {
+ setCursor(Qt::ClosedHandCursor);
+ }
+ }
+ else if (e->button() == Qt::RightButton
+ || e->button() == Qt::MidButton)
+ {
+ cancel();
+ }
+
+ update();
+}
+
+void AreaDialog::mouseReleaseEvent(QMouseEvent* e)
+{
+ if (mAutoclose)
+ grabRect();
+
+ if (!mSelection.isNull() && mAcceptWidget)
+ mAcceptWidget->show();
+
+ mMouseDown = false;
+ mNewSelection = false;
+ mIdleTimer.start();
+
+ if (mMouseOverHandle == 0 && mSelection.contains(e->pos()))
+ setCursor(Qt::OpenHandCursor);
+
+ update();
+}
+
void AreaDialog::paintEvent(QPaintEvent* e)
{
Q_UNUSED(e);
if (mGrabbing) // grabWindow() should just get the background
return;
QPainter painter(this);
QPalette pal = palette();
QFont font = QToolTip::font();
QColor handleColor(25, 115, 240, 180);
QColor overlayColor(0, 0, 0, mOverlayAlpha);
QColor textColor = pal.color(QPalette::Active, QPalette::Text);
QColor textBackgroundColor = pal.color(QPalette::Active, QPalette::Base);
painter.drawPixmap(0, 0, mScreenshot->pixmap());
painter.setFont(font);
QRect r = mSelection.normalized().adjusted(0, 0, -1, -1);
QRegion grey(rect());
grey = grey.subtracted(r);
painter.setPen(handleColor);
painter.setBrush(overlayColor);
painter.setClipRegion(grey);
painter.drawRect(-1, -1, rect().width() + 1, rect().height() + 1);
painter.setClipRect(rect());
painter.setBrush(Qt::NoBrush);
painter.drawRect(r);
if (mShowHelp) {
//Drawing the explanatory text.
QRect helpRect = qApp->desktop()->screenGeometry(qApp->desktop()->primaryScreen());
QString helpTxt = tr("Lightscreen area mode:\nUse your mouse to draw a rectangle to capture.\nPress any key or right click to exit.");
helpRect.setHeight(qRound(helpRect.height() / 10)); // We get a decently sized rect where the text should be drawn (centered)
// We draw the white contrasting background for the text, using the same text and options to get the boundingRect that the text will have.
painter.setPen(QPen(Qt::white));
painter.setBrush(QBrush(QColor(255, 255, 255, 180), Qt::SolidPattern));
QRectF bRect = painter.boundingRect(helpRect, Qt::AlignCenter, helpTxt);
// These four calls provide padding for the rect
bRect.setWidth(bRect.width() + 12);
bRect.setHeight(bRect.height() + 10);
bRect.setX(bRect.x() - 12);
bRect.setY(bRect.y() - 10);
painter.drawRoundedRect(bRect, 8, 8);
// Draw the text:
painter.setPen(QPen(Qt::black));
painter.drawText(helpRect, Qt::AlignCenter, helpTxt);
}
if (!mSelection.isNull()) {
// The grabbed region is everything which is covered by the drawn
// rectangles (border included). This means that there is no 0px
// selection, since a 0px wide rectangle will always be drawn as a line.
QString txt = QString("%1x%2").arg(mSelection.width() == 0 ? 2 : mSelection.width())
.arg(mSelection.height() == 0 ? 2 : mSelection.height());
QRect textRect = painter.boundingRect(rect(), Qt::AlignLeft, txt);
QRect boundingRect = textRect.adjusted(-4, 0, 0, 0);
if (textRect.width() < r.width() - 2*mHandleSize &&
textRect.height() < r.height() - 2*mHandleSize &&
(r.width() > 100 && r.height() > 100)) // center, unsuitable for small selections
{
boundingRect.moveCenter(r.center());
textRect.moveCenter(r.center());
}
else if (r.y() - 3 > textRect.height() &&
r.x() + textRect.width() < rect().right()) // on top, left aligned
{
boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3));
textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3));
}
else if (r.x() - 3 > textRect.width()) // left, top aligned
{
boundingRect.moveTopRight(QPoint(r.x() - 3, r.y()));
textRect.moveTopRight(QPoint(r.x() - 5, r.y()));
}
else if (r.bottom() + 3 + textRect.height() < rect().bottom() &&
r.right() > textRect.width()) // at bottom, right aligned
{
boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3));
textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3));
}
else if (r.right() + textRect.width() + 3 < rect().width()) // right, bottom aligned
{
boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom()));
textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom()));
}
// if the above didn't catch it, you are running on a very tiny screen...
painter.setPen(textColor);
painter.setBrush(textBackgroundColor);
painter.drawRect(boundingRect);
painter.drawText(textRect, txt);
if ((r.height() > mHandleSize*2 && r.width() > mHandleSize*2)
|| !mMouseDown)
{
updateHandles();
painter.setPen(handleColor);
handleColor.setAlpha(80);
painter.setBrush(handleColor);
painter.drawRects(handleMask().rects());
}
}
if (!mScreenshot->options().magnify)
return;
// Drawing the magnified version
QPoint magStart, magEnd, drawPosition;
QRect newRect;
QRect pixmapRect = mScreenshot->pixmap().rect();
if (mMouseMagnifier) {
drawPosition = QCursor::pos() - QPoint(100, 100);
magStart = QCursor::pos() - QPoint(50, 50);
magEnd = QCursor::pos() + QPoint(50, 50);
newRect = QRect(magStart, magEnd);
}
else {
// So pretty.. oh so pretty.
if (mMouseOverHandle == &mTLHandle)
magStart = mSelection.topLeft();
else if (mMouseOverHandle == &mTRHandle)
magStart = mSelection.topRight();
else if (mMouseOverHandle == &mBLHandle)
magStart = mSelection.bottomLeft();
else if (mMouseOverHandle == &mBRHandle)
magStart = mSelection.bottomRight();
else if (mMouseOverHandle == &mLHandle)
magStart = QPoint(mSelection.left(), mSelection.center().y());
else if (mMouseOverHandle == &mTHandle)
magStart = QPoint(mSelection.center().x(), mSelection.top());
else if (mMouseOverHandle == &mRHandle)
magStart = QPoint(mSelection.right(), mSelection.center().y());
else if (mMouseOverHandle == &mBHandle)
magStart = QPoint(mSelection.center().x(), mSelection.bottom());
else if (mMouseOverHandle == 0)
magStart = QCursor::pos();
magEnd = magStart;
drawPosition = mSelection.bottomRight();
magStart -= QPoint(50, 50);
magEnd += QPoint(50, 50);
newRect = QRect(magStart, magEnd);
if ((drawPosition.x()+newRect.width()*2) > pixmapRect.width())
drawPosition.setX(drawPosition.x()-newRect.width()*2);
if ((drawPosition.y()+newRect.height()*2) > pixmapRect.height())
drawPosition.setY(drawPosition.y()-newRect.height()*2);
if (drawPosition.y() == mSelection.bottomRight().y()-newRect.height()*2
&& drawPosition.x() == mSelection.bottomRight().x()-newRect.width()*2)
painter.setOpacity(0.7);
}
if (!pixmapRect.contains(newRect, true) || drawPosition.x() <= 0 || drawPosition.y() <= 0) {
return;
}
QPixmap magnified = mScreenshot->pixmap().copy(newRect).scaled(QSize(newRect.width()*2, newRect.height()*2));
QPainter magPainter(&magnified);
magPainter.setPen(QPen(QBrush(QColor(25, 115, 240)), 2)); // Same border pen
magPainter.drawRect(magnified.rect());
if (!mMouseMagnifier) {
magPainter.drawText(magnified.rect().center()-QPoint(4, -4), "+"); //Center minus the 4 pixels wide and across of the "+" -- TODO: Test alternative DPI settings.
}
painter.drawPixmap(drawPosition, magnified);
}
void AreaDialog::resizeEvent(QResizeEvent* e)
{
Q_UNUSED(e);
if (mSelection.isNull())
return;
QRect r = mSelection;
r.setTopLeft(limitPointToRect(r.topLeft(), rect()));
r.setBottomRight(limitPointToRect(r.bottomRight(), rect()));
if (r.width() <= 1 || r.height() <= 1) //this just results in ugly drawing...
r = QRect();
mSelection = r;
}
-void AreaDialog::mousePressEvent(QMouseEvent* e)
-{
- mShowHelp = false;
- mIdleTimer.stop();
-
- if (mAcceptWidget)
- mAcceptWidget->hide();
-
- if (e->button() == Qt::LeftButton) {
- mMouseDown = true;
- mDragStartPoint = e->pos();
- mSelectionBeforeDrag = mSelection;
- if (!mSelection.contains(e->pos())) {
- mNewSelection = true;
- mSelection = QRect();
- mShowHelp = true;
- setCursor(Qt::CrossCursor);
- }
- else {
- setCursor(Qt::ClosedHandCursor);
- }
- }
- else if (e->button() == Qt::RightButton
- || e->button() == Qt::MidButton)
- {
- cancel();
- }
-
- update();
-}
-
-void AreaDialog::mouseMoveEvent(QMouseEvent* e)
-{
- mMouseMagnifier = false;
-
- if (mMouseDown) {
-
- mMousePos = e->pos();
-
- if (mNewSelection) {
- QRect r = rect();
-
- mSelection = QRect(mDragStartPoint, limitPointToRect(mMousePos, r)).normalized();
- }
- else if (mMouseOverHandle == 0) { // moving the whole selection
- QRect r = rect().normalized(), s = mSelectionBeforeDrag.normalized();
- QPoint p = s.topLeft() + e->pos() - mDragStartPoint;
- r.setBottomRight(r.bottomRight() - QPoint(s.width(), s.height()));
-
- if (!r.isNull() && r.isValid())
- mSelection.moveTo(limitPointToRect(p, r));
- }
- else {// dragging a handle
- QRect r = mSelectionBeforeDrag;
- QPoint offset = e->pos() - mDragStartPoint;
-
- if (mMouseOverHandle == &mTLHandle || mMouseOverHandle == &mTHandle
- || mMouseOverHandle == &mTRHandle) // dragging one of the top handles
- {
- r.setTop(r.top() + offset.y());
- }
-
- if (mMouseOverHandle == &mTLHandle || mMouseOverHandle == &mLHandle
- || mMouseOverHandle == &mBLHandle) // dragging one of the left handles
- {
- r.setLeft(r.left() + offset.x());
- }
-
- if (mMouseOverHandle == &mBLHandle || mMouseOverHandle == &mBHandle
- || mMouseOverHandle == &mBRHandle) // dragging one of the bottom handles
- {
- r.setBottom(r.bottom() + offset.y());
- }
-
- if (mMouseOverHandle == &mTRHandle || mMouseOverHandle == &mRHandle
- || mMouseOverHandle == &mBRHandle) // dragging one of the right handles
- {
- r.setRight(r.right() + offset.x());
- }
-
- r = r.normalized();
- r.setTopLeft(limitPointToRect(r.topLeft(), rect()));
- r.setBottomRight(limitPointToRect(r.bottomRight(), rect()));
- mSelection = r;
- }
-
- if (qApp->keyboardModifiers() & Qt::ControlModifier)
- {
- // The lazy 1:1 aspect ratio approach!
- mSelection.setHeight(mSelection.width());
- }
-
- if (mAcceptWidget) {
- QPoint acceptPos = e->pos();
- QRect acceptRect = QRect(acceptPos, QSize(120, 70));
-
- if ((acceptPos.x()+120) > mScreenshot->pixmap().rect().width())
- acceptPos.setX(acceptPos.x()-120);
-
- if ((acceptPos.y()+70) > mScreenshot->pixmap().rect().height())
- acceptPos.setY(acceptPos.y()-70);
-
- // Prevent the widget from overlapping the handles
- if (acceptRect.intersects(mTLHandle)) {
- acceptPos = mTLHandle.bottomRight() + QPoint(2, 2); // Corner case
- }
-
- if (acceptRect.intersects(mBRHandle)) {
- acceptPos = mBRHandle.bottomRight();
- }
-
- if (acceptRect.intersects(mBHandle)) {
- acceptPos = mBHandle.bottomRight();
- }
-
- if (acceptRect.intersects(mRHandle)) {
- acceptPos = mRHandle.topRight();
- }
-
- mAcceptWidget->move(acceptPos);
- }
-
- update();
- }
- else
- {
- if (mSelection.isNull()) {
- mMouseMagnifier = true;
- update();
- return;
- }
-
- bool found = false;
- foreach(QRect* r, mHandles) {
-
- if (r->contains(e->pos())) {
- mMouseOverHandle = r;
- found = true;
- break;
- }
-
- }
-
- if (!found) {
- mMouseOverHandle = 0;
- if (mSelection.contains(e->pos()))
- setCursor(Qt::OpenHandCursor);
- else if (mAcceptWidget && QRect(mAcceptWidget->mapToParent(mAcceptWidget->pos()), QSize(100, 60)).contains(e->pos()))
- setCursor(Qt::PointingHandCursor);
- else
- setCursor(Qt::CrossCursor);
- }
- else {
- if (mMouseOverHandle == &mTLHandle || mMouseOverHandle == &mBRHandle)
- setCursor(Qt::SizeFDiagCursor);
- if (mMouseOverHandle == &mTRHandle || mMouseOverHandle == &mBLHandle)
- setCursor(Qt::SizeBDiagCursor);
- if (mMouseOverHandle == &mLHandle || mMouseOverHandle == &mRHandle)
- setCursor(Qt::SizeHorCursor);
- if (mMouseOverHandle == &mTHandle || mMouseOverHandle == &mBHandle)
- setCursor(Qt::SizeVerCursor);
- }
-
-
- }
-}
-
-void AreaDialog::mouseReleaseEvent(QMouseEvent* e)
-{
- if (mAutoclose)
- grabRect();
-
- if (!mSelection.isNull() && mAcceptWidget)
- mAcceptWidget->show();
-
- mMouseDown = false;
- mNewSelection = false;
- mIdleTimer.start();
-
- if (mMouseOverHandle == 0 && mSelection.contains(e->pos()))
- setCursor(Qt::OpenHandCursor);
-
- update();
-}
-
-void AreaDialog::mouseDoubleClickEvent(QMouseEvent*)
-{
- grabRect();
-}
-
-void AreaDialog::keyPressEvent(QKeyEvent* e)
-{
- if (e->key() == Qt::Key_Escape) {
- cancel();
- }
- else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
- grabRect();
- }
- else {
- e->ignore();
- }
-}
-
void AreaDialog::showEvent(QShowEvent* e)
{
Q_UNUSED(e)
QRect geometry = qApp->desktop()->geometry();
if (mScreenshot->options().currentMonitor) {
geometry = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(QCursor::pos()));
}
resize(geometry.size());
move(geometry.topLeft());
if (mScreenshot->options().animations) {
os::effect(this, SLOT(animationTick(int)), 85, 300);
}
else {
animationTick(85);
}
setMouseTracking(true);
}
-void AreaDialog::grabRect()
-{
- QRect r = mSelection.normalized();
- if (!r.isNull() && r.isValid()) {
- mGrabbing = true;
- accept();
- }
-}
-
-void AreaDialog::cancel()
-{
- reject();
-}
-
-void AreaDialog::animationTick(int frame)
-{
- mOverlayAlpha = frame;
- update();
-}
-
void AreaDialog::updateHandles()
{
QRect r = mSelection.normalized().adjusted(0, 0, -1, -1);
int s2 = mHandleSize / 2;
mTLHandle.moveTopLeft(r.topLeft());
mTRHandle.moveTopRight(r.topRight());
mBLHandle.moveBottomLeft(r.bottomLeft());
mBRHandle.moveBottomRight(r.bottomRight());
mLHandle.moveTopLeft(QPoint(r.x(), r.y() + r.height() / 2 - s2));
mTHandle.moveTopLeft(QPoint(r.x() + r.width() / 2 - s2, r.y()));
mRHandle.moveTopRight(QPoint(r.right(), r.y() + r.height() / 2 - s2));
mBHandle.moveBottomLeft(QPoint(r.x() + r.width() / 2 - s2, r.bottom()));
}
QRegion AreaDialog::handleMask() const
{
// note: not normalized QRects are bad here, since they will not be drawn
QRegion mask;
foreach(QRect* rect, mHandles) mask += QRegion(*rect);
return mask;
}
QPoint AreaDialog::limitPointToRect(const QPoint &p, const QRect &r) const
{
QPoint q;
q.setX(p.x() < r.x() ? r.x() : p.x() < r.right() ? p.x() : r.right());
q.setY(p.y() < r.y() ? r.y() : p.y() < r.bottom() ? p.y() : r.bottom());
return q;
}
diff --git a/dialogs/areadialog.h b/dialogs/areadialog.h
index d56316c..da0b17e 100644
--- a/dialogs/areadialog.h
+++ b/dialogs/areadialog.h
@@ -1,100 +1,99 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
******
*
* Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann <lucag@student.ethz.ch>
* released under the GNU LGPL <http://www.gnu.org/licenses/old-licenses/library.txt>
*
*/
#ifndef AREADIALOG_H
#define AREADIALOG_H
#include <QDialog>
#include <QVector>
#include <QPointer>
#include <QTimer>
struct QRegion;
struct QPoint;
struct QRect;
class QPaintEvent;
class QResizeEvent;
class QMouseEvent;
class Screenshot;
class AreaDialog : public QDialog
{
Q_OBJECT
public:
AreaDialog(Screenshot* screenshot);
QRect &resultRect();
protected slots:
+ void animationTick(int frame);
+ void cancel();
void displayHelp();
void grabRect();
- void cancel();
- void animationTick(int frame);
signals:
void regionGrabbed( const QPixmap & );
protected:
- void paintEvent( QPaintEvent* e );
- void resizeEvent( QResizeEvent* e );
- void mousePressEvent( QMouseEvent* e );
+ void keyPressEvent( QKeyEvent* e );
+ void mouseDoubleClickEvent( QMouseEvent* );
void mouseMoveEvent( QMouseEvent* e );
+ void mousePressEvent( QMouseEvent* e );
void mouseReleaseEvent( QMouseEvent* e );
- void mouseDoubleClickEvent( QMouseEvent* );
- void keyPressEvent( QKeyEvent* e );
+ void paintEvent( QPaintEvent* e );
+ void resizeEvent( QResizeEvent* e );
void showEvent( QShowEvent* e );
void updateHandles();
-
QRegion handleMask() const;
+
QPoint limitPointToRect( const QPoint &p, const QRect &r ) const;
- Screenshot *mScreenshot;
- QPoint mMousePos;
- QRect mSelection;
- bool mMouseDown;
- bool mMouseMagnifier;
- bool mNewSelection;
- const int mHandleSize;
- QRect *mMouseOverHandle;
+ bool mAutoclose;
QPoint mDragStartPoint;
- QRect mSelectionBeforeDrag;
+ bool mGrabbing;
+ const int mHandleSize;
QTimer mIdleTimer;
- bool mShowHelp;
- bool mGrabbing;
+ bool mMouseDown;
+ bool mMouseMagnifier;
+ QRect *mMouseOverHandle;
+ QPoint mMousePos;
+ bool mNewSelection;
int mOverlayAlpha;
- bool mAutoclose;
-
+ Screenshot *mScreenshot;
+ QRect mSelection;
+ QRect mSelectionBeforeDrag;
+ bool mShowHelp;
// naming convention for handles
// T top, B bottom, R Right, L left
// 2 letters: a corner
// 1 letter: the handle on the middle of the corresponding side
QRect mTLHandle, mTRHandle, mBLHandle, mBRHandle;
QRect mLHandle, mTHandle, mRHandle, mBHandle;
- QVector<QRect*> mHandles;
+ QVector<QRect*> mHandles;
QPointer<QWidget> mAcceptWidget;
};
#endif
diff --git a/dialogs/historydialog.cpp b/dialogs/historydialog.cpp
index 69cad74..93251d6 100644
--- a/dialogs/historydialog.cpp
+++ b/dialogs/historydialog.cpp
@@ -1,219 +1,221 @@
#include "historydialog.h"
#include "ui_historydialog.h"
#include "../tools/os.h"
#include "../tools/qxtcsvmodel.h"
#include "../tools/uploader.h"
#include "../tools/screenshotmanager.h"
-#include <QMessageBox>
-#include <QFile>
+#include <QClipboard>
#include <QDesktopServices>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
#include <QFileSystemWatcher>
-#include <QUrl>
#include <QMenu>
-#include <QFileInfo>
-#include <QClipboard>
-#include <QDir>
+#include <QMessageBox>
#include <QSortFilterProxyModel>
+#include <QUrl>
+
#include <QDebug>
HistoryDialog::HistoryDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::HistoryDialog)
{
ui->setupUi(this);
if (os::aeroGlass(this)) {
layout()->setMargin(2);
}
ui->filterEdit->setText(tr("Filter.."));
ui->filterEdit->installEventFilter(this);
QFile historyFile(ScreenshotManager::instance()->historyPath());
if (!historyFile.exists())
{
ui->tableView->setEnabled(false);
return;
}
QFileSystemWatcher *watcher = new QFileSystemWatcher(QStringList() << historyFile.fileName(), this);
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(reloadHistory()));
reloadHistory();
ui->tableView->setTextElideMode(Qt::ElideLeft);
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tableView->setAlternatingRowColors(true);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
ui->tableView->setSortingEnabled(true);
if (ui->tableView->model()->rowCount() > 0)
{
ui->clearButton->setEnabled(true);
ui->filterEdit->setEnabled(true);
}
connect(ui->uploadButton, SIGNAL(clicked()), this, SLOT(upload()));
connect(ui->clearButton , SIGNAL(clicked()), this, SLOT(clear()));
connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(open(QModelIndex)));
connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint)));
}
HistoryDialog::~HistoryDialog()
{
delete ui;
}
+void HistoryDialog::clear()
+{
+ if (QMessageBox::question(this,
+ tr("Clearing the screenshot history"),
+ tr("Are you sure you want to clear your entire screenshot history?\nThis cannot be undone."),
+ tr("Clear History"),
+ tr("Don't Clear")) == 1) {
+ return;
+ }
+
+ QFile::remove(ScreenshotManager::instance()->historyPath());
+ close();
+}
+
void HistoryDialog::contextMenu(QPoint point)
{
mContextIndex = ui->tableView->indexAt(point);;
QMenu contextMenu(ui->tableView);
QAction copyAction((mContextIndex.column() == 0) ? tr("Copy Path") : tr("Copy URL"), &contextMenu);
connect(&copyAction, SIGNAL(triggered()), this, SLOT(copy()));
contextMenu.addAction(&copyAction);
QAction locationAction(tr("Open Location"), &contextMenu);
if (mContextIndex.column() == 0)
{
connect(&locationAction, SIGNAL(triggered()), this, SLOT(location()));
contextMenu.addAction(&locationAction);
}
else if (mContextIndex.data().toString() == QObject::tr("- not uploaded -")) {
copyAction.setEnabled(false);
}
contextMenu.exec(QCursor::pos());
}
void HistoryDialog::copy()
{
qApp->clipboard()->setText(mContextIndex.data().toString());
}
void HistoryDialog::location()
{
QDesktopServices::openUrl("file:///" + QFileInfo(mContextIndex.data().toString()).absolutePath());
}
-void HistoryDialog::selectionChanged(QItemSelection selected, QItemSelection deselected)
-{
- Q_UNUSED(deselected);
-
- QModelIndex index = selected.indexes().at(0);
-
- QString screenshot, url;
-
- if (index.column() == 0) {
- screenshot = index.data().toString();
- url = ui->tableView->model()->index(index.row(), 1).data().toString();
- }
- else {
- screenshot = ui->tableView->model()->index(index.row(), 0).data().toString();
- url = index.data().toString();
- }
-
- mSelectedScreenshot = screenshot;
-
- ui->uploadButton->setEnabled((url == QObject::tr("- not uploaded -") && QFile::exists(screenshot)));
-}
-
void HistoryDialog::open(QModelIndex index)
{
if (index.column() == 0) {
QDesktopServices::openUrl(QUrl("file:///" + index.data().toString()));
}
else {
QDesktopServices::openUrl(index.data().toUrl());
}
}
void HistoryDialog::reloadHistory()
{
if (ui->tableView->model()) {
ui->tableView->model()->deleteLater();
}
QFile historyFile(ScreenshotManager::instance()->historyPath());
QxtCsvModel *model = new QxtCsvModel(&historyFile, this, false, '|');
model->setHeaderData(QStringList() << tr("Screenshot") << tr("URL"));
mFilterModel = new QSortFilterProxyModel(model);
mFilterModel->setSourceModel(model);
mFilterModel->setDynamicSortFilter(true);
ui->tableView->setModel(mFilterModel);
ui->tableView->hideColumn(2); // No timestamp.
ui->tableView->horizontalHeader()->setClickable(false);
ui->tableView->horizontalHeader()->setMovable(false);
ui->tableView->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);
ui->tableView->verticalHeader()->hide();
}
-void HistoryDialog::upload()
+void HistoryDialog::selectionChanged(QItemSelection selected, QItemSelection deselected)
{
- Uploader::instance()->upload(mSelectedScreenshot);
- ui->uploadButton->setEnabled(false);
-}
+ Q_UNUSED(deselected);
-void HistoryDialog::clear()
-{
- if (QMessageBox::question(this,
- tr("Clearing the screenshot history"),
- tr("Are you sure you want to clear your entire screenshot history?\nThis cannot be undone."),
- tr("Clear History"),
- tr("Don't Clear")) == 1) {
- return;
+ QModelIndex index = selected.indexes().at(0);
+
+ QString screenshot, url;
+
+ if (index.column() == 0) {
+ screenshot = index.data().toString();
+ url = ui->tableView->model()->index(index.row(), 1).data().toString();
+ }
+ else {
+ screenshot = ui->tableView->model()->index(index.row(), 0).data().toString();
+ url = index.data().toString();
}
- QFile::remove(ScreenshotManager::instance()->historyPath());
- close();
+ mSelectedScreenshot = screenshot;
+
+ ui->uploadButton->setEnabled((url == QObject::tr("- not uploaded -") && QFile::exists(screenshot)));
+}
+
+
+void HistoryDialog::upload()
+{
+ Uploader::instance()->upload(mSelectedScreenshot);
+ ui->uploadButton->setEnabled(false);
}
bool HistoryDialog::eventFilter(QObject *object, QEvent *event)
{
if (object == ui->filterEdit) {
if (event->type() == QEvent::FocusIn)
{
if (ui->filterEdit->text() == tr("Filter..")) {
ui->filterEdit->setStyleSheet("");
ui->filterEdit->setText("");
mFilterModel->setFilterWildcard("");
mFilterModel->sort(2, Qt::DescendingOrder);
}
}
else if (event->type() == QEvent::FocusOut)
{
if (ui->filterEdit->text() == "") {
ui->filterEdit->setStyleSheet("color: palette(mid);");
ui->filterEdit->setText(tr("Filter.."));
mFilterModel->sort(2, Qt::DescendingOrder);
}
}
else if (event->type() == QEvent::KeyRelease)
{
if (ui->filterEdit->text() != tr("Filter..") && !ui->filterEdit->text().isEmpty()) {
mFilterModel->setFilterWildcard(ui->filterEdit->text());
mFilterModel->sort(2, Qt::DescendingOrder);
}
else {
mFilterModel->setFilterWildcard("");
mFilterModel->sort(2, Qt::DescendingOrder);
}
}
}
return QDialog::eventFilter(object, event);
}
diff --git a/dialogs/historydialog.h b/dialogs/historydialog.h
index d1f7b1c..f1792ca 100644
--- a/dialogs/historydialog.h
+++ b/dialogs/historydialog.h
@@ -1,40 +1,40 @@
#ifndef UPLOADDIALOG_H
#define UPLOADDIALOG_H
#include <QDialog>
#include <QItemSelection>
namespace Ui {
class HistoryDialog;
}
class QSortFilterProxyModel;
class HistoryDialog : public QDialog
{
Q_OBJECT
public:
explicit HistoryDialog(QWidget *parent = 0);
~HistoryDialog();
private slots:
+ void clear();
+ void contextMenu(QPoint point);
void copy();
void location();
- void contextMenu(QPoint point);
- void selectionChanged(QItemSelection selected, QItemSelection deselected);
void open(QModelIndex index);
void reloadHistory();
+ void selectionChanged(QItemSelection selected, QItemSelection deselected);
void upload();
- void clear();
protected:
bool eventFilter(QObject *object, QEvent *event);
private:
- Ui::HistoryDialog *ui;
- QSortFilterProxyModel *mFilterModel;
- QString mSelectedScreenshot;
- QModelIndex mContextIndex;
+ Ui::HistoryDialog *ui;
+ QSortFilterProxyModel *mFilterModel;
+ QString mSelectedScreenshot;
+ QModelIndex mContextIndex;
};
#endif // UPLOADDIALOG_H
diff --git a/dialogs/namingdialog.cpp b/dialogs/namingdialog.cpp
index abf0b0e..e293d5a 100644
--- a/dialogs/namingdialog.cpp
+++ b/dialogs/namingdialog.cpp
@@ -1,98 +1,98 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "namingdialog.h"
#include "../tools/screenshot.h"
#include "../tools/os.h"
#include "../tools/screenshotmanager.h"
-#include <QSettings>
+#include <QDesktopServices>
#include <QKeyEvent>
+#include <QSettings>
#include <QUrl>
-#include <QDesktopServices>
NamingDialog::NamingDialog(Screenshot::Naming naming,QWidget *parent) :
QDialog(parent)
{
ui.setupUi(this);
setModal(true);
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
ui.dateFormatComboBox->installEventFilter(this);
// Aero
if (os::aeroGlass(this)) {
ui.container->setStyleSheet("#container { background: palette(light); border: 1px solid palette(dark); border-radius: 4px; }");
ui.container->setWindowOpacity(0.5);
layout()->setMargin(2);
}
// Settings
QSettings *s = ScreenshotManager::instance()->settings();
ui.flipNamingCheckBox->setChecked(s->value("options/flip", false).toBool());
ui.dateFormatComboBox->setCurrentIndex(
ui.dateFormatComboBox->findText(s->value("options/naming/dateFormat", "yyyy-MM-dd").toString())
);
if (ui.dateFormatComboBox->currentIndex() == -1) {
ui.dateFormatComboBox->addItem(s->value("options/naming/dateFormat", "yyyy-MM-dd").toString());
ui.dateFormatComboBox->setCurrentIndex(ui.dateFormatComboBox->count()-1);
}
ui.leadingZerosSpinBox->setValue(s->value("options/naming/leadingZeros", 0).toInt());
// Signals/Slots
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(saveSettings()));
connect(ui.dateHelpLabel, SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
// Stack & window size adjustments
ui.stack->setCurrentIndex((int)naming);
ui.stack->currentWidget()->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
resize(minimumSizeHint());
}
+void NamingDialog::openUrl(QString url)
+{
+ QDesktopServices::openUrl(QUrl(url));
+}
+
void NamingDialog::saveSettings()
{
QSettings *s = ScreenshotManager::instance()->settings();
s->setValue("options/flip" , ui.flipNamingCheckBox->isChecked());
s->setValue("options/naming/dateFormat" , ui.dateFormatComboBox->currentText());
s->setValue("options/naming/leadingZeros", ui.leadingZerosSpinBox->value());
}
-void NamingDialog::openUrl(QString url)
-{
- QDesktopServices::openUrl(QUrl(url));
-}
-
bool NamingDialog::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::KeyPress
&& object == ui.dateFormatComboBox)
{
QKeyEvent *keyEvent = (QKeyEvent*)(event);
if (QRegExp("[?:\\\\/*\"<>|]").exactMatch(keyEvent->text())) {
event->ignore();
return true;
}
}
return QDialog::eventFilter(object, event);
}
diff --git a/dialogs/namingdialog.h b/dialogs/namingdialog.h
index 41c8a7a..a556a66 100644
--- a/dialogs/namingdialog.h
+++ b/dialogs/namingdialog.h
@@ -1,45 +1,45 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef NAMINGDIALOG_H
#define NAMINGDIALOG_H
#include "ui_namingdialog.h"
#include "tools/screenshot.h"
#include <QUrl>
class NamingDialog : public QDialog
{
Q_OBJECT
public:
explicit NamingDialog(Screenshot::Naming naming, QWidget *parent = 0);
-protected:
- bool eventFilter(QObject *object, QEvent *event);
-
private slots:
void openUrl(QString url);
void saveSettings();
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+
private:
Ui::NamingDialog ui;
};
#endif // NAMINGDIALOG_H
diff --git a/dialogs/optionsdialog.cpp b/dialogs/optionsdialog.cpp
index 0f96458..6e3d0c2 100644
--- a/dialogs/optionsdialog.cpp
+++ b/dialogs/optionsdialog.cpp
@@ -1,726 +1,725 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QCompleter>
#include <QDate>
#include <QDesktopServices>
#include <QDesktopWidget>
#include <QDirModel>
#include <QFileDialog>
#include <QKeyEvent>
#include <QMessageBox>
+#include <QProcess>
#include <QSettings>
-#include <QUrl>
#include <QTimer>
-#include <QProcess>
+#include <QUrl>
#include <QDebug>
#ifdef Q_WS_WIN
#include <windows.h>
#endif
#include "optionsdialog.h"
#include "namingdialog.h"
#include "historydialog.h"
#include "../tools/os.h"
#include "../tools/screenshot.h"
#include "../tools/screenshotmanager.h"
#include "../updater/updater.h"
OptionsDialog::OptionsDialog(QWidget *parent) :
QDialog(parent)
{
ui.setupUi(this);
setModal(true);
if (os::aeroGlass(this)) {
layout()->setMargin(2);
resize(minimumSizeHint());
}
#if defined(Q_WS_X11)
// KDE-specific style tweaks.
if (qApp->style()->objectName() == "oxygen") {
ui.browsePushButton->setMaximumWidth(30);
ui.namingOptionsButton->setMaximumWidth(30);
ui.fileGroupBox->setFlat(false);
ui.startupGroupBox->setFlat(false);
ui.capturesGroupBox->setFlat(false);
ui.controlGroupBox->setFlat(false);
ui.interfaceGroupBox->setFlat(false);
ui.screenshotsGroupBox->setFlat(false);
ui.previewGroupBox->setFlat(false);
ui.updaterGroupBox->setFlat(false);
ui.optionsTab->layout()->setContentsMargins(0, 0, 6, 0);
ui.aboutTab->layout()->setMargin(8);
}
#endif
QTimer::singleShot(0, this, SLOT(init()));
QTimer::singleShot(1, this, SLOT(loadSettings()));
}
-void OptionsDialog::init()
-{
- // Make the scroll area share the Tab Widget background color
- QPalette optionsPalette = ui.optionsScrollArea->palette();
- optionsPalette.setColor(QPalette::Window, ui.tabWidget->palette().color(QPalette::Base));
- ui.optionsScrollArea->setPalette(optionsPalette);
-
- ui.buttonBox->addButton(new QPushButton(" " + tr("Restore Defaults") + " ", this), QDialogButtonBox::ResetRole);
-
- // Set up the autocomplete for the directory.
- QCompleter *completer = new QCompleter(this);
- completer->setModel(new QDirModel(QStringList(), QDir::Dirs, QDir::Name, completer));
- ui.targetLineEdit->setCompleter(completer);
-
- // HotkeyWidget icons.
- ui.screenHotkeyWidget->setIcon (QIcon(":/icons/screen"));
- ui.windowHotkeyWidget->setIcon (QIcon(":/icons/window"));
- ui.windowPickerHotkeyWidget->setIcon(QIcon(":/icons/picker"));
- ui.areaHotkeyWidget->setIcon (QIcon(":/icons/area"));
- ui.openHotkeyWidget->setIcon (QIcon(":/icons/lightscreen.small"));
- ui.directoryHotkeyWidget->setIcon (QIcon(":/icons/folder"));
-
- // Version
- ui.versionLabel->setText(tr("Version %1").arg(qApp->applicationVersion()));
-
- setEnabled(false); // We disable the widgets to prevent any user interaction until the settings have loaded.
- setUpdatesEnabled(false);
-
- //
- // Connections
- //
-
- connect(ui.buttonBox , SIGNAL(clicked(QAbstractButton*)), this , SLOT(dialogButtonClicked(QAbstractButton*)));
- connect(ui.buttonBox , SIGNAL(accepted()) , this , SLOT(accepted()));
- connect(ui.buttonBox , SIGNAL(rejected()) , this , SLOT(rejected()));
- connect(ui.namingOptionsButton , SIGNAL(clicked()) , this , SLOT(namingOptions()));
-
- connect(ui.prefixLineEdit , SIGNAL(textChanged(QString)) , this , SLOT(updatePreview()));
- connect(ui.formatComboBox , SIGNAL(currentIndexChanged(int)) , this , SLOT(updatePreview()));
- connect(ui.namingComboBox , SIGNAL(currentIndexChanged(int)) , this , SLOT(updatePreview()));
-
- connect(ui.browsePushButton , SIGNAL(clicked()) , this , SLOT(browse()));
- connect(ui.checkUpdatesPushButton , SIGNAL(clicked()) , this , SLOT(checkUpdatesNow()));
- connect(ui.historyPushButton , SIGNAL(clicked()) , this , SLOT(viewHistory()));
-
- connect(ui.screenCheckBox , SIGNAL(toggled(bool)), ui.screenHotkeyWidget , SLOT(setEnabled(bool)));
- connect(ui.areaCheckBox , SIGNAL(toggled(bool)), ui.areaHotkeyWidget , SLOT(setEnabled(bool)));
- connect(ui.windowCheckBox , SIGNAL(toggled(bool)), ui.windowHotkeyWidget , SLOT(setEnabled(bool)));
- connect(ui.windowPickerCheckBox, SIGNAL(toggled(bool)), ui.windowPickerHotkeyWidget, SLOT(setEnabled(bool)));
- connect(ui.openCheckBox , SIGNAL(toggled(bool)), ui.openHotkeyWidget , SLOT(setEnabled(bool)));
- connect(ui.directoryCheckBox , SIGNAL(toggled(bool)), ui.directoryHotkeyWidget, SLOT(setEnabled(bool)));
-
- // "Save as" disables the file target input field.
- connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.targetLineEdit , SLOT(setDisabled(bool)));
- connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.browsePushButton , SLOT(setDisabled(bool)));
- connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.directoryLabel , SLOT(setDisabled(bool)));
-
- connect(ui.startupCheckBox , SIGNAL(toggled(bool)), ui.startupHideCheckBox , SLOT(setEnabled(bool)));
- connect(ui.qualitySlider , SIGNAL(valueChanged(int)), ui.qualityValueLabel, SLOT(setNum(int)));
- connect(ui.trayCheckBox , SIGNAL(toggled(bool)), ui.messageCheckBox , SLOT(setEnabled(bool)));
-
- // Auto-upload disables the default action button in the previews.
- connect(ui.uploadCheckBox , SIGNAL(toggled(bool)), ui.previewDefaultActionLabel , SLOT(setDisabled(bool)));
- connect(ui.uploadCheckBox , SIGNAL(toggled(bool)), ui.previewDefaultActionComboBox, SLOT(setDisabled(bool)));
- connect(ui.directoryCheckBox , SIGNAL(toggled(bool)), ui.directoryHotkeyWidget, SLOT(setEnabled(bool)));
-
- connect(ui.moreInformationLabel, SIGNAL(linkActivated(QString)) , this, SLOT(openUrl(QString)));
-
- connect(ui.languageComboBox , SIGNAL(currentIndexChanged(QString)), this, SLOT(languageChange(QString)));
-
- connect(ui.mainLabel , SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
- connect(ui.licenseAboutLabel, SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
- connect(ui.linksLabel, SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
-
- //
- // Languages
- //
-
- QDir languages(":/translations");
-
- ui.languageComboBox->addItem("English");
-
- foreach (QString language, languages.entryList()) {
- ui.languageComboBox->addItem(language);
- }
-}
-
-void OptionsDialog::namingOptions()
-{
- NamingDialog namingDialog((Screenshot::Naming) ui.namingComboBox->currentIndex());
-
- namingDialog.exec();
- flipToggled(settings()->value("options/flip").toBool());
- updatePreview();
-}
-
-QSettings *OptionsDialog::settings() const
-{
- return ScreenshotManager::instance()->settings();
-}
-
-/*
- * Slots
- */
-
void OptionsDialog::accepted()
{
if (hotkeyCollision()) {
QMessageBox::critical(this, tr("Hotkey conflict"), tr("You have assigned the same hotkeys to more than one action."));
return;
}
if (ui.prefixLineEdit->text().contains(QRegExp("[?:\\\\/*\"<>|]"))) {
QMessageBox::critical(this, tr("Filename character error"), tr("The filename can't contain any of the following characters: ? : \\ / * \" < > |"));
return;
}
if (!ui.fileGroupBox->isChecked() && !ui.clipboardCheckBox->isChecked()) {
QMessageBox::critical(this, tr("Final Destination"), tr("You can't take screenshots unless you enable either file saving or the clipboard."));
return;
}
saveSettings();
accept();
}
-void OptionsDialog::browse()
-{
- QString fileName = QFileDialog::getExistingDirectory(this,
- tr("Select where you want to save the screenshots"),
- ui.targetLineEdit->text());
-
- if (fileName.isEmpty())
- return;
-
- ui.targetLineEdit->setText(fileName);
-}
-
void OptionsDialog::checkUpdatesNow()
{
Updater::instance()->checkWithFeedback();
}
-void OptionsDialog::dialogButtonClicked(QAbstractButton *button)
+void OptionsDialog::languageChange(QString language)
{
- if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole) {
- QMessageBox msgBox;
- msgBox.setWindowTitle(tr("Lightscreen - Restore Default Options"));
- msgBox.setText(tr("Restoring the default options will cause you to lose all of your current configuration."));
- msgBox.setIcon(QMessageBox::Warning);
-
- QPushButton *restoreButton = msgBox.addButton(tr("Restore"), QMessageBox::ActionRole);
- QPushButton *dontRestoreButton = msgBox.addButton(tr("Don't Restore"), QMessageBox::ActionRole);
+ os::translate(language);
+}
- msgBox.setDefaultButton(dontRestoreButton);
- msgBox.exec();
+void OptionsDialog::loadSettings()
+{
+ settings()->sync();
+ os::translate(settings()->value("options/language").toString()); // Why? Don't ask me, I'm just the programmer.
- Q_UNUSED(restoreButton)
+ if (!settings()->contains("file/format")) {
+ // If there are no settings, get rid of the cancel button so that the user is forced to save them
+ ui.buttonBox->clear();
+ ui.buttonBox->addButton(QDialogButtonBox::Ok);
- if (msgBox.clickedButton() == dontRestoreButton)
- return;
+ // Move the first option window to the center of the screen, since Windows usually positions it in a random location since it has no visible parent.
+ if (!(static_cast<QWidget*>(parent())->isVisible()))
+ move(qApp->desktop()->screen(qApp->desktop()->primaryScreen())->rect().center()-QPoint(height()/2, width()/2));
+ }
- QString language = settings()->value("options/language").toString(); // Only mantain language.
+ ui.startupCheckBox->toggle();
+ ui.trayCheckBox->toggle();
+ ui.previewAutocloseCheckBox->toggle();
- settings()->clear();
- settings()->setValue("options/language", language);
+ QString targetDefault;
- loadSettings();
+ if (ScreenshotManager::instance()->portableMode()) {
+ targetDefault = tr("Screenshots");
+ }
+ else {
+ targetDefault = os::getDocumentsPath() + QDir::separator() + tr("Screenshots");
}
-}
-void OptionsDialog::flipToggled(bool checked)
-{
- setUpdatesEnabled(false);
+ settings()->beginGroup("file");
+ ui.formatComboBox->setCurrentIndex(settings()->value("format", 1).toInt());
+ ui.prefixLineEdit->setText(settings()->value("prefix", tr("screenshot.")).toString());
+ ui.namingComboBox->setCurrentIndex(settings()->value("naming", 0).toInt());
+ ui.targetLineEdit->setText(settings()->value("target", targetDefault).toString());
+ ui.fileGroupBox->setChecked(settings()->value("enabled", true).toBool());
+ settings()->endGroup();
- ui.filenameLayout->removeWidget(ui.prefixLineEdit);
- ui.filenameLayout->removeWidget(ui.namingComboBox);
+ settings()->beginGroup("options");
+ ui.startupCheckBox->setChecked(settings()->value("startup", false).toBool());
+ ui.startupHideCheckBox->setChecked(settings()->value("startupHide", true).toBool());
+ ui.hideCheckBox->setChecked(settings()->value("hide", true).toBool());
+ ui.delaySpinBox->setValue(settings()->value("delay", 0).toInt());
+ flipToggled(settings()->value("flip", false).toBool());
+ ui.trayCheckBox->setChecked(settings()->value("tray", true).toBool());
+ ui.messageCheckBox->setChecked(settings()->value("message", true).toBool());
+ ui.qualitySlider->setValue(settings()->value("quality", 100).toInt());
+ ui.playSoundCheckBox->setChecked(settings()->value("playSound", false).toBool());
+ ui.updaterCheckBox->setChecked(!settings()->value("disableUpdater", false).toBool());
+ ui.magnifyCheckBox->setChecked(settings()->value("magnify", true).toBool());
+ ui.cursorCheckBox->setChecked(settings()->value("cursor", false).toBool());
+ ui.saveAsCheckBox->setChecked(settings()->value("saveAs", false).toBool());
+ ui.previewGroupBox->setChecked(settings()->value("preview", false).toBool());
+ ui.previewSizeSpinBox->setValue(settings()->value("previewSize", 300).toInt());
+ ui.previewPositionComboBox->setCurrentIndex(settings()->value("previewPosition", 3).toInt());
+ ui.previewAutocloseCheckBox->setChecked(settings()->value("previewAutoclose", false).toBool());
+ ui.previewAutocloseTimeSpinBox->setValue(settings()->value("previewAutocloseTime", 15).toInt());
+ ui.previewAutocloseActionComboBox->setCurrentIndex(settings()->value("previewAutocloseAction", 0).toInt());
+ ui.previewDefaultActionComboBox->setCurrentIndex(settings()->value("previewDefaultAction", 0).toInt());
+ ui.areaAutocloseCheckBox->setChecked(settings()->value("areaAutoclose", false).toBool());
+ ui.historyCheckBox->setChecked(settings()->value("history", true).toBool());
- if (checked) {
- ui.filenameLayout->addWidget(ui.namingComboBox);
- ui.filenameLayout->addWidget(ui.prefixLineEdit);
+ // Advanced
+ ui.clipboardCheckBox->setChecked(settings()->value("clipboard", true).toBool());
+ ui.optiPngCheckBox->setChecked(settings()->value("optipng", true).toBool());
+ ui.warnHideCheckBox->setChecked(!settings()->value("disableHideAlert", false).toBool());
+ ui.currentMonitorCheckBox->setChecked(settings()->value("currentMonitor", false).toBool());
+ ui.replaceCheckBox->setChecked(settings()->value("replace", false).toBool());
+ ui.uploadCheckBox->setChecked(settings()->value("uploadAuto", false).toBool());
+
+#ifdef Q_WS_WIN
+ if (!QFile::exists(qApp->applicationDirPath() + QDir::separator() + "optipng.exe")) {
+ ui.optiPngCheckBox->setEnabled(false);
+ ui.optiPngLabel->setText("optipng.exe not found");
}
- else {
- ui.filenameLayout->addWidget(ui.prefixLineEdit);
- ui.filenameLayout->addWidget(ui.namingComboBox);
+#elif defined(Q_WS_X11)
+ if (!QProcess::startDetached("optipng")) {
+ ui.optiPngCheckBox->setChecked(false);
+ ui.optiPngCheckBox->setEnabled(false);
+ ui.optiPngLabel->setText(tr("Install 'OptiPNG'"));
}
- if (ui.prefixLineEdit->text() == tr("screenshot.")
- && checked)
- ui.prefixLineEdit->setText(tr(".screenshot"));
+ //TODO: Sound cue support on Linux
+ ui.playSoundCheckBox->setVisible(false);
+ ui.playSoundCheckBox->setChecked(false);
- if (ui.prefixLineEdit->text() == tr(".screenshot")
- && !checked)
- ui.prefixLineEdit->setText(tr("screenshot."));
+ //TODO: Cursor support on X11
+ ui.cursorCheckBox->setVisible(false);
+ ui.cursorCheckBox->setChecked(false);
+#endif
- setUpdatesEnabled(true); // Avoids flicker
-}
+ //TODO: Must replace with not-stupid system
+ QString lang = settings()->value("language").toString();
+ int index = ui.languageComboBox->findText(lang);
-void OptionsDialog::languageChange(QString language)
-{
- os::translate(language);
+ if (index == -1)
+ index = ui.languageComboBox->findText("English");
+
+ ui.languageComboBox->setCurrentIndex(index);
+
+ settings()->endGroup();
+
+ settings()->beginGroup("actions");
+
+ // This toggle is for the first run
+ ui.screenCheckBox->toggle();
+ ui.areaCheckBox->toggle();
+ ui.windowCheckBox->toggle();
+ ui.windowPickerCheckBox->toggle();
+ ui.openCheckBox->toggle();
+ ui.directoryCheckBox->toggle();
+
+ settings()->beginGroup("screen");
+ ui.screenCheckBox->setChecked(settings()->value("enabled", true).toBool());
+ ui.screenHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::Key_Print)).value<QKeySequence> ());
+ settings()->endGroup();
+
+ settings()->beginGroup("area");
+ ui.areaCheckBox->setChecked(settings()->value("enabled").toBool());
+ ui.areaHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::Key_Print)).value<QKeySequence> ());
+ settings()->endGroup();
+
+ settings()->beginGroup("window");
+ ui.windowCheckBox->setChecked(settings()->value("enabled").toBool());
+ ui.windowHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::ALT + Qt::Key_Print)).value<QKeySequence> ());
+ settings()->endGroup();
+
+ settings()->beginGroup("windowPicker");
+ ui.windowPickerCheckBox->setChecked(settings()->value("enabled").toBool());
+ ui.windowPickerHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Print)).value<QKeySequence> ());
+ settings()->endGroup();
+
+ settings()->beginGroup("open");
+ ui.openCheckBox->setChecked(settings()->value("enabled").toBool());
+ ui.openHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::Key_PageUp)).value<QKeySequence> ());
+ settings()->endGroup();
+
+ settings()->beginGroup("directory");
+ ui.directoryCheckBox->setChecked(settings()->value("enabled").toBool());
+ ui.directoryHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::SHIFT + Qt::Key_PageUp)).value<QKeySequence> ());
+ settings()->endGroup();
+
+ settings()->endGroup();
+
+ QTimer::singleShot(0, this, SLOT(updatePreview()));
+
+ setEnabled(true);
+ setUpdatesEnabled(true);
}
void OptionsDialog::openUrl(QString url)
{
if (url == "#aboutqt") {
qApp->aboutQt();
}
else {
QDesktopServices::openUrl(QUrl(url));
}
}
void OptionsDialog::rejected()
{
languageChange(settings()->value("options/language").toString()); // Revert language to default.
}
void OptionsDialog::saveSettings()
{
settings()->beginGroup("file");
settings()->setValue("format", ui.formatComboBox->currentIndex());
settings()->setValue("prefix", ui.prefixLineEdit->text());
settings()->setValue("naming", ui.namingComboBox->currentIndex());
settings()->setValue("target", ui.targetLineEdit->text());
settings()->setValue("enabled", ui.fileGroupBox->isChecked());
settings()->endGroup();
settings()->beginGroup("options");
settings()->setValue("startup", ui.startupCheckBox->isChecked());
settings()->setValue("startupHide", ui.startupHideCheckBox->isChecked());
settings()->setValue("hide", ui.hideCheckBox->isChecked());
settings()->setValue("delay", ui.delaySpinBox->value());
settings()->setValue("tray", ui.trayCheckBox->isChecked());
settings()->setValue("message", ui.messageCheckBox->isChecked());
settings()->setValue("quality", ui.qualitySlider->value());
settings()->setValue("playSound", ui.playSoundCheckBox->isChecked());
// We save the explicit string because addition/removal of language files can cause it to change
settings()->setValue("language", ui.languageComboBox->currentText());
// This settings is inverted because the first iteration of the Updater did not have a settings but instead relied on the messagebox choice of the user.
settings()->setValue("disableUpdater", !ui.updaterCheckBox->isChecked());
settings()->setValue("magnify", ui.magnifyCheckBox->isChecked());
settings()->setValue("cursor", ui.cursorCheckBox->isChecked());
settings()->setValue("saveAs", ui.saveAsCheckBox->isChecked());
settings()->setValue("preview", ui.previewGroupBox->isChecked());
settings()->setValue("previewSize", ui.previewSizeSpinBox->value());
settings()->setValue("previewPosition", ui.previewPositionComboBox->currentIndex());
settings()->setValue("previewAutoclose", ui.previewAutocloseCheckBox->isChecked());
settings()->setValue("previewAutocloseTime", ui.previewAutocloseTimeSpinBox->value());
settings()->setValue("previewAutocloseAction", ui.previewAutocloseActionComboBox->currentIndex());
settings()->setValue("previewDefaultAction", ui.previewDefaultActionComboBox->currentIndex());
settings()->setValue("areaAutoclose", ui.areaAutocloseCheckBox->isChecked());
settings()->setValue("history", ui.historyCheckBox->isChecked());
// Advanced
settings()->setValue("disableHideAlert", !ui.warnHideCheckBox->isChecked());
settings()->setValue("clipboard", ui.clipboardCheckBox->isChecked());
settings()->setValue("optipng", ui.optiPngCheckBox->isChecked());
settings()->setValue("currentMonitor", ui.currentMonitorCheckBox->isChecked());
settings()->setValue("replace", ui.replaceCheckBox->isChecked());
//Upload
settings()->setValue("uploadAuto", ui.uploadCheckBox->isChecked());
settings()->endGroup();
settings()->beginGroup("actions");
settings()->beginGroup("screen");
settings()->setValue("enabled", ui.screenCheckBox->isChecked());
settings()->setValue("hotkey", ui.screenHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("area");
settings()->setValue("enabled", ui.areaCheckBox->isChecked());
settings()->setValue("hotkey", ui.areaHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("window");
settings()->setValue("enabled", ui.windowCheckBox->isChecked());
settings()->setValue("hotkey", ui.windowHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("windowPicker");
settings()->setValue("enabled", ui.windowPickerCheckBox->isChecked());
settings()->setValue("hotkey", ui.windowPickerHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("open");
settings()->setValue("enabled", ui.openCheckBox->isChecked());
settings()->setValue("hotkey", ui.openHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("directory");
settings()->setValue("enabled", ui.directoryCheckBox->isChecked());
settings()->setValue("hotkey", ui.directoryHotkeyWidget->hotkey());
settings()->endGroup();
settings()->endGroup();
}
-/*
- * Private
- */
-void OptionsDialog::loadSettings()
+void OptionsDialog::updatePreview()
{
- settings()->sync();
- os::translate(settings()->value("options/language").toString()); // Why? Don't ask me, I'm just the programmer.
+ Screenshot::NamingOptions options;
- if (!settings()->contains("file/format")) {
- // If there are no settings, get rid of the cancel button so that the user is forced to save them
- ui.buttonBox->clear();
- ui.buttonBox->addButton(QDialogButtonBox::Ok);
+ options.naming = (Screenshot::Naming)ui.namingComboBox->currentIndex();
+ options.flip = settings()->value("options/flip").toBool();
+ options.leadingZeros = settings()->value("options/naming/leadingZeros").toInt();
+ options.dateFormat = settings()->value("options/naming/dateFormat").toString();
- // Move the first option window to the center of the screen, since Windows usually positions it in a random location since it has no visible parent.
- if (!(static_cast<QWidget*>(parent())->isVisible()))
- move(qApp->desktop()->screen(qApp->desktop()->primaryScreen())->rect().center()-QPoint(height()/2, width()/2));
+ ui.namingOptionsButton->setDisabled((options.naming == Screenshot::Empty));
+
+ QString preview = Screenshot::getName(options,
+ ui.prefixLineEdit->text(),
+ QDir(ui.targetLineEdit->text()));
+
+ preview = QString("%1.%2").arg(preview).arg(ui.formatComboBox->currentText().toLower());
+
+ if (preview.length() >= 40) {
+ preview.truncate(37);
+ preview.append("...");
}
- ui.startupCheckBox->toggle();
- ui.trayCheckBox->toggle();
- ui.previewAutocloseCheckBox->toggle();
+ ui.previewLabel->setText(preview);
+}
+
+void OptionsDialog::viewHistory()
+{
+ HistoryDialog historyDialog(this);
+ historyDialog.exec();
+}
+
+//
+
+bool OptionsDialog::event(QEvent* event)
+{
+ if (event->type() == QEvent::LanguageChange) {
+
+ // ComboBoxes revert to the first index when translated:
+ int naming = ui.namingComboBox->currentIndex();
+ int format = ui.formatComboBox->currentIndex();
+ int previewPosition = ui.previewPositionComboBox->currentIndex();
+ int previewAutoclose = ui.previewAutocloseActionComboBox->currentIndex();
+ int previewDefault = ui.previewDefaultActionComboBox->currentIndex();
+
+ ui.retranslateUi(this);
+
+ // Restoring comboboxes
+ ui.namingComboBox->setCurrentIndex(naming);
+ ui.formatComboBox->setCurrentIndex(format);
+ ui.previewPositionComboBox->setCurrentIndex(previewPosition);
+ ui.previewAutocloseActionComboBox->setCurrentIndex(previewAutoclose);
+ ui.previewDefaultActionComboBox->setCurrentIndex(previewDefault);
+
+ updatePreview();
+ resize(minimumSizeHint());
+ }
+ else if (event->type() == QEvent::Close) {
+ if (!settings()->contains("file/format")) {
+ // I'm afraid I can't let you do that, Dave.
+ event->ignore();
+ return false;
+ }
+ }
+
+ return QDialog::event(event);
+}
+
+#ifdef Q_WS_WIN
+// Qt does not send the print screen key as a regular QKeyPress event, so we must use the Windows API
+bool OptionsDialog::winEvent(MSG *message, long *result)
+{
+ if ((message->message == WM_KEYUP || message->message == WM_SYSKEYUP)
+ && message->wParam == VK_SNAPSHOT) {
+ qApp->postEvent(qApp->focusWidget(), new QKeyEvent(QEvent::KeyPress, Qt::Key_Print, qApp->keyboardModifiers()));
+ }
+
+ return QDialog::winEvent(message, result);
+}
+#endif
+
+//
+
+void OptionsDialog::browse()
+{
+ QString fileName = QFileDialog::getExistingDirectory(this,
+ tr("Select where you want to save the screenshots"),
+ ui.targetLineEdit->text());
+
+ if (fileName.isEmpty())
+ return;
+
+ ui.targetLineEdit->setText(fileName);
+}
+
+void OptionsDialog::dialogButtonClicked(QAbstractButton *button)
+{
+ if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole) {
+ QMessageBox msgBox;
+ msgBox.setWindowTitle(tr("Lightscreen - Restore Default Options"));
+ msgBox.setText(tr("Restoring the default options will cause you to lose all of your current configuration."));
+ msgBox.setIcon(QMessageBox::Warning);
+
+ QPushButton *restoreButton = msgBox.addButton(tr("Restore"), QMessageBox::ActionRole);
+ QPushButton *dontRestoreButton = msgBox.addButton(tr("Don't Restore"), QMessageBox::ActionRole);
+
+ msgBox.setDefaultButton(dontRestoreButton);
+ msgBox.exec();
+
+ Q_UNUSED(restoreButton)
+
+ if (msgBox.clickedButton() == dontRestoreButton)
+ return;
+
+ QString language = settings()->value("options/language").toString(); // Only mantain language.
+
+ settings()->clear();
+ settings()->setValue("options/language", language);
+
+ loadSettings();
+ }
+}
+
+void OptionsDialog::flipToggled(bool checked)
+{
+ setUpdatesEnabled(false);
+
+ ui.filenameLayout->removeWidget(ui.prefixLineEdit);
+ ui.filenameLayout->removeWidget(ui.namingComboBox);
+
+ if (checked) {
+ ui.filenameLayout->addWidget(ui.namingComboBox);
+ ui.filenameLayout->addWidget(ui.prefixLineEdit);
+ }
+ else {
+ ui.filenameLayout->addWidget(ui.prefixLineEdit);
+ ui.filenameLayout->addWidget(ui.namingComboBox);
+ }
+
+ if (ui.prefixLineEdit->text() == tr("screenshot.")
+ && checked)
+ ui.prefixLineEdit->setText(tr(".screenshot"));
- QString targetDefault;
+ if (ui.prefixLineEdit->text() == tr(".screenshot")
+ && !checked)
+ ui.prefixLineEdit->setText(tr("screenshot."));
- if (ScreenshotManager::instance()->portableMode()) {
- targetDefault = tr("Screenshots");
- }
- else {
- targetDefault = os::getDocumentsPath() + QDir::separator() + tr("Screenshots");
- }
+ setUpdatesEnabled(true); // Avoids flicker
+}
- settings()->beginGroup("file");
- ui.formatComboBox->setCurrentIndex(settings()->value("format", 1).toInt());
- ui.prefixLineEdit->setText(settings()->value("prefix", tr("screenshot.")).toString());
- ui.namingComboBox->setCurrentIndex(settings()->value("naming", 0).toInt());
- ui.targetLineEdit->setText(settings()->value("target", targetDefault).toString());
- ui.fileGroupBox->setChecked(settings()->value("enabled", true).toBool());
- settings()->endGroup();
+void OptionsDialog::init()
+{
+ // Make the scroll area share the Tab Widget background color
+ QPalette optionsPalette = ui.optionsScrollArea->palette();
+ optionsPalette.setColor(QPalette::Window, ui.tabWidget->palette().color(QPalette::Base));
+ ui.optionsScrollArea->setPalette(optionsPalette);
- settings()->beginGroup("options");
- ui.startupCheckBox->setChecked(settings()->value("startup", false).toBool());
- ui.startupHideCheckBox->setChecked(settings()->value("startupHide", true).toBool());
- ui.hideCheckBox->setChecked(settings()->value("hide", true).toBool());
- ui.delaySpinBox->setValue(settings()->value("delay", 0).toInt());
- flipToggled(settings()->value("flip", false).toBool());
- ui.trayCheckBox->setChecked(settings()->value("tray", true).toBool());
- ui.messageCheckBox->setChecked(settings()->value("message", true).toBool());
- ui.qualitySlider->setValue(settings()->value("quality", 100).toInt());
- ui.playSoundCheckBox->setChecked(settings()->value("playSound", false).toBool());
- ui.updaterCheckBox->setChecked(!settings()->value("disableUpdater", false).toBool());
- ui.magnifyCheckBox->setChecked(settings()->value("magnify", true).toBool());
- ui.cursorCheckBox->setChecked(settings()->value("cursor", false).toBool());
- ui.saveAsCheckBox->setChecked(settings()->value("saveAs", false).toBool());
- ui.previewGroupBox->setChecked(settings()->value("preview", false).toBool());
- ui.previewSizeSpinBox->setValue(settings()->value("previewSize", 300).toInt());
- ui.previewPositionComboBox->setCurrentIndex(settings()->value("previewPosition", 3).toInt());
- ui.previewAutocloseCheckBox->setChecked(settings()->value("previewAutoclose", false).toBool());
- ui.previewAutocloseTimeSpinBox->setValue(settings()->value("previewAutocloseTime", 15).toInt());
- ui.previewAutocloseActionComboBox->setCurrentIndex(settings()->value("previewAutocloseAction", 0).toInt());
- ui.previewDefaultActionComboBox->setCurrentIndex(settings()->value("previewDefaultAction", 0).toInt());
- ui.areaAutocloseCheckBox->setChecked(settings()->value("areaAutoclose", false).toBool());
- ui.historyCheckBox->setChecked(settings()->value("history", true).toBool());
+ ui.buttonBox->addButton(new QPushButton(" " + tr("Restore Defaults") + " ", this), QDialogButtonBox::ResetRole);
- // Advanced
- ui.clipboardCheckBox->setChecked(settings()->value("clipboard", true).toBool());
- ui.optiPngCheckBox->setChecked(settings()->value("optipng", true).toBool());
- ui.warnHideCheckBox->setChecked(!settings()->value("disableHideAlert", false).toBool());
- ui.currentMonitorCheckBox->setChecked(settings()->value("currentMonitor", false).toBool());
- ui.replaceCheckBox->setChecked(settings()->value("replace", false).toBool());
- ui.uploadCheckBox->setChecked(settings()->value("uploadAuto", false).toBool());
+ // Set up the autocomplete for the directory.
+ QCompleter *completer = new QCompleter(this);
+ completer->setModel(new QDirModel(QStringList(), QDir::Dirs, QDir::Name, completer));
+ ui.targetLineEdit->setCompleter(completer);
-#ifdef Q_WS_WIN
- if (!QFile::exists(qApp->applicationDirPath() + QDir::separator() + "optipng.exe")) {
- ui.optiPngCheckBox->setEnabled(false);
- ui.optiPngLabel->setText("optipng.exe not found");
- }
-#elif defined(Q_WS_X11)
- if (!QProcess::startDetached("optipng")) {
- ui.optiPngCheckBox->setChecked(false);
- ui.optiPngCheckBox->setEnabled(false);
- ui.optiPngLabel->setText(tr("Install 'OptiPNG'"));
- }
+ // HotkeyWidget icons.
+ ui.screenHotkeyWidget->setIcon (QIcon(":/icons/screen"));
+ ui.windowHotkeyWidget->setIcon (QIcon(":/icons/window"));
+ ui.windowPickerHotkeyWidget->setIcon(QIcon(":/icons/picker"));
+ ui.areaHotkeyWidget->setIcon (QIcon(":/icons/area"));
+ ui.openHotkeyWidget->setIcon (QIcon(":/icons/lightscreen.small"));
+ ui.directoryHotkeyWidget->setIcon (QIcon(":/icons/folder"));
- //TODO: Sound cue support on Linux
- ui.playSoundCheckBox->setVisible(false);
- ui.playSoundCheckBox->setChecked(false);
+ // Version
+ ui.versionLabel->setText(tr("Version %1").arg(qApp->applicationVersion()));
- //TODO: Cursor support on X11
- ui.cursorCheckBox->setVisible(false);
- ui.cursorCheckBox->setChecked(false);
-#endif
+ setEnabled(false); // We disable the widgets to prevent any user interaction until the settings have loaded.
+ setUpdatesEnabled(false);
- //TODO: Must replace with not-stupid system
- QString lang = settings()->value("language").toString();
- int index = ui.languageComboBox->findText(lang);
+ //
+ // Connections
+ //
- if (index == -1)
- index = ui.languageComboBox->findText("English");
+ connect(ui.buttonBox , SIGNAL(clicked(QAbstractButton*)), this , SLOT(dialogButtonClicked(QAbstractButton*)));
+ connect(ui.buttonBox , SIGNAL(accepted()) , this , SLOT(accepted()));
+ connect(ui.buttonBox , SIGNAL(rejected()) , this , SLOT(rejected()));
+ connect(ui.namingOptionsButton , SIGNAL(clicked()) , this , SLOT(namingOptions()));
- ui.languageComboBox->setCurrentIndex(index);
+ connect(ui.prefixLineEdit , SIGNAL(textChanged(QString)) , this , SLOT(updatePreview()));
+ connect(ui.formatComboBox , SIGNAL(currentIndexChanged(int)) , this , SLOT(updatePreview()));
+ connect(ui.namingComboBox , SIGNAL(currentIndexChanged(int)) , this , SLOT(updatePreview()));
- settings()->endGroup();
+ connect(ui.browsePushButton , SIGNAL(clicked()) , this , SLOT(browse()));
+ connect(ui.checkUpdatesPushButton , SIGNAL(clicked()) , this , SLOT(checkUpdatesNow()));
+ connect(ui.historyPushButton , SIGNAL(clicked()) , this , SLOT(viewHistory()));
- settings()->beginGroup("actions");
+ connect(ui.screenCheckBox , SIGNAL(toggled(bool)), ui.screenHotkeyWidget , SLOT(setEnabled(bool)));
+ connect(ui.areaCheckBox , SIGNAL(toggled(bool)), ui.areaHotkeyWidget , SLOT(setEnabled(bool)));
+ connect(ui.windowCheckBox , SIGNAL(toggled(bool)), ui.windowHotkeyWidget , SLOT(setEnabled(bool)));
+ connect(ui.windowPickerCheckBox, SIGNAL(toggled(bool)), ui.windowPickerHotkeyWidget, SLOT(setEnabled(bool)));
+ connect(ui.openCheckBox , SIGNAL(toggled(bool)), ui.openHotkeyWidget , SLOT(setEnabled(bool)));
+ connect(ui.directoryCheckBox , SIGNAL(toggled(bool)), ui.directoryHotkeyWidget, SLOT(setEnabled(bool)));
- // This toggle is for the first run
- ui.screenCheckBox->toggle();
- ui.areaCheckBox->toggle();
- ui.windowCheckBox->toggle();
- ui.windowPickerCheckBox->toggle();
- ui.openCheckBox->toggle();
- ui.directoryCheckBox->toggle();
+ // "Save as" disables the file target input field.
+ connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.targetLineEdit , SLOT(setDisabled(bool)));
+ connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.browsePushButton , SLOT(setDisabled(bool)));
+ connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.directoryLabel , SLOT(setDisabled(bool)));
- settings()->beginGroup("screen");
- ui.screenCheckBox->setChecked(settings()->value("enabled", true).toBool());
- ui.screenHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::Key_Print)).value<QKeySequence> ());
- settings()->endGroup();
+ connect(ui.startupCheckBox , SIGNAL(toggled(bool)), ui.startupHideCheckBox , SLOT(setEnabled(bool)));
+ connect(ui.qualitySlider , SIGNAL(valueChanged(int)), ui.qualityValueLabel, SLOT(setNum(int)));
+ connect(ui.trayCheckBox , SIGNAL(toggled(bool)), ui.messageCheckBox , SLOT(setEnabled(bool)));
- settings()->beginGroup("area");
- ui.areaCheckBox->setChecked(settings()->value("enabled").toBool());
- ui.areaHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::Key_Print)).value<QKeySequence> ());
- settings()->endGroup();
+ // Auto-upload disables the default action button in the previews.
+ connect(ui.uploadCheckBox , SIGNAL(toggled(bool)), ui.previewDefaultActionLabel , SLOT(setDisabled(bool)));
+ connect(ui.uploadCheckBox , SIGNAL(toggled(bool)), ui.previewDefaultActionComboBox, SLOT(setDisabled(bool)));
+ connect(ui.directoryCheckBox , SIGNAL(toggled(bool)), ui.directoryHotkeyWidget, SLOT(setEnabled(bool)));
- settings()->beginGroup("window");
- ui.windowCheckBox->setChecked(settings()->value("enabled").toBool());
- ui.windowHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::ALT + Qt::Key_Print)).value<QKeySequence> ());
- settings()->endGroup();
+ connect(ui.moreInformationLabel, SIGNAL(linkActivated(QString)) , this, SLOT(openUrl(QString)));
- settings()->beginGroup("windowPicker");
- ui.windowPickerCheckBox->setChecked(settings()->value("enabled").toBool());
- ui.windowPickerHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Print)).value<QKeySequence> ());
- settings()->endGroup();
+ connect(ui.languageComboBox , SIGNAL(currentIndexChanged(QString)), this, SLOT(languageChange(QString)));
- settings()->beginGroup("open");
- ui.openCheckBox->setChecked(settings()->value("enabled").toBool());
- ui.openHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::Key_PageUp)).value<QKeySequence> ());
- settings()->endGroup();
+ connect(ui.mainLabel , SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
+ connect(ui.licenseAboutLabel, SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
+ connect(ui.linksLabel, SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
- settings()->beginGroup("directory");
- ui.directoryCheckBox->setChecked(settings()->value("enabled").toBool());
- ui.directoryHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::SHIFT + Qt::Key_PageUp)).value<QKeySequence> ());
- settings()->endGroup();
+ //
+ // Languages
+ //
- settings()->endGroup();
+ QDir languages(":/translations");
- QTimer::singleShot(0, this, SLOT(updatePreview()));
+ ui.languageComboBox->addItem("English");
- setEnabled(true);
- setUpdatesEnabled(true);
+ foreach (QString language, languages.entryList()) {
+ ui.languageComboBox->addItem(language);
+ }
}
-void OptionsDialog::viewHistory()
+void OptionsDialog::namingOptions()
{
- HistoryDialog historyDialog(this);
- historyDialog.exec();
+ NamingDialog namingDialog((Screenshot::Naming) ui.namingComboBox->currentIndex());
+
+ namingDialog.exec();
+ flipToggled(settings()->value("options/flip").toBool());
+ updatePreview();
}
+//
+
bool OptionsDialog::hotkeyCollision()
{
// Check for hotkey collision (there's probably a better way to do this...=)
if (ui.screenCheckBox->isChecked()) {
if (ui.screenHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.areaCheckBox->isChecked()) {
if (ui.areaHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.windowCheckBox->isChecked()) {
if (ui.windowHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.openCheckBox->isChecked()) {
if (ui.openHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.directoryCheckBox->isChecked()) {
if (ui.directoryHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
}
return false;
}
-void OptionsDialog::updatePreview()
-{
- Screenshot::NamingOptions options;
-
- options.naming = (Screenshot::Naming)ui.namingComboBox->currentIndex();
- options.flip = settings()->value("options/flip").toBool();
- options.leadingZeros = settings()->value("options/naming/leadingZeros").toInt();
- options.dateFormat = settings()->value("options/naming/dateFormat").toString();
-
- ui.namingOptionsButton->setDisabled((options.naming == Screenshot::Empty));
-
- QString preview = Screenshot::getName(options,
- ui.prefixLineEdit->text(),
- QDir(ui.targetLineEdit->text()));
-
- preview = QString("%1.%2").arg(preview).arg(ui.formatComboBox->currentText().toLower());
-
- if (preview.length() >= 40) {
- preview.truncate(37);
- preview.append("...");
- }
-
- ui.previewLabel->setText(preview);
-}
-
-bool OptionsDialog::event(QEvent* event)
-{
- if (event->type() == QEvent::LanguageChange) {
-
- // ComboBoxes revert to the first index when translated:
- int naming = ui.namingComboBox->currentIndex();
- int format = ui.formatComboBox->currentIndex();
- int previewPosition = ui.previewPositionComboBox->currentIndex();
- int previewAutoclose = ui.previewAutocloseActionComboBox->currentIndex();
- int previewDefault = ui.previewDefaultActionComboBox->currentIndex();
-
- ui.retranslateUi(this);
-
- // Restoring comboboxes
- ui.namingComboBox->setCurrentIndex(naming);
- ui.formatComboBox->setCurrentIndex(format);
- ui.previewPositionComboBox->setCurrentIndex(previewPosition);
- ui.previewAutocloseActionComboBox->setCurrentIndex(previewAutoclose);
- ui.previewDefaultActionComboBox->setCurrentIndex(previewDefault);
-
- updatePreview();
- resize(minimumSizeHint());
- }
- else if (event->type() == QEvent::Close) {
- if (!settings()->contains("file/format")) {
- // I'm afraid I can't let you do that, Dave.
- event->ignore();
- return false;
- }
- }
-
- return QDialog::event(event);
-}
-
-#ifdef Q_WS_WIN
-// Qt does not send the print screen key as a regular QKeyPress event, so we must use the Windows API
-bool OptionsDialog::winEvent(MSG *message, long *result)
+QSettings *OptionsDialog::settings() const
{
- if ((message->message == WM_KEYUP || message->message == WM_SYSKEYUP)
- && message->wParam == VK_SNAPSHOT) {
- qApp->postEvent(qApp->focusWidget(), new QKeyEvent(QEvent::KeyPress, Qt::Key_Print, qApp->keyboardModifiers()));
- }
-
- return QDialog::winEvent(message, result);
+ return ScreenshotManager::instance()->settings();
}
-#endif
diff --git a/dialogs/optionsdialog.h b/dialogs/optionsdialog.h
index c717039..228cdea 100644
--- a/dialogs/optionsdialog.h
+++ b/dialogs/optionsdialog.h
@@ -1,68 +1,68 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef OPTIONSDIALOG_H
#define OPTIONSDIALOG_H
#include <QtGui/QDialog>
#include "../updater/updater.h"
#include "ui_optionsdialog.h"
class QSettings;
class QAbstractButton;
class OptionsDialog : public QDialog
{
Q_OBJECT
public:
OptionsDialog(QWidget *parent = 0);
public slots:
void accepted();
void checkUpdatesNow();
void languageChange(QString language);
+ void loadSettings();
void openUrl(QString url);
void rejected();
void saveSettings();
void updatePreview();
- void loadSettings();
void viewHistory();
protected:
bool event(QEvent *event);
#ifdef Q_WS_WIN
bool winEvent(MSG *message, long *result);
#endif
private slots:
- void namingOptions();
- void flipToggled(bool checked);
- void dialogButtonClicked(QAbstractButton *button);
void browse();
+ void dialogButtonClicked(QAbstractButton *button);
+ void flipToggled(bool checked);
void init();
+ void namingOptions();
private:
bool hotkeyCollision();
QSettings *settings() const;
private:
Ui::OptionsDialog ui;
};
#endif // OPTIONSDIALOG_H
diff --git a/dialogs/previewdialog.cpp b/dialogs/previewdialog.cpp
index bc86930..27ff2d8 100644
--- a/dialogs/previewdialog.cpp
+++ b/dialogs/previewdialog.cpp
@@ -1,402 +1,407 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "previewdialog.h"
#include "screenshotdialog.h"
#include "../tools/screenshot.h"
#include "../tools/screenshotmanager.h"
#include "../tools/os.h"
#include <QApplication>
-#include <QObject>
-#include <QList>
-#include <QHBoxLayout>
-#include <QIcon>
-#include <QPushButton>
-#include <QPalette>
#include <QDesktopWidget>
#include <QGraphicsDropShadowEffect>
+#include <QHBoxLayout>
+#include <QIcon>
#include <QLabel>
-#include <QStackedLayout>
+#include <QList>
+#include <QMenu>
+#include <QObject>
+#include <QPalette>
+#include <QPushButton>
#include <QSettings>
+#include <QStackedLayout>
#include <QToolButton>
-#include <QMenu>
#include <QDebug>
PreviewDialog::PreviewDialog(QWidget *parent) :
QDialog(parent), mAutoclose(0)
{
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
os::aeroGlass(this);
setWindowTitle(tr("Screenshot Preview"));
QSettings *settings = ScreenshotManager::instance()->settings();
mSize = settings->value("options/previewSize", 300).toInt();
mPosition = settings->value("options/previewPosition", 3).toInt();
if (settings->value("options/previewAutoclose", false).toBool()) {
mAutoclose = settings->value("options/previewAutocloseTime").toInt();
mAutocloseReset = mAutoclose;
mAutocloseAction = settings->value("options/previewAutocloseAction").toInt();
}
QHBoxLayout *l = new QHBoxLayout;
mStack = new QStackedLayout;
connect(mStack, SIGNAL(currentChanged(int)), this, SLOT(indexChanged(int)));
mPrevButton = new QPushButton(QIcon(":/icons/arrow-left"), "", this);
connect(mPrevButton, SIGNAL(clicked()), this, SLOT(previous()));
mNextButton = new QPushButton(QIcon(":/icons/arrow-right"), "", this);
connect(mNextButton, SIGNAL(clicked()), this, SLOT(next()));
mPrevButton->setCursor(Qt::PointingHandCursor);
mPrevButton->setFlat(true);
mPrevButton->setGraphicsEffect(os::shadow());
mPrevButton->setIconSize(QSize(24, 24));
mPrevButton->setVisible(false);
mNextButton->setCursor(Qt::PointingHandCursor);
mNextButton->setFlat(true);
mNextButton->setGraphicsEffect(os::shadow());
mNextButton->setIconSize(QSize(24, 24));
mNextButton->setVisible(false);
l->addWidget(mPrevButton);
l->addLayout(mStack);
l->addWidget(mNextButton);
l->setMargin(0);
l->setContentsMargins(6, 6, 6, 6);
mStack->setMargin(0);
setMaximumHeight(mSize);
setLayout(l);
if (mAutoclose) {
startTimer(1000);
}
}
void PreviewDialog::add(Screenshot *screenshot)
{
if (!isVisible()) {
show();
}
if (mAutoclose) {
mAutoclose = mAutocloseReset;
}
QLabel *label = new QLabel(this);
label->setGraphicsEffect(os::shadow());
bool small = false;
connect(label, SIGNAL(destroyed()), screenshot, SLOT(discard()));
QSize size = screenshot->pixmap().size();
if (size.width() > mSize || size.height() > mSize) {
size.scale(mSize, mSize, Qt::KeepAspectRatio);
}
else {
small = true;
}
QPixmap thumbnail = screenshot->pixmap().scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
label->setPixmap(thumbnail);
thumbnail = QPixmap();
label->setAlignment(Qt::AlignCenter);
if (size.height() < 120) {
label->setMinimumHeight(120);
}
if (size.width() < 140) {
label->setMinimumWidth(140);
}
label->resize(size);
QPushButton *discardPushButton = new QPushButton(QIcon(":/icons/no") , "", label);
QPushButton *enlargePushButton = new QPushButton(QIcon(":/icons/zoom.in"), "", label);
QToolButton *confirmPushButton = new QToolButton(label);
confirmPushButton->setIconSize(QSize(24, 24));
confirmPushButton->setCursor(Qt::PointingHandCursor);
confirmPushButton->setGraphicsEffect(os::shadow());
if (ScreenshotManager::instance()->settings()->value("options/previewDefaultAction", 0).toInt() == 0
|| ScreenshotManager::instance()->settings()->value("options/uploadAuto").toBool()) {
// Default button, confirm & upload.
confirmPushButton->setIcon(QIcon(":/icons/yes"));
if (!ScreenshotManager::instance()->settings()->value("options/uploadAuto").toBool()) {
QMenu *confirmMenu = new QMenu(confirmPushButton);
confirmMenu->setObjectName("confirmMenu");
QAction *uploadAction = new QAction(QIcon(":/icons/imgur.yes"), tr("Upload"), confirmPushButton);
connect(uploadAction, SIGNAL(triggered()), screenshot, SLOT(markUpload()));
connect(uploadAction, SIGNAL(triggered()), screenshot, SLOT(confirm()));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(closePreview()));
connect(this, SIGNAL(uploadAll()), uploadAction, SLOT(trigger()));
confirmMenu->addAction(uploadAction);
confirmPushButton->setMenu(confirmMenu);
confirmPushButton->setPopupMode(QToolButton::MenuButtonPopup);
}
connect(this, SIGNAL(acceptAll()), confirmPushButton, SLOT(click()));
connect(confirmPushButton, SIGNAL(clicked()), screenshot, SLOT(confirm()));
connect(confirmPushButton, SIGNAL(clicked()), this, SLOT(closePreview()));
}
else {
// Reversed button, upload & confirm.
confirmPushButton->setIcon(QIcon(":/icons/imgur.yes"));
QMenu *confirmMenu = new QMenu(confirmPushButton);
confirmMenu->setObjectName("confirmMenu");
QAction *confirmAction = new QAction(QIcon(":/icons/yes"), tr("Save"), confirmPushButton);
connect(this, SIGNAL(acceptAll()), confirmAction, SLOT(trigger()));
connect(confirmAction, SIGNAL(triggered()), screenshot, SLOT(confirm()));
connect(confirmAction, SIGNAL(triggered()), this, SLOT(closePreview()));
connect(confirmPushButton, SIGNAL(clicked()), screenshot, SLOT(markUpload()));
connect(confirmPushButton, SIGNAL(clicked()), screenshot, SLOT(confirm()));
connect(confirmPushButton, SIGNAL(clicked()), this, SLOT(closePreview()));
connect(this, SIGNAL(uploadAll()), confirmPushButton, SLOT(click()));
confirmMenu->addAction(confirmAction);
confirmPushButton->setMenu(confirmMenu);
confirmPushButton->setPopupMode(QToolButton::MenuButtonPopup);
}
confirmPushButton->setAutoRaise(true);
confirmPushButton->setVisible(false);
discardPushButton->setIconSize(QSize(24, 24));
discardPushButton->setCursor(Qt::PointingHandCursor);
discardPushButton->setGraphicsEffect(os::shadow());
discardPushButton->setFlat(true);
discardPushButton->setVisible(false);
enlargePushButton->setIconSize(QSize(22, 22));
enlargePushButton->setCursor(Qt::PointingHandCursor);
enlargePushButton->setGraphicsEffect(os::shadow());
enlargePushButton->setFlat(true);
enlargePushButton->setVisible(false);
enlargePushButton->setDisabled(small);
connect(this, SIGNAL(rejectAll()), discardPushButton, SLOT(click()));
connect(discardPushButton, SIGNAL(clicked()), screenshot, SLOT(discard()));
connect(discardPushButton, SIGNAL(clicked()), this, SLOT(closePreview()));
connect(enlargePushButton, SIGNAL(clicked()), this, SLOT(enlargePreview()));
QHBoxLayout *wlayout = new QHBoxLayout;
wlayout->addWidget(confirmPushButton);
wlayout->addStretch();
wlayout->addWidget(enlargePushButton);
wlayout->addStretch();
wlayout->addWidget(discardPushButton);
wlayout->setMargin(0);
QVBoxLayout *wl = new QVBoxLayout;
wl->addStretch();
wl->addLayout(wlayout);
wl->setMargin(0);
label->setLayout(wl);
mStack->addWidget(label);
mStack->setCurrentIndex(mStack->count()-1);
mNextButton->setEnabled(false);
if (mStack->count() >= 2 && !mNextButton->isVisible()) {
mNextButton->setVisible(true);
mPrevButton->setVisible(true);
}
relocate();
}
int PreviewDialog::count() const
{
return mStack->count();
}
-void PreviewDialog::relocate()
-{
- updateGeometry();
- resize(minimumSizeHint());
- QApplication::sendEvent(this, new QEvent(QEvent::Enter)); // Ensures the buttons are visible.
-
- QPoint where;
- switch (mPosition)
- {
- case 0:
- where = QApplication::desktop()->availableGeometry(this).topLeft();
- break;
- case 1:
- where = QApplication::desktop()->availableGeometry(this).topRight();
- where.setX(where.x() - frameGeometry().width());
- break;
- case 2:
- where = QApplication::desktop()->availableGeometry(this).bottomLeft();
- where.setY(where.y() - frameGeometry().height());
- break;
- case 3:
- default:
- where = QApplication::desktop()->availableGeometry(this).bottomRight();
- where.setX(where.x() - frameGeometry().width());
- where.setY(where.y() - frameGeometry().height());
- break;
- }
-
- move(where);
-}
+//
void PreviewDialog::closePreview()
{
QWidget *widget = mStack->currentWidget();
mStack->removeWidget(widget);
widget->deleteLater();
if (mStack->count() == 0) {
close();
}
else {
relocate();
}
}
+void PreviewDialog::enlargePreview()
+{
+ Screenshot *screenshot = qobject_cast<Screenshot*>(ScreenshotManager::instance()->children().at(mStack->currentIndex()));
+
+ if (screenshot) {
+ new ScreenshotDialog(screenshot, this);
+ }
+}
+
void PreviewDialog::indexChanged(int i)
{
if (i == mStack->count()-1) {
mNextButton->setEnabled(false);
mPrevButton->setEnabled(true);
}
if (i == 0 && mStack->count() > 1) {
mNextButton->setEnabled(true);
mPrevButton->setEnabled(false);
}
if (i != 0 && i != mStack->count()-1) {
mNextButton->setEnabled(true);
mPrevButton->setEnabled(true);
}
if (mStack->count() < 2) {
mNextButton->setEnabled(false);
mPrevButton->setEnabled(false);
}
if (mStack->widget(i)) {
mStack->widget(i)->setFocus();
}
if (mStack->count() > 1) {
setWindowTitle(tr("Screenshot Preview (%1 of %2)").arg(mStack->currentIndex()+1).arg(mStack->count()));
}
else {
setWindowTitle(tr("Screenshot Preview"));
}
}
-void PreviewDialog::previous()
+void PreviewDialog::next()
{
- mStack->setCurrentIndex(mStack->currentIndex()-1);
+ mStack->setCurrentIndex(mStack->currentIndex()+1);
relocate();
}
-void PreviewDialog::next()
+void PreviewDialog::previous()
{
- mStack->setCurrentIndex(mStack->currentIndex()+1);
+ mStack->setCurrentIndex(mStack->currentIndex()-1);
relocate();
}
-void PreviewDialog::enlargePreview()
+
+void PreviewDialog::relocate()
{
- Screenshot *screenshot = qobject_cast<Screenshot*>(ScreenshotManager::instance()->children().at(mStack->currentIndex()));
+ updateGeometry();
+ resize(minimumSizeHint());
+ QApplication::sendEvent(this, new QEvent(QEvent::Enter)); // Ensures the buttons are visible.
- if (screenshot) {
- new ScreenshotDialog(screenshot, this);
+ QPoint where;
+ switch (mPosition)
+ {
+ case 0:
+ where = QApplication::desktop()->availableGeometry(this).topLeft();
+ break;
+ case 1:
+ where = QApplication::desktop()->availableGeometry(this).topRight();
+ where.setX(where.x() - frameGeometry().width());
+ break;
+ case 2:
+ where = QApplication::desktop()->availableGeometry(this).bottomLeft();
+ where.setY(where.y() - frameGeometry().height());
+ break;
+ case 3:
+ default:
+ where = QApplication::desktop()->availableGeometry(this).bottomRight();
+ where.setX(where.x() - frameGeometry().width());
+ where.setY(where.y() - frameGeometry().height());
+ break;
}
+
+ move(where);
}
+//
+
bool PreviewDialog::event(QEvent *event)
{
if ((event->type() == QEvent::Enter || event->type() == QEvent::Leave)
&& mStack->currentWidget())
{
foreach (QObject *child, mStack->currentWidget()->children()) {
QWidget *widget = qobject_cast<QWidget*>(child);
if (widget) {
// Lets avoid disappearing buttons and bail if the menu is open.
QMenu *confirmMenu = widget->findChild<QMenu*>("confirmMenu");
if (confirmMenu && confirmMenu->isVisible())
return false;
widget->setVisible((event->type() == QEvent::Enter));
}
}
}
else if (event->type() == QEvent::Close) {
deleteLater();
}
else if (event->type() == QEvent::MouseButtonDblClick) {
enlargePreview();
}
return QDialog::event(event);
}
void PreviewDialog::timerEvent(QTimerEvent *event)
{
if (mAutoclose == 0) {
if (mAutocloseAction == 0) {
emit acceptAll();
}
else if (mAutocloseAction == 1) {
emit uploadAll();
}
else {
emit rejectAll();
}
}
else if (mAutoclose < 0) {
killTimer(event->timerId());
}
else {
setWindowTitle(tr("Preview: Closing in %1").arg(mAutoclose));
mAutoclose--;
}
}
diff --git a/dialogs/previewdialog.h b/dialogs/previewdialog.h
index 297da6b..9a60d75 100644
--- a/dialogs/previewdialog.h
+++ b/dialogs/previewdialog.h
@@ -1,73 +1,69 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef PREVIEWDIALOG_H
#define PREVIEWDIALOG_H
#include <QDialog>
class Screenshot;
class QStackedLayout;
class QPushButton;
class PreviewDialog : public QDialog
{
Q_OBJECT
public:
PreviewDialog(QWidget *parent);
void add(Screenshot* screenshot);
int count() const;
- static PreviewDialog *instance();
- static bool isActive();
-
public slots:
void setWidth(int w) { resize(w, height()); }
void setHeight(int h) { resize(width(), h); }
signals:
void acceptAll();
- void uploadAll();
void rejectAll();
+ void uploadAll();
private slots:
void closePreview();
- void relocate();
- void previous();
- void next();
- void indexChanged(int i);
void enlargePreview();
+ void indexChanged(int i);
+ void next();
+ void previous();
+ void relocate();
protected:
- void timerEvent(QTimerEvent *event);
bool event(QEvent *event);
+ void timerEvent(QTimerEvent *event);
private:
- static PreviewDialog* mInstance;
- int mSize;
- int mPosition; //0: top left, 1: top right, 2: bottom left, 3: bottom rigth (default)
int mAutoclose;
- int mAutocloseReset;
int mAutocloseAction;
- QStackedLayout* mStack;
+ int mAutocloseReset;
+ int mPosition; //0: top left, 1: top right, 2: bottom left, 3: bottom rigth (default)
+ int mSize;
QPushButton* mNextButton;
QPushButton* mPrevButton;
+ QStackedLayout* mStack;
};
#endif // PREVIEWDIALOG_H
diff --git a/dialogs/screenshotdialog.cpp b/dialogs/screenshotdialog.cpp
index 3cf4000..2748914 100644
--- a/dialogs/screenshotdialog.cpp
+++ b/dialogs/screenshotdialog.cpp
@@ -1,139 +1,140 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "screenshotdialog.h"
#include "../tools/screenshot.h"
-
#include <QApplication>
#include <QDesktopWidget>
-#include <QScrollArea>
-#include <QScrollBar>
-#include <QLabel>
#include <QHBoxLayout>
+#include <QLabel>
#include <QMouseEvent>
+#include <QScrollArea>
+#include <QScrollBar>
#include <QDebug>
ScreenshotDialog::ScreenshotDialog(Screenshot *screenshot, QWidget *parent) :
QDialog(parent)
{
setWindowTitle(tr("Lightscreen Screenshot Viewer"));
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint | Qt::WindowContextHelpButtonHint);
setWhatsThis(tr("You can zoom using the mouse wheel while holding the CTRL key. To return to the default zoom press \"Ctrl-0\"."));
mScrollArea = new QScrollArea(this);
mScrollArea->verticalScrollBar()->installEventFilter(this);
QPalette newPalette = mScrollArea->palette();
newPalette.setBrush(QPalette::Background, QBrush(QPixmap(":/backgrounds/checkerboard")));
mScrollArea->setPalette(newPalette);
mLabel = new QLabel(this);
QHBoxLayout *layout = new QHBoxLayout(this);
mLabel->setPixmap(screenshot->pixmap());
mLabel->setScaledContents(true);
mScrollArea->setAlignment(Qt::AlignCenter);
mScrollArea->setWidget(mLabel);
layout->addWidget(mScrollArea);
layout->setMargin(0);
setLayout(layout);
setCursor(Qt::OpenHandCursor);
mOriginalSize = mLabel->size();
QSize size = (mLabel->pixmap()->size() + QSize(10, 10)); //TODO: Good padding for all platforms
if (size.width() >= qApp->desktop()->availableGeometry().width()) {
size.setWidth(qApp->desktop()->availableGeometry().size().width() - 300);
}
if (size.height() >= qApp->desktop()->availableGeometry().height()) {
size.setHeight(qApp->desktop()->availableGeometry().size().height() - 300);
}
resize(size);
show();
}
void ScreenshotDialog::zoom(int offset)
{
if (offset == 0) {
mLabel->resize(mOriginalSize);
}
else {
QSize newSize = mLabel->size();
newSize.scale(mLabel->size() + QSize(offset, offset), Qt::KeepAspectRatio);
if (offset < 0 && (newSize.width() < 200 || newSize.height() < 200)) {
return;
}
mLabel->resize(newSize);
}
}
-void ScreenshotDialog::keyPressEvent(QKeyEvent *event)
+//
+
+bool ScreenshotDialog::eventFilter(QObject *obj, QEvent *event)
{
- if (event->key() == Qt::Key_0 && event->modifiers() & Qt::ControlModifier) {
- zoom(0);
+ if (event->type() == QEvent::Wheel
+ && qApp->keyboardModifiers() & Qt::ControlModifier) {
+ QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
+ zoom(wheelEvent->delta());
+ return true;
}
+
+ return QObject::eventFilter(obj, event);
}
-void ScreenshotDialog::mousePressEvent(QMouseEvent *event)
+void ScreenshotDialog::closeEvent(QCloseEvent *event)
{
- mMousePos = event->pos();
- setCursor(Qt::ClosedHandCursor);
+ Q_UNUSED(event)
+ deleteLater();
}
-void ScreenshotDialog::mouseReleaseEvent(QMouseEvent *event)
+void ScreenshotDialog::keyPressEvent(QKeyEvent *event)
{
- Q_UNUSED(event)
- setCursor(Qt::OpenHandCursor);
+ if (event->key() == Qt::Key_0 && event->modifiers() & Qt::ControlModifier) {
+ zoom(0);
+ }
}
void ScreenshotDialog::mouseMoveEvent(QMouseEvent *event)
{
QPoint diff = event->pos() - mMousePos;
mMousePos = event->pos();
mScrollArea->verticalScrollBar()->setValue(mScrollArea->verticalScrollBar()->value() - diff.y());
mScrollArea->horizontalScrollBar()->setValue(mScrollArea->horizontalScrollBar()->value() - diff.x());
}
-void ScreenshotDialog::closeEvent(QCloseEvent *event)
+void ScreenshotDialog::mousePressEvent(QMouseEvent *event)
{
- Q_UNUSED(event)
- deleteLater();
+ mMousePos = event->pos();
+ setCursor(Qt::ClosedHandCursor);
}
-bool ScreenshotDialog::eventFilter(QObject *obj, QEvent *event)
+void ScreenshotDialog::mouseReleaseEvent(QMouseEvent *event)
{
- if (event->type() == QEvent::Wheel
- && qApp->keyboardModifiers() & Qt::ControlModifier) {
- QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
- zoom(wheelEvent->delta());
- return true;
- }
-
- return QObject::eventFilter(obj, event);
+ Q_UNUSED(event)
+ setCursor(Qt::OpenHandCursor);
}
diff --git a/dialogs/screenshotdialog.h b/dialogs/screenshotdialog.h
index bc1c47a..f0ca945 100644
--- a/dialogs/screenshotdialog.h
+++ b/dialogs/screenshotdialog.h
@@ -1,51 +1,51 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef SCREENSHOTDIALOG_H
#define SCREENSHOTDIALOG_H
#include <QDialog>
struct QPoint;
class Screenshot;
class QScrollArea;
class QLabel;
class ScreenshotDialog : public QDialog
{
public:
ScreenshotDialog(Screenshot *screenshot, QWidget *parent = 0);
private:
- void zoom(int offset);
+ void zoom(int offset);
protected:
- void keyPressEvent(QKeyEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void closeEvent(QCloseEvent *event);
- bool eventFilter(QObject *obj, QEvent *event);
+ bool eventFilter(QObject *obj, QEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
private:
- QScrollArea *mScrollArea;
- QLabel *mLabel;
- QPoint mMousePos;
- QSize mOriginalSize;
+ QLabel *mLabel;
+ QPoint mMousePos;
+ QScrollArea *mScrollArea;
+ QSize mOriginalSize;
};
#endif // SCREENSHOTDIALOG_H
diff --git a/dialogs/updaterdialog.cpp b/dialogs/updaterdialog.cpp
index 333c5f9..7ea6eca 100644
--- a/dialogs/updaterdialog.cpp
+++ b/dialogs/updaterdialog.cpp
@@ -1,65 +1,65 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
#include <QDesktopServices>
-#include <QProgressBar>
#include <QLabel>
#include <QLayout>
+#include <QProgressBar>
#include <QUrl>
#include "updaterdialog.h"
#include "../tools/os.h"
UpdaterDialog::UpdaterDialog() :
QProgressDialog("", tr("Cancel"), 0, 0)
{
setWindowTitle(tr("Updater - Lightscreen"));
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
setAutoClose(false);
QProgressBar *bar = new QProgressBar(this);
bar->setTextVisible(false);
bar->setRange(0, 0);
QLabel *label = new QLabel(tr("Checking for updates..."), this);
connect(label, SIGNAL(linkActivated(QString)), this, SLOT(link(QString)));
setLabel(label);
setBar(bar);
}
void UpdaterDialog::updateDone(bool result)
{
if (result) {
setLabelText(tr("There's a new version available,<br> please see <a href=\"http://lightscreen.sourceforge.net/whatsnew/%1\">the Lighscreen website</a>.").arg(qApp->applicationVersion()));
}
else {
setLabelText(tr("No new versions available."));
}
setMaximum(1);
setCancelButtonText(tr("Close"));
}
void UpdaterDialog::link(QString url)
{
QDesktopServices::openUrl(url);
}
diff --git a/lightscreenwindow.cpp b/lightscreenwindow.cpp
index 292ba22..0f9181b 100644
--- a/lightscreenwindow.cpp
+++ b/lightscreenwindow.cpp
@@ -1,1022 +1,1027 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QDate>
#include <QDesktopServices>
#include <QFileInfo>
#include <QHttp>
+#include <QKeyEvent>
#include <QMenu>
#include <QMessageBox>
#include <QPointer>
#include <QProcess>
#include <QSettings>
#include <QSound>
#include <QSystemTrayIcon>
#include <QTimer>
-#include <QUrl>
-#include <QKeyEvent>
#include <QToolTip>
+#include <QUrl>
#include <QDebug>
#ifdef Q_WS_WIN
#include <windows.h>
#include "tools/qwin7utils/Taskbar.h"
#include "tools/qwin7utils/TaskbarButton.h"
using namespace QW7;
#endif
/*
* Lightscreen includes
*/
#include "lightscreenwindow.h"
#include "dialogs/optionsdialog.h"
#include "dialogs/previewdialog.h"
#include "dialogs/historydialog.h"
#include "tools/globalshortcut/globalshortcutmanager.h"
#include "tools/os.h"
#include "tools/screenshot.h"
#include "tools/screenshotmanager.h"
#include "tools/qtwin.h"
#include "tools/uploader.h"
#include "updater/updater.h"
LightscreenWindow::LightscreenWindow(QWidget *parent) :
QDialog(parent),
mDoCache(false),
mHideTrigger(false),
mReviveMain(false),
mWasVisible(true),
mOptimizeCount(0),
mLastMode(-1),
mLastMessage(0),
mLastScreenshot()
{
os::translate(settings()->value("options/language", "English").toString());
ui.setupUi(this);
if (QtWin::isCompositionEnabled()) {
layout()->setMargin(0);
resize(minimumSizeHint());
}
setMaximumSize(size());
setMinimumSize(size());
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint); // Remove the what's this button, no real use in the main window.
#ifdef Q_WS_WIN
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
mTaskbarButton = new TaskbarButton(this);
}
#endif
// Actions
connect(ui.optionsPushButton , SIGNAL(clicked()), this, SLOT(showOptions()));
connect(ui.hidePushButton , SIGNAL(clicked()), this, SLOT(toggleVisibility()));
connect(ui.screenshotPushButton, SIGNAL(clicked()), this, SLOT(showScreenshotMenu()));
connect(ui.quitPushButton , SIGNAL(clicked()), this, SLOT(quit()));
// Uploader
connect(Uploader::instance(), SIGNAL(progress(qint64,qint64)), this, SLOT(uploadProgress(qint64, qint64)));
connect(Uploader::instance(), SIGNAL(done(QString, QString)) , this, SLOT(showUploaderMessage(QString, QString)));
connect(Uploader::instance(), SIGNAL(error(QString)) , this, SLOT(showUploaderError(QString)));
// Manager
connect(ScreenshotManager::instance(), SIGNAL(confirm(Screenshot*)), this, SLOT(preview(Screenshot*)));
connect(ScreenshotManager::instance(), SIGNAL(windowCleanup(Screenshot::Options&)), this, SLOT(cleanup(Screenshot::Options&)));
if (!settings()->contains("file/format")) {
showOptions(); // There are no options (or the options config is invalid or incomplete)
}
else {
QTimer::singleShot(0 , this, SLOT(applySettings()));
QTimer::singleShot(5000, this, SLOT(checkForUpdates()));
}
}
LightscreenWindow::~LightscreenWindow()
{
settings()->setValue("lastScreenshot", mLastScreenshot);
GlobalShortcutManager::instance()->clear();
delete mTrayIcon;
}
-/*
- * Slots
- */
-
void LightscreenWindow::action(int mode)
{
if (mode == 4) {
goToFolder();
}
else {
show();
}
}
-bool LightscreenWindow::closingWithoutTray()
+void LightscreenWindow::areaHotkey()
{
- if (settings()->value("options/disableHideAlert", false).toBool())
- return false;
-
- QMessageBox msgBox;
- msgBox.setWindowTitle(tr("Lightscreen"));
- msgBox.setText(tr("You have chosen to hide Lightscreen when there's no system tray icon, so you will not be able to access the program <b>unless you have selected a hotkey to do so</b>.<br>What do you want to do?"));
- msgBox.setIcon(QMessageBox::Warning);
-
- msgBox.setStyleSheet("QPushButton { padding: 4px 8px; }");
-
- QPushButton *enableButton = msgBox.addButton(tr("Hide but enable tray"),
- QMessageBox::ActionRole);
- QPushButton *enableAndDenotifyButton = msgBox.addButton(tr("Hide and don't warn"),
- QMessageBox::ActionRole);
- QPushButton *hideButton = msgBox.addButton(tr("Just hide"),
- QMessageBox::ActionRole);
- QPushButton *abortButton = msgBox.addButton(QMessageBox::Cancel);
-
- Q_UNUSED(abortButton);
+ screenshotAction(2);
+}
- msgBox.exec();
+void LightscreenWindow::checkForUpdates()
+{
+ if (settings()->value("options/disableUpdater", false).toBool())
+ return;
- if (msgBox.clickedButton() == hideButton) {
- return false;
- }
- else if (msgBox.clickedButton() == enableAndDenotifyButton) {
- settings()->setValue("options/disableHideAlert", true);
- applySettings();
- return false;
- }
- else if (msgBox.clickedButton() == enableButton) {
- settings()->setValue("options/tray", true);
- applySettings();
- return false;
- }
+ if (settings()->value("lastUpdateCheck").toInt() + 7
+ > QDate::currentDate().dayOfYear())
+ return; // If 7 days have not passed since the last update check.
- return true; // Cancel
+ connect(Updater::instance(), SIGNAL(done(bool)), this, SLOT(updaterDone(bool)));
+ Updater::instance()->check();
}
void LightscreenWindow::cleanup(Screenshot::Options &options)
{
// Reversing settings
if (settings()->value("options/hide").toBool()) {
#ifndef Q_WS_X11 // X is not quick enough and the notification ends up everywhere but in the icon
if (settings()->value("options/tray").toBool() && mTrayIcon) {
mTrayIcon->show();
}
#endif
if (mPreviewDialog) {
if (mPreviewDialog->count() <= 1 && mWasVisible) {
show();
}
mPreviewDialog->show();
}
else if (mWasVisible) {
show();
}
mHideTrigger = false;
}
if (settings()->value("options/tray").toBool() && mTrayIcon) {
notify(options.result);
if (settings()->value("options/message").toBool() && options.file) {
showScreenshotMessage(options.result, options.fileName);
}
}
if (settings()->value("options/playSound", false).toBool()) {
if (options.result == Screenshot::Success) {
QSound::play("sounds/ls.screenshot.wav");
}
else {
#ifdef Q_WS_WIN
QSound::play("afakepathtomakewindowsplaythedefaultsoundtheresprobablyabetterwaybuticantbebothered");
#else
QSound::play("sound/ls.error.wav");
#endif
}
}
if (options.result != Screenshot::Success
|| !options.file)
return;
if (settings()->value("options/optipng").toBool()
&& options.format == Screenshot::PNG) {
optiPNG(options.fileName, options.upload);
}
else if (options.upload) {
upload(options.fileName);
}
else {
ScreenshotManager::instance()->saveHistory(options.fileName);
}
mLastScreenshot = options.fileName;
}
+bool LightscreenWindow::closingWithoutTray()
+{
+ if (settings()->value("options/disableHideAlert", false).toBool())
+ return false;
+
+ QMessageBox msgBox;
+ msgBox.setWindowTitle(tr("Lightscreen"));
+ msgBox.setText(tr("You have chosen to hide Lightscreen when there's no system tray icon, so you will not be able to access the program <b>unless you have selected a hotkey to do so</b>.<br>What do you want to do?"));
+ msgBox.setIcon(QMessageBox::Warning);
+
+ msgBox.setStyleSheet("QPushButton { padding: 4px 8px; }");
+
+ QPushButton *enableButton = msgBox.addButton(tr("Hide but enable tray"),
+ QMessageBox::ActionRole);
+ QPushButton *enableAndDenotifyButton = msgBox.addButton(tr("Hide and don't warn"),
+ QMessageBox::ActionRole);
+ QPushButton *hideButton = msgBox.addButton(tr("Just hide"),
+ QMessageBox::ActionRole);
+ QPushButton *abortButton = msgBox.addButton(QMessageBox::Cancel);
+
+ Q_UNUSED(abortButton);
+
+ msgBox.exec();
+
+ if (msgBox.clickedButton() == hideButton) {
+ return false;
+ }
+ else if (msgBox.clickedButton() == enableAndDenotifyButton) {
+ settings()->setValue("options/disableHideAlert", true);
+ applySettings();
+ return false;
+ }
+ else if (msgBox.clickedButton() == enableButton) {
+ settings()->setValue("options/tray", true);
+ applySettings();
+ return false;
+ }
+
+ return true; // Cancel
+}
+
void LightscreenWindow::goToFolder()
{
#ifdef Q_WS_WIN
if (!mLastScreenshot.isEmpty()) {
QProcess::startDetached("explorer /select, \"" + mLastScreenshot +"\"");
}
else {
#endif
QString folder = settings()->value("file/target").toString();
if (folder.isEmpty())
folder = qApp->applicationDirPath();
if (QDir::toNativeSeparators(folder.at(folder.size()-1)) != QDir::separator())
folder.append(QDir::separator());
QDesktopServices::openUrl("file:///"+folder);
#ifdef Q_WS_WIN
}
#endif
}
+void LightscreenWindow::messageClicked()
+{
+ if (mLastMessage == 1) {
+ goToFolder();
+ }
+ else {
+ QDesktopServices::openUrl(QUrl(Uploader::instance()->lastUrl()));
+ }
+}
+
void LightscreenWindow::messageReceived(const QString &message)
{
if (message.contains(' ')) {
foreach (QString argument, message.split(' ')) {
messageReceived(argument);
}
}
if (message == "--wake") {
show();
qApp->alert(this, 500);
return;
}
if (message == "--screen")
screenshotAction();
else if (message == "--area")
screenshotAction(2);
else if (message == "--activewindow")
screenshotAction(1);
else if (message == "--pickwindow")
screenshotAction(3);
else if (message == "--folder")
action(4);
else if (message == "--uploadlast")
uploadLast();
else if (message == "--viewhistory")
showUploadDialog();
}
-void LightscreenWindow::messageClicked()
+void LightscreenWindow::notify(const Screenshot::Result &result)
{
- if (mLastMessage == 1) {
- goToFolder();
- }
- else {
- QDesktopServices::openUrl(QUrl(Uploader::instance()->lastUrl()));
+ switch (result)
+ {
+ case Screenshot::Success:
+ mTrayIcon->setIcon(QIcon(":/icons/lightscreen.yes"));
+
+#ifdef Q_WS_WIN
+ if (mTaskbarButton)
+ mTaskbarButton->SetOverlayIcon(QIcon(":/icons/yes"), tr("Success!"));
+#endif
+
+ setWindowTitle(tr("Success!"));
+ break;
+ case Screenshot::Fail:
+ mTrayIcon->setIcon(QIcon(":/icons/lightscreen.no"));
+ setWindowTitle(tr("Failed!"));
+#ifdef Q_WS_WIN
+ if (mTaskbarButton)
+ mTaskbarButton->SetOverlayIcon(QIcon(":/icons/no"), tr("Failed!"));
+#endif
+ break;
+ case Screenshot::Cancel:
+ setWindowTitle(tr("Cancelled!"));
+ break;
}
+
+ QTimer::singleShot(2000, this, SLOT(restoreNotification()));
+}
+
+void LightscreenWindow::optimizationDone()
+{
+ // A mouthful :D
+ mOptimizeCount--;
+ QString screenshot = (qobject_cast<QProcess*>(sender()))->property("screenshot").toString();
+ upload(screenshot);
}
void LightscreenWindow::preview(Screenshot* screenshot)
{
if (screenshot->options().preview) {
if (!mPreviewDialog) {
mPreviewDialog = new PreviewDialog(this);
}
mPreviewDialog->add(screenshot);
}
else {
screenshot->confirm(true);
}
}
void LightscreenWindow::quit()
{
settings()->setValue("position", pos());
QString doing;
int answer = 0;
if (Uploader::instance()->uploading() > 0) {
doing = tr("uploading one or more screenshots");
}
if (mOptimizeCount > 0) {
if (!doing.isNull()) {
doing = tr("optimizing and uploading screenshots");
}
else {
doing = tr("optimizing one or more screenshots");
}
}
if (!doing.isNull()) {
answer = QMessageBox::question(this,
tr("Are you sure you want to quit?"),
tr("Lightscreen is currently %1, this will finish momentarily, are you sure you want to quit?").arg(doing),
tr("Quit"),
tr("Don't Quit"));
}
if (answer == 0)
accept();
}
void LightscreenWindow::restoreNotification()
{
if (mTrayIcon)
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.small"));
#ifdef Q_WS_WIN
if (mTaskbarButton)
mTaskbarButton->SetOverlayIcon(QIcon(), "");
#endif
updateUploadStatus();
}
void LightscreenWindow::screenshotAction(int mode)
{
int delayms = -1;
bool optionsHide = settings()->value("options/hide").toBool(); // Option cache, used a couple of times.
if (!mHideTrigger) {
mWasVisible = isVisible();
mHideTrigger = true;
}
// Applying pre-screenshot settings
if (optionsHide) {
hide();
#ifndef Q_WS_X11 // X is not quick enough and the notification ends up everywhere but in the icon
if (mTrayIcon)
mTrayIcon->hide();
#endif
}
// Screenshot delay
delayms = settings()->value("options/delay", 0).toInt();
delayms = delayms * 1000; // Converting the delay to milliseconds.
delayms += 400;
if (optionsHide && mPreviewDialog) {
if (mPreviewDialog->count() >= 1) {
mPreviewDialog->hide();
}
}
// The delayed functions works using the static variable lastMode
// which keeps the argument so a QTimer can call this function again.
if (delayms > 0) {
if (mLastMode < 0) {
mLastMode = mode;
QTimer::singleShot(delayms, this, SLOT(screenshotAction()));
return;
}
else {
mode = mLastMode;
mLastMode = -1;
}
}
static Screenshot::Options options;
if (!mDoCache) {
// Populating the option object that will then be passed to the screenshot engine (sounds fancy huh?)
options.file = settings()->value("file/enabled").toBool();
options.format = (Screenshot::Format) settings()->value("file/format").toInt();
options.prefix = settings()->value("file/prefix").toString();
options.directory = QDir(settings()->value("file/target").toString());
options.quality = settings()->value("options/quality", 100).toInt();
options.currentMonitor = settings()->value("options/currentMonitor", false).toBool();
options.clipboard = settings()->value("options/clipboard", true).toBool();
options.preview = settings()->value("options/preview", false).toBool();
options.magnify = settings()->value("options/magnify", false).toBool();
options.cursor = settings()->value("options/cursor" , false).toBool();
options.saveAs = settings()->value("options/saveAs" , false).toBool();
options.animations = settings()->value("options/animations" , true).toBool();
options.replace = settings()->value("options/replace", false).toBool();
options.upload = settings()->value("options/uploadAuto", false).toBool();
Screenshot::NamingOptions namingOptions;
namingOptions.naming = (Screenshot::Naming) settings()->value("file/naming").toInt();
namingOptions.leadingZeros = settings()->value("options/naming/leadingZeros", 0).toInt();
namingOptions.flip = settings()->value("options/flip", false).toBool();
namingOptions.dateFormat = settings()->value("options/naming/dateFormat", "yyyy-MM-dd").toString();
options.namingOptions = namingOptions;
mDoCache = true;
}
options.mode = mode;
ScreenshotManager::instance()->take(options);
}
void LightscreenWindow::screenshotActionTriggered(QAction* action)
{
screenshotAction(action->data().toInt());
}
-void LightscreenWindow::showOptions()
+void LightscreenWindow::showHotkeyError(const QStringList &hotkeys)
{
- GlobalShortcutManager::clear();
+ static bool dontShow = false;
- QPointer<OptionsDialog> optionsDialog = new OptionsDialog(this);
+ if (dontShow)
+ return;
- optionsDialog->exec();
- optionsDialog->deleteLater();
+ QString messageText;
- applySettings();
-}
+ messageText = tr("Some hotkeys could not be registered, they might already be in use");
-void LightscreenWindow::showScreenshotMessage(const Screenshot::Result &result, const QString &fileName)
-{
- if (result == Screenshot::Cancel
- || mPreviewDialog)
- return;
+ if (hotkeys.count() > 1) {
+ messageText += tr("<br>The failed hotkeys are the following:") + "<ul>";
- // Showing message.
- QString title;
- QString message;
+ foreach(const QString &hotkey, hotkeys) {
+ messageText += QString("%1%2%3").arg("<li><b>").arg(hotkey).arg("</b></li>");
+ }
- if (result == Screenshot::Success) {
- title = QFileInfo(fileName).fileName();
+ messageText += "</ul>";
+ }
+ else {
+ messageText += tr("<br>The failed hotkey is <b>%1</b>").arg(hotkeys[0]);
+ }
- if (settings()->value("file/target").toString().isEmpty()) {
- message = QDir::toNativeSeparators(QCoreApplication::applicationDirPath());
- }
- else {
- message = tr("Saved to \"%1\"").arg(settings()->value("file/target").toString());
- }
- }
- else {
- title = tr("The screenshot was not taken");
- message = tr("An error occurred.");
- }
+ messageText += tr("<br><i>What do you want to do?</i>");
- mLastMessage = 1;
- mTrayIcon->showMessage(title, message);
-}
+ QMessageBox msgBox(this);
+ msgBox.setWindowTitle(tr("Lightscreen"));
+ msgBox.setText(messageText);
-void LightscreenWindow::showUploadDialog()
-{
- HistoryDialog historyDialog(this);
- historyDialog.exec();
-}
+ QPushButton *changeButton = msgBox.addButton(tr("Change") , QMessageBox::ActionRole);
+ QPushButton *disableButton = msgBox.addButton(tr("Disable"), QMessageBox::ActionRole);
+ QPushButton *exitButton = msgBox.addButton(tr("Quit") , QMessageBox::ActionRole);
-void LightscreenWindow::showUploaderMessage(QString fileName, QString url)
-{
- if (!mTrayIcon)
- return;
+ msgBox.exec();
- QString screenshot = QFileInfo(fileName).fileName();
+ if (msgBox.clickedButton() == exitButton) {
+ dontShow = true;
+ QTimer::singleShot(10, this, SLOT(quit()));
+ }
+ else if (msgBox.clickedButton() == changeButton) {
+ showOptions();
+ }
+ else if (msgBox.clickedButton() == disableButton) {
+ foreach(const QString &hotkey, hotkeys) {
+ settings()->setValue(QString("actions/%1/enabled").arg(hotkey), false);
+ }
+ }
- mLastMessage = 2;
- mTrayIcon->showMessage(tr("%1 uploaded").arg(screenshot), tr("Click here to go to %1").arg(url));
- updateUploadStatus();
}
-void LightscreenWindow::showUploaderError(const QString &error)
+void LightscreenWindow::showOptions()
{
- mLastMessage = -1;
+ GlobalShortcutManager::clear();
- if (mTrayIcon && !error.isEmpty()) {
- mTrayIcon->showMessage(tr("Upload error"), error);
- }
+ QPointer<OptionsDialog> optionsDialog = new OptionsDialog(this);
- updateUploadStatus();
+ optionsDialog->exec();
+ optionsDialog->deleteLater();
+
+ applySettings();
}
void LightscreenWindow::showScreenshotMenu()
{
// This slot is called only on the first click
QMenu *buttonMenu = new QMenu;
QAction *screenAction = new QAction(QIcon(":/icons/screen"), tr("&Screen"), buttonMenu);
screenAction->setData(QVariant(0));
QAction *windowAction = new QAction(QIcon(":/icons/window"),tr("Active &Window"), buttonMenu);
windowAction->setData(QVariant(1));
QAction *windowPickerAction = new QAction(QIcon(":/icons/picker"), tr("&Pick Window"), buttonMenu);
windowPickerAction->setData(QVariant(3));
QAction *areaAction = new QAction(QIcon(":/icons/area"), tr("&Area"), buttonMenu);
areaAction->setData(QVariant(2));
QAction *uploadAction = new QAction(QIcon(":/icons/imgur"), tr("&Upload last"), buttonMenu);
uploadAction->setToolTip(tr("Upload the last screenshot you took to imgur.com"));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(uploadLast()));
QAction *historyAction = new QAction(QIcon(":/icons/view-history"), tr("View &History"), buttonMenu);
connect(historyAction, SIGNAL(triggered()), this, SLOT(showUploadDialog()));
QAction *goAction = new QAction(QIcon(":/icons/folder"), tr("&Go to Folder"), buttonMenu);
connect(goAction, SIGNAL(triggered()), this, SLOT(goToFolder()));
QActionGroup *screenshotGroup = new QActionGroup(buttonMenu);
screenshotGroup->addAction(screenAction);
screenshotGroup->addAction(windowAction);
screenshotGroup->addAction(windowPickerAction);
screenshotGroup->addAction(areaAction);
QMenu* imgurMenu = new QMenu(tr("Upload"));
imgurMenu->addAction(uploadAction);
imgurMenu->addAction(historyAction);
imgurMenu->addSeparator();
connect(screenshotGroup, SIGNAL(triggered(QAction*)), this, SLOT(screenshotActionTriggered(QAction*)));
buttonMenu->addAction(screenAction);
buttonMenu->addAction(areaAction);
buttonMenu->addAction(windowAction);
buttonMenu->addAction(windowPickerAction);
buttonMenu->addSeparator();
buttonMenu->addMenu(imgurMenu);
buttonMenu->addSeparator();
buttonMenu->addAction(goAction);
ui.screenshotPushButton->setMenu(buttonMenu);
ui.screenshotPushButton->showMenu();
}
-void LightscreenWindow::notify(const Screenshot::Result &result)
+void LightscreenWindow::showScreenshotMessage(const Screenshot::Result &result, const QString &fileName)
{
- switch (result)
- {
- case Screenshot::Success:
- mTrayIcon->setIcon(QIcon(":/icons/lightscreen.yes"));
+ if (result == Screenshot::Cancel
+ || mPreviewDialog)
+ return;
-#ifdef Q_WS_WIN
- if (mTaskbarButton)
- mTaskbarButton->SetOverlayIcon(QIcon(":/icons/yes"), tr("Success!"));
-#endif
+ // Showing message.
+ QString title;
+ QString message;
- setWindowTitle(tr("Success!"));
- break;
- case Screenshot::Fail:
- mTrayIcon->setIcon(QIcon(":/icons/lightscreen.no"));
- setWindowTitle(tr("Failed!"));
-#ifdef Q_WS_WIN
- if (mTaskbarButton)
- mTaskbarButton->SetOverlayIcon(QIcon(":/icons/no"), tr("Failed!"));
-#endif
- break;
- case Screenshot::Cancel:
- setWindowTitle(tr("Cancelled!"));
- break;
+ if (result == Screenshot::Success) {
+ title = QFileInfo(fileName).fileName();
+
+ if (settings()->value("file/target").toString().isEmpty()) {
+ message = QDir::toNativeSeparators(QCoreApplication::applicationDirPath());
+ }
+ else {
+ message = tr("Saved to \"%1\"").arg(settings()->value("file/target").toString());
+ }
+ }
+ else {
+ title = tr("The screenshot was not taken");
+ message = tr("An error occurred.");
}
- QTimer::singleShot(2000, this, SLOT(restoreNotification()));
+ mLastMessage = 1;
+ mTrayIcon->showMessage(title, message);
}
-void LightscreenWindow::optimizationDone()
+void LightscreenWindow::showUploadDialog()
{
- // A mouthful :D
- mOptimizeCount--;
- QString screenshot = (qobject_cast<QProcess*>(sender()))->property("screenshot").toString();
- upload(screenshot);
+ HistoryDialog historyDialog(this);
+ historyDialog.exec();
}
-void LightscreenWindow::showHotkeyError(const QStringList &hotkeys)
+void LightscreenWindow::showUploaderError(const QString &error)
{
- static bool dontShow = false;
-
- if (dontShow)
- return;
-
- QString messageText;
-
- messageText = tr("Some hotkeys could not be registered, they might already be in use");
-
- if (hotkeys.count() > 1) {
- messageText += tr("<br>The failed hotkeys are the following:") + "<ul>";
-
- foreach(const QString &hotkey, hotkeys) {
- messageText += QString("%1%2%3").arg("<li><b>").arg(hotkey).arg("</b></li>");
- }
-
- messageText += "</ul>";
- }
- else {
- messageText += tr("<br>The failed hotkey is <b>%1</b>").arg(hotkeys[0]);
- }
-
- messageText += tr("<br><i>What do you want to do?</i>");
+ mLastMessage = -1;
- QMessageBox msgBox(this);
- msgBox.setWindowTitle(tr("Lightscreen"));
- msgBox.setText(messageText);
+ if (mTrayIcon && !error.isEmpty()) {
+ mTrayIcon->showMessage(tr("Upload error"), error);
+ }
- QPushButton *changeButton = msgBox.addButton(tr("Change") , QMessageBox::ActionRole);
- QPushButton *disableButton = msgBox.addButton(tr("Disable"), QMessageBox::ActionRole);
- QPushButton *exitButton = msgBox.addButton(tr("Quit") , QMessageBox::ActionRole);
+ updateUploadStatus();
+}
- msgBox.exec();
+void LightscreenWindow::showUploaderMessage(QString fileName, QString url)
+{
+ if (!mTrayIcon)
+ return;
- if (msgBox.clickedButton() == exitButton) {
- dontShow = true;
- QTimer::singleShot(10, this, SLOT(quit()));
- }
- else if (msgBox.clickedButton() == changeButton) {
- showOptions();
- }
- else if (msgBox.clickedButton() == disableButton) {
- foreach(const QString &hotkey, hotkeys) {
- settings()->setValue(QString("actions/%1/enabled").arg(hotkey), false);
- }
- }
+ QString screenshot = QFileInfo(fileName).fileName();
+ mLastMessage = 2;
+ mTrayIcon->showMessage(tr("%1 uploaded").arg(screenshot), tr("Click here to go to %1").arg(url));
+ updateUploadStatus();
}
void LightscreenWindow::toggleVisibility(QSystemTrayIcon::ActivationReason reason)
{
if (reason != QSystemTrayIcon::DoubleClick)
return;
if (isVisible()) {
if (settings()->value("options/tray").toBool() == false
&& closingWithoutTray())
return;
hide();
}
else {
show();
}
}
-// Aliases
-void LightscreenWindow::windowHotkey() { screenshotAction(1); }
-void LightscreenWindow::windowPickerHotkey() { screenshotAction(3); }
-void LightscreenWindow::areaHotkey() { screenshotAction(2); }
+void LightscreenWindow::updateUploadStatus()
+{
+ int uploading = Uploader::instance()->uploading();
+ QString statusString;
-/*
- * Private
- */
+ if (uploading > 0) {
+ statusString = tr("Uploading %1 screenshot(s)").arg(uploading);
+ }
+ else {
+ statusString = tr("Lightscreen");
+#ifdef Q_WS_WIN
+ if (mTaskbarButton) {
+ mTaskbarButton->SetProgresValue(0, 0);
+ mTaskbarButton->SetState(STATE_NOPROGRESS);
+ }
+#endif
+ }
+
+ if (mTrayIcon) {
+ mTrayIcon->setToolTip(statusString);
+ }
+
+ setWindowTitle(statusString);
+}
+
+void LightscreenWindow::updaterDone(bool result)
+{
+ settings()->setValue("lastUpdateCheck", QDate::currentDate().dayOfYear());
+
+ if (!result)
+ return;
+
+ QMessageBox msgBox;
+ msgBox.setWindowTitle(tr("Lightscreen"));
+ msgBox.setText(tr("There's a new version of Lightscreen available.<br>Would you like to see more information?<br>(<em>You can turn this notification off</em>)"));
+ msgBox.setIcon(QMessageBox::Information);
+
+ QPushButton *yesButton = msgBox.addButton(QMessageBox::Yes);
+ QPushButton *turnOffButton = msgBox.addButton(tr("Turn Off"), QMessageBox::ActionRole);
+ QPushButton *remindButton = msgBox.addButton(tr("Remind Me Later"), QMessageBox::RejectRole);
+
+ Q_UNUSED(remindButton);
+
+ msgBox.exec();
+
+ if (msgBox.clickedButton() == yesButton) {
+ QDesktopServices::openUrl(QUrl("http://lightscreen.sourceforge.net/whatsnew/?from=" + qApp->applicationVersion()));
+ }
+ else if (msgBox.clickedButton() == turnOffButton) {
+ settings()->setValue("options/disableUpdater", true);
+ }
+}
+
+void LightscreenWindow::upload(const QString &fileName)
+{
+ Uploader::instance()->upload(fileName);
+}
+
+void LightscreenWindow::uploadAction(QAction *upload)
+{
+ QString url = upload->text();
+
+ if (url == tr("Uploading...")) {
+ int confirm = QMessageBox::question(this, tr("Upload cancel"), tr("Do you want to cancel the upload of %1").arg(upload->toolTip()), tr("Cancel"), tr("Don't Cancel"));
+
+ if (confirm == 0) {
+ Uploader::instance()->cancel(upload->whatsThis()); // Full path stored in the whatsThis
+ }
+ }
+ else {
+ QDesktopServices::openUrl(QUrl(url));
+ }
+}
+
+void LightscreenWindow::uploadLast()
+{
+ upload(mLastScreenshot);
+ updateUploadStatus();
+}
+
+void LightscreenWindow::uploadProgress(qint64 sent, qint64 total)
+{
+#ifdef Q_WS_WIN
+ if (mTaskbarButton)
+ mTaskbarButton->SetProgresValue(sent, total);
+#endif
+ //TODO: Update mTrayIcon & windowTitle()
+}
+
+void LightscreenWindow::windowHotkey()
+{
+ screenshotAction(1);
+}
+
+void LightscreenWindow::windowPickerHotkey()
+{
+ screenshotAction(3);
+}
+
+//
void LightscreenWindow::applySettings()
{
bool tray = settings()->value("options/tray").toBool();
if (tray && !mTrayIcon) {
createTrayIcon();
mTrayIcon->show();
}
else if (!tray && mTrayIcon) {
mTrayIcon->deleteLater();
}
connectHotkeys();
mDoCache = false;
if (settings()->value("lastScreenshot").isValid())
mLastScreenshot = settings()->value("lastScreenshot").toString();
os::setStartup(settings()->value("options/startup").toBool(), settings()->value("options/startupHide").toBool());
}
-void LightscreenWindow::optiPNG(const QString &fileName, bool upload)
-{
- if (upload) {
- // If the user has chosen to upload the screenshots we have to track the progress of the optimization, so we use QProcess
- QProcess* optipng = new QProcess(this);
-
- // To be read by optimizationDone() (for uploading)
- optipng->setProperty("screenshot", fileName);
-
- // Delete the QProcess once it's done.
- connect(optipng, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(optimizationDone()));
- connect(optipng, SIGNAL(finished(int, QProcess::ExitStatus)), optipng, SLOT(deleteLater()));
-
-#ifdef Q_OS_UNIX
- optipng->start("optipng", QStringList() << fileName);
-#else
- optipng->start(qApp->applicationDirPath() + QDir::separator() + "optipng.exe", QStringList() << fileName);
-#endif
-
- mOptimizeCount++;
- }
- else {
- // Otherwise start it detached from this process.
-#ifdef Q_WS_WIN
- ShellExecuteW(NULL, NULL, (LPCWSTR)QString(qApp->applicationDirPath() + QDir::separator() + "optipng.exe").toStdWString().data(), (LPCWSTR)fileName.toStdWString().data(), NULL, SW_HIDE);
-#endif
+//
-#ifdef Q_OS_UNIX
- QProcess::startDetached("optipng " + fileName + " -quiet");
-#endif
-
- ScreenshotManager::instance()->saveHistory(fileName);
- }
-}
void LightscreenWindow::connectHotkeys()
{
// Set to true because if the hotkey is disabled it will show an error.
bool screen = true, area = true, window = true, windowPicker = true, open = true, directory = true;
if (settings()->value("actions/screen/enabled").toBool())
screen = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/screen/hotkey").value<QKeySequence> (), this, SLOT(screenshotAction()));
if (settings()->value("actions/area/enabled").toBool())
area = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/area/hotkey").value<QKeySequence> (), this, SLOT(areaHotkey()));
if (settings()->value("actions/window/enabled").toBool())
window = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/window/hotkey").value<QKeySequence> (), this, SLOT(windowHotkey()));
if (settings()->value("actions/windowPicker/enabled").toBool())
windowPicker = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/windowPicker/hotkey").value<QKeySequence> (), this, SLOT(windowPickerHotkey()));
if (settings()->value("actions/open/enabled").toBool())
open = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/open/hotkey").value<QKeySequence> (), this, SLOT(show()));
if (settings()->value("actions/directory/enabled").toBool())
directory = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/directory/hotkey").value<QKeySequence> (), this, SLOT(goToFolder()));
QStringList failed;
if (!screen) failed << "screen";
if (!area) failed << "area";
if (!window) failed << "window";
if (!windowPicker) failed << "window picker";
if (!open) failed << "open";
if (!directory) failed << "directory";
if (!failed.isEmpty())
showHotkeyError(failed);
}
void LightscreenWindow::createTrayIcon()
{
mTrayIcon = new QSystemTrayIcon(QIcon(":/icons/lightscreen.small"), this);
updateUploadStatus();
connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason)));
connect(mTrayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
QAction *hideAction = new QAction(QIcon(":/icons/lightscreen.small"), tr("Show&/Hide"), mTrayIcon);
connect(hideAction, SIGNAL(triggered()), this, SLOT(toggleVisibility()));
QAction *screenAction = new QAction(QIcon(":/icons/screen"), tr("&Screen"), mTrayIcon);
screenAction->setData(QVariant(0));
QAction *windowAction = new QAction(QIcon(":/icons/window"), tr("Active &Window"), this);
windowAction->setData(QVariant(1));
QAction *windowPickerAction = new QAction(QIcon(":/icons/picker"), tr("&Pick Window"), this);
windowPickerAction->setData(QVariant(3));
QAction *areaAction = new QAction(QIcon(":/icons/area"), tr("&Area"), mTrayIcon);
areaAction->setData(QVariant(2));
QActionGroup *screenshotGroup = new QActionGroup(mTrayIcon);
screenshotGroup->addAction(screenAction);
screenshotGroup->addAction(areaAction);
screenshotGroup->addAction(windowAction);
screenshotGroup->addAction(windowPickerAction);
connect(screenshotGroup, SIGNAL(triggered(QAction*)), this, SLOT(screenshotActionTriggered(QAction*)));
// Duplicated for the screenshot button :(
QAction *uploadAction = new QAction(QIcon(":/icons/imgur"), tr("&Upload last"), mTrayIcon);
uploadAction->setToolTip(tr("Upload the last screenshot you took to imgur.com"));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(uploadLast()));
QAction *historyAction = new QAction(QIcon(":/icons/view-history"), tr("View History"), mTrayIcon);
connect(historyAction, SIGNAL(triggered()), this, SLOT(showUploadDialog()));
//
QAction *optionsAction = new QAction(QIcon(":/icons/configure"), tr("View &Options"), mTrayIcon);
connect(optionsAction, SIGNAL(triggered()), this, SLOT(showOptions()));
QAction *goAction = new QAction(QIcon(":/icons/folder"), tr("&Go to Folder"), mTrayIcon);
connect(goAction, SIGNAL(triggered()), this, SLOT(goToFolder()));
QAction *quitAction = new QAction(tr("&Quit"), mTrayIcon);
connect(quitAction, SIGNAL(triggered()), this, SLOT(quit()));
QMenu* screenshotMenu = new QMenu(tr("Screenshot"));
- screenshotMenu->addAction(screenAction);
+ screenshotMenu->addAction(screenAction);
screenshotMenu->addAction(areaAction);
screenshotMenu->addAction(windowAction);
screenshotMenu->addAction(windowPickerAction);
// Duplicated for the screenshot button :(
QMenu* imgurMenu = new QMenu(tr("Upload"));
imgurMenu->addAction(uploadAction);
imgurMenu->addAction(historyAction);
imgurMenu->addSeparator();
QMenu* trayIconMenu = new QMenu;
trayIconMenu->addAction(hideAction);
trayIconMenu->addSeparator();
trayIconMenu->addMenu(imgurMenu);
trayIconMenu->addSeparator();
trayIconMenu->addMenu(screenshotMenu);
trayIconMenu->addAction(optionsAction);
trayIconMenu->addAction(goAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
mTrayIcon->setContextMenu(trayIconMenu);
}
-#ifdef Q_WS_WIN
-bool LightscreenWindow::winEvent(MSG *message, long *result)
-{
- Taskbar::GetInstance()->winEvent(message, result);
- return false;
-}
-#endif
-
-QSettings *LightscreenWindow::settings() const
-{
- return ScreenshotManager::instance()->settings();
-}
-
-void LightscreenWindow::checkForUpdates()
-{
- if (settings()->value("options/disableUpdater", false).toBool())
- return;
-
- if (settings()->value("lastUpdateCheck").toInt() + 7
- > QDate::currentDate().dayOfYear())
- return; // If 7 days have not passed since the last update check.
-
- connect(Updater::instance(), SIGNAL(done(bool)), this, SLOT(updaterDone(bool)));
- Updater::instance()->check();
-}
-
-void LightscreenWindow::updaterDone(bool result)
+void LightscreenWindow::optiPNG(const QString &fileName, bool upload)
{
- settings()->setValue("lastUpdateCheck", QDate::currentDate().dayOfYear());
-
- if (!result)
- return;
-
- QMessageBox msgBox;
- msgBox.setWindowTitle(tr("Lightscreen"));
- msgBox.setText(tr("There's a new version of Lightscreen available.<br>Would you like to see more information?<br>(<em>You can turn this notification off</em>)"));
- msgBox.setIcon(QMessageBox::Information);
+ if (upload) {
+ // If the user has chosen to upload the screenshots we have to track the progress of the optimization, so we use QProcess
+ QProcess* optipng = new QProcess(this);
- QPushButton *yesButton = msgBox.addButton(QMessageBox::Yes);
- QPushButton *turnOffButton = msgBox.addButton(tr("Turn Off"), QMessageBox::ActionRole);
- QPushButton *remindButton = msgBox.addButton(tr("Remind Me Later"), QMessageBox::RejectRole);
+ // To be read by optimizationDone() (for uploading)
+ optipng->setProperty("screenshot", fileName);
- Q_UNUSED(remindButton);
+ // Delete the QProcess once it's done.
+ connect(optipng, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(optimizationDone()));
+ connect(optipng, SIGNAL(finished(int, QProcess::ExitStatus)), optipng, SLOT(deleteLater()));
- msgBox.exec();
+#ifdef Q_OS_UNIX
+ optipng->start("optipng", QStringList() << fileName);
+#else
+ optipng->start(qApp->applicationDirPath() + QDir::separator() + "optipng.exe", QStringList() << fileName);
+#endif
- if (msgBox.clickedButton() == yesButton) {
- QDesktopServices::openUrl(QUrl("http://lightscreen.sourceforge.net/whatsnew/?from=" + qApp->applicationVersion()));
- }
- else if (msgBox.clickedButton() == turnOffButton) {
- settings()->setValue("options/disableUpdater", true);
+ mOptimizeCount++;
}
-}
-
-void LightscreenWindow::upload(const QString &fileName)
-{
- Uploader::instance()->upload(fileName);
-}
-
-void LightscreenWindow::uploadAction(QAction *upload)
-{
- QString url = upload->text();
+ else {
+ // Otherwise start it detached from this process.
+#ifdef Q_WS_WIN
+ ShellExecuteW(NULL, NULL, (LPCWSTR)QString(qApp->applicationDirPath() + QDir::separator() + "optipng.exe").toStdWString().data(), (LPCWSTR)fileName.toStdWString().data(), NULL, SW_HIDE);
+#endif
- if (url == tr("Uploading...")) {
- int confirm = QMessageBox::question(this, tr("Upload cancel"), tr("Do you want to cancel the upload of %1").arg(upload->toolTip()), tr("Cancel"), tr("Don't Cancel"));
+#ifdef Q_OS_UNIX
+ QProcess::startDetached("optipng " + fileName + " -quiet");
+#endif
- if (confirm == 0) {
- Uploader::instance()->cancel(upload->whatsThis()); // Full path stored in the whatsThis
- }
- }
- else {
- QDesktopServices::openUrl(QUrl(url));
+ ScreenshotManager::instance()->saveHistory(fileName);
}
}
-void LightscreenWindow::uploadProgress(qint64 sent, qint64 total)
-{
#ifdef Q_WS_WIN
- if (mTaskbarButton)
- mTaskbarButton->SetProgresValue(sent, total);
-#endif
- //TODO: Update mTrayIcon & windowTitle()
-}
-
-void LightscreenWindow::uploadLast()
+bool LightscreenWindow::winEvent(MSG *message, long *result)
{
- upload(mLastScreenshot);
- updateUploadStatus();
+ Taskbar::GetInstance()->winEvent(message, result);
+ return false;
}
-
-void LightscreenWindow::updateUploadStatus()
-{
- int uploading = Uploader::instance()->uploading();
- QString statusString;
-
- if (uploading > 0) {
- statusString = tr("Uploading %1 screenshot(s)").arg(uploading);
- }
- else {
- statusString = tr("Lightscreen");
-#ifdef Q_WS_WIN
- if (mTaskbarButton) {
- mTaskbarButton->SetProgresValue(0, 0);
- mTaskbarButton->SetState(STATE_NOPROGRESS);
- }
#endif
- }
- if (mTrayIcon) {
- mTrayIcon->setToolTip(statusString);
- }
-
- setWindowTitle(statusString);
+QSettings *LightscreenWindow::settings() const
+{
+ return ScreenshotManager::instance()->settings();
}
// Event handling
bool LightscreenWindow::event(QEvent *event)
{
if (event->type() == QEvent::Hide) {
settings()->setValue("position", pos());
}
else if (event->type() == QEvent::Close) {
quit();
}
else if (event->type() == QEvent::Show) {
os::aeroGlass(this);
if (!settings()->value("position").toPoint().isNull())
move(settings()->value("position").toPoint());
}
else if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
#ifdef Q_WS_MAC
if (keyEvent->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) {
keyEvent->ignore();
if(isVisible())
toggleVisibility();
return false;
}
else
#endif
if (!keyEvent->modifiers() && keyEvent->key() == Qt::Key_Escape) {
keyEvent->ignore();
if(isVisible())
toggleVisibility();
return false;
}
}
else if (event->type() == QEvent::LanguageChange) {
ui.retranslateUi(this);
resize(minimumSizeHint());
}
return QDialog::event(event);
}
-
-
diff --git a/lightscreenwindow.h b/lightscreenwindow.h
index d3a8b17..1451405 100644
--- a/lightscreenwindow.h
+++ b/lightscreenwindow.h
@@ -1,115 +1,116 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef LIGHTSCREENWINDOW_H
#define LIGHTSCREENWINDOW_H
#include <QtGui/QDialog>
#include <QPointer>
#include <QSystemTrayIcon>
#include "updater/updater.h"
#include "tools/screenshot.h"
#include "dialogs/previewdialog.h"
#include "ui_lightscreenwindow.h"
#ifdef Q_WS_WIN
#include "tools/qwin7utils/TaskbarButton.h"
#endif
class QHttp;
class Updater;
class QSettings;
class LightscreenWindow : public QDialog
{
Q_OBJECT
public:
LightscreenWindow(QWidget *parent = 0);
~LightscreenWindow();
public slots:
void action(int mode = 3);
void areaHotkey();
void checkForUpdates();
void cleanup(Screenshot::Options &options);
bool closingWithoutTray();
void goToFolder();
void messageClicked();
void messageReceived(const QString &message);
void notify(const Screenshot::Result &result);
void optimizationDone();
void preview(Screenshot* screenshot);
void quit();
void restoreNotification();
void screenshotAction(int mode = 0);
void screenshotActionTriggered(QAction* action);
void showHotkeyError(const QStringList &hotkeys);
void showOptions();
void showScreenshotMenu();
void showScreenshotMessage(const Screenshot::Result &result, const QString &fileName);
void showUploadDialog();
void showUploaderError(const QString &error);
void showUploaderMessage(QString fileName, QString url);
void toggleVisibility(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::DoubleClick);
void updateUploadStatus();
void updaterDone(bool result);
void upload(const QString &fileName);
void uploadAction(QAction* upload);
- void uploadProgress(qint64 sent, qint64 total);
void uploadLast();
+ void uploadProgress(qint64 sent, qint64 total);
void windowHotkey();
void windowPickerHotkey();
private slots:
void applySettings();
private:
- void optiPNG(const QString &fileName, bool upload);
void connectHotkeys();
void createTrayIcon();
+ void optiPNG(const QString &fileName, bool upload);
+
#ifdef Q_WS_WIN
bool winEvent(MSG *message, long *result);
#endif
// Convenience function
QSettings *settings() const;
protected:
bool event(QEvent *event);
private:
bool mDoCache;
bool mHideTrigger;
bool mReviveMain;
bool mWasVisible;
- int mOptimizeCount;
- int mLastMode;
int mLastMessage;
+ int mLastMode;
+ int mOptimizeCount;
QString mLastScreenshot;
QPointer<QSystemTrayIcon> mTrayIcon;
QPointer<PreviewDialog> mPreviewDialog;
Ui::LightscreenWindowClass ui;
#ifdef Q_WS_WIN
QW7::TaskbarButton *mTaskbarButton;
#endif
};
#endif // LIGHTSCREENWINDOW_H
diff --git a/main.cpp b/main.cpp
index 909e665..65e2955 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,103 +1,102 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
#include <QDesktopWidget>
#include <QLocale>
+
#include <QDebug>
#ifdef Q_WS_WIN
#include "tools/qwin7utils/AppUserModel.h"
#include "tools/qwin7utils/JumpList.h"
#include "tools/qwin7utils/Taskbar.h"
using namespace QW7;
#endif
#include "tools/os.h"
#include <QtSingleApplication>
#include "lightscreenwindow.h"
-#include <QMessageBox>
-
int main(int argc, char *argv[])
{
QtSingleApplication application(argc, argv);
application.setOrganizationName("K");
application.setApplicationName ("Lightscreen");
application.setApplicationVersion("2.0");
application.setQuitOnLastWindowClosed(false);
if (application.isRunning()) {
if (application.arguments().size() > 1) {
QStringList arguments = application.arguments();
arguments.removeFirst();
application.sendMessage(arguments.join(" "));
}
else {
application.sendMessage("--wake");
}
return 0;
}
LightscreenWindow lightscreen;
#ifdef Q_WS_WIN
// Windows 7 jumplists.
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
AppUserModel::SetCurrentProcessExplicitAppUserModelID("Lightscreen");
JumpList jumpList("Lightscreen");
QList<JumpListItem> tasks;
tasks.append(JumpListItem(application.applicationFilePath(), "--screen" , QObject::tr("Screen") , "", "", 0, application.applicationDirPath()));
tasks.append(JumpListItem(application.applicationFilePath(), "--area" , QObject::tr("Area") , "", "", 0, application.applicationDirPath()));
tasks.append(JumpListItem(application.applicationFilePath(), "--activewindow", QObject::tr("Active Window"), "", "", 0, application.applicationDirPath()));
tasks.append(JumpListItem(application.applicationFilePath(), "--pickwindow" , QObject::tr("Pick Window") , "", "", 0, application.applicationDirPath()));
tasks.append(JumpListItem());
tasks.append(JumpListItem(application.applicationFilePath(), "--uploadlast" , QObject::tr("Upload Last") , "", "", 0, application.applicationDirPath()));
tasks.append(JumpListItem(application.applicationFilePath(), "--viewhistory" , QObject::tr("View History") , "", "", 0, application.applicationDirPath()));
tasks.append(JumpListItem());
tasks.append(JumpListItem(application.applicationFilePath(), "--folder" , QObject::tr("Go to Folder") , "", "", 0, application.applicationDirPath()));
jumpList.Begin();
jumpList.AddUserTasks(tasks);
jumpList.Commit();
}
#endif
if (application.arguments().size() > 1) {
foreach (QString argument, application.arguments()) {
lightscreen.messageReceived(argument);
}
}
else {
lightscreen.show();
}
QObject::connect(&application, SIGNAL(messageReceived(const QString&)), &lightscreen, SLOT(messageReceived(const QString&)));
QObject::connect(&lightscreen, SIGNAL(finished(int)), &application, SLOT(quit()));
int result = application.exec();
#ifdef Q_WS_WIN
Taskbar::ReleaseInstance();
#endif
return result;
}
diff --git a/tools/os.cpp b/tools/os.cpp
index 9f2497e..0c139cd 100644
--- a/tools/os.cpp
+++ b/tools/os.cpp
@@ -1,408 +1,409 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
#include <QBitmap>
+#include <QDesktopServices>
#include <QDesktopWidget>
#include <QDialog>
#include <QDir>
-#include <QSettings>
+#include <QGraphicsDropShadowEffect>
#include <QLibrary>
#include <QPixmap>
+#include <QPointer>
+#include <QProcess>
+#include <QSettings>
#include <QTextEdit>
-#include <QTranslator>
-#include <QTimer>
#include <QTimeLine>
+#include <QTimer>
+#include <QTranslator>
+#include <QUrl>
#include <QWidget>
-#include <QGraphicsDropShadowEffect>
#include <string>
-#include <QDesktopServices>
-#include <QPointer>
-#include <QProcess>
-#include <QUrl>
+
#include <QDebug>
#include <QMessageBox>
#include "qtwin.h"
#ifdef Q_WS_WIN
#include <qt_windows.h>
#include <shlobj.h>
#elif defined(Q_WS_X11)
#include <QX11Info>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#endif
#include "os.h"
void os::addToRecentDocuments(QString fileName)
{
#ifdef Q_WS_WIN
QT_WA ( {
SHAddToRecentDocs (0x00000003, QDir::toNativeSeparators(fileName).utf16());
} , {
SHAddToRecentDocs (0x00000002, QDir::toNativeSeparators(fileName).toLocal8Bit().data());
} ); // QT_WA
#else
Q_UNUSED(fileName)
#endif
}
bool os::aeroGlass(QWidget* target)
{
if (QtWin::isCompositionEnabled() && QtWin::extendFrameIntoClientArea(target)) {
return true;
}
return false;
}
-void os::setStartup(bool startup, bool hide)
+QPixmap os::cursor()
{
- QString lightscreen = QDir::toNativeSeparators(qApp->applicationFilePath());
+#ifdef Q_WS_WIN
+ /*
+ * Taken from: git://github.com/arrai/mumble-record.git ? src ? mumble ? Overlay.cpp
+ * BSD License.
+ */
- if (hide)
- lightscreen.append(" -h");
+ QPixmap pixmap;
-#ifdef Q_WS_WIN
- // Windows startup settings
- QSettings init("Microsoft", "Windows");
- init.beginGroup("CurrentVersion");
- init.beginGroup("Run");
+ CURSORINFO cursorInfo;
+ cursorInfo.cbSize = sizeof(cursorInfo);
+ ::GetCursorInfo(&cursorInfo);
- if (startup) {
- init.setValue("Lightscreen", lightscreen);
- }
- else {
- init.remove("Lightscreen");
- }
+ HICON cursor = (HICON) cursorInfo.hCursor;
- init.endGroup();
- init.endGroup();
-#endif
+ ICONINFO info;
+ ZeroMemory(&info, sizeof(info));
-#if defined(Q_WS_X11)
- QFile desktopFile(QDir::homePath() + "/.config/autostart/lightscreen.desktop");
+ if (::GetIconInfo(cursor, &info)) {
+ if (info.hbmColor) {
+ pixmap = QPixmap::fromWinHBITMAP(info.hbmColor);
+ pixmap.setMask(QBitmap(QPixmap::fromWinHBITMAP(info.hbmMask)));
+ }
+ else {
+ QBitmap orig(QPixmap::fromWinHBITMAP(info.hbmMask));
+ QImage img = orig.toImage();
- desktopFile.remove();
+ int h = img.height() / 2;
+ int w = img.bytesPerLine() / sizeof(quint32);
- if (startup) {
- desktopFile.open(QIODevice::WriteOnly);
- desktopFile.write(QString("[Desktop Entry]\nExec=%1\nType=Application").arg(lightscreen).toAscii());
+ QImage out(img.width(), h, QImage::Format_MonoLSB);
+ QImage outmask(img.width(), h, QImage::Format_MonoLSB);
+
+ for (int i=0;i<h; ++i) {
+ const quint32 *srcimg = reinterpret_cast<const quint32 *>(img.scanLine(i + h));
+ const quint32 *srcmask = reinterpret_cast<const quint32 *>(img.scanLine(i));
+
+ quint32 *dstimg = reinterpret_cast<quint32 *>(out.scanLine(i));
+ quint32 *dstmask = reinterpret_cast<quint32 *>(outmask.scanLine(i));
+
+ for (int j=0;j<w;++j) {
+ dstmask[j] = srcmask[j];
+ dstimg[j] = srcimg[j];
+ }
+ }
+
+ pixmap = QBitmap::fromImage(out, Qt::ColorOnly);
+ }
+
+ if (info.hbmMask)
+ ::DeleteObject(info.hbmMask);
+
+ if (info.hbmColor)
+ ::DeleteObject(info.hbmColor);
}
+
+ return pixmap;
+#else
+ return QPixmap();
#endif
}
+void os::effect(QObject* target, const char *slot, int frames, int duration, const char* cleanup)
+{
+ QTimeLine* timeLine = new QTimeLine(duration);
+ timeLine->setFrameRange(0, frames);
+
+ timeLine->connect(timeLine, SIGNAL(frameChanged(int)), target, slot);
+
+ if (cleanup != 0)
+ timeLine->connect(timeLine, SIGNAL(finished()), target, SLOT(cleanup()));
+
+ timeLine->connect(timeLine, SIGNAL(finished()), timeLine, SLOT(deleteLater()));
+
+
+ timeLine->start();
+}
+
QString os::getDocumentsPath()
{
#ifdef Q_WS_WIN
TCHAR szPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL,
CSIDL_PERSONAL|CSIDL_FLAG_CREATE,
NULL,
0,
szPath)))
{
std::wstring path(szPath);
return QString::fromWCharArray(path.c_str());
}
return QDir::homePath() + QDir::separator() + "My Documents";
#else
return QDir::homePath() + QDir::separator() + "Documents";
#endif
}
QPixmap os::grabWindow(WId winId)
{
#ifdef Q_WS_WIN
RECT rcWindow;
GetWindowRect(winId, &rcWindow);
if (IsZoomed(winId)) {
int margin = GetSystemMetrics(SM_CXSIZEFRAME);
rcWindow.right -= margin;
rcWindow.left += margin;
rcWindow.top += margin;
rcWindow.bottom -= margin;
}
int width, height;
width = rcWindow.right - rcWindow.left;
height = rcWindow.bottom - rcWindow.top;
RECT rcScreen;
GetWindowRect(GetDesktopWindow(), &rcScreen);
RECT rcResult;
UnionRect(&rcResult, &rcWindow, &rcScreen);
QPixmap pixmap;
// Comparing the rects to determine if the window is outside the boundaries of the screen,
// the window DC method has the disadvantage that it does not show Aero glass transparency,
// so we'll avoid it for the screenshots that don't need it.
HDC hdcMem;
HBITMAP hbmCapture;
if (EqualRect(&rcScreen, &rcResult)) {
// Grabbing the window from the Screen DC.
HDC hdcScreen = GetDC(NULL);
BringWindowToTop(winId);
hdcMem = CreateCompatibleDC(hdcScreen);
hbmCapture = CreateCompatibleBitmap(hdcScreen, width, height);
SelectObject(hdcMem, hbmCapture);
BitBlt(hdcMem, 0, 0, width, height, hdcScreen, rcWindow.left, rcWindow.top, SRCCOPY);
}
else {
// Grabbing the window by its own DC
HDC hdcWindow = GetWindowDC(winId);
hdcMem = CreateCompatibleDC(hdcWindow);
hbmCapture = CreateCompatibleBitmap(hdcWindow, width, height);
SelectObject(hdcMem, hbmCapture);
BitBlt(hdcMem, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY);
}
ReleaseDC(winId, hdcMem);
DeleteDC(hdcMem);
pixmap = QPixmap::fromWinHBITMAP(hbmCapture);
DeleteObject(hbmCapture);
return pixmap;
#else
return QPixmap::grabWindow(winId);
#endif
}
void os::setForegroundWindow(QWidget *window)
{
#ifdef Q_WS_WIN
ShowWindow(window->winId(), SW_RESTORE);
SetForegroundWindow(window->winId());
#else
Q_UNUSED(window)
#endif
}
-QPixmap os::cursor()
+void os::setStartup(bool startup, bool hide)
{
-#ifdef Q_WS_WIN
- /*
- * Taken from: git://github.com/arrai/mumble-record.git ? src ? mumble ? Overlay.cpp
- * BSD License.
- */
-
- QPixmap pixmap;
-
- CURSORINFO cursorInfo;
- cursorInfo.cbSize = sizeof(cursorInfo);
- ::GetCursorInfo(&cursorInfo);
-
- HICON cursor = (HICON) cursorInfo.hCursor;
-
- ICONINFO info;
- ZeroMemory(&info, sizeof(info));
-
- if (::GetIconInfo(cursor, &info)) {
- if (info.hbmColor) {
- pixmap = QPixmap::fromWinHBITMAP(info.hbmColor);
- pixmap.setMask(QBitmap(QPixmap::fromWinHBITMAP(info.hbmMask)));
- }
- else {
- QBitmap orig(QPixmap::fromWinHBITMAP(info.hbmMask));
- QImage img = orig.toImage();
-
- int h = img.height() / 2;
- int w = img.bytesPerLine() / sizeof(quint32);
+ QString lightscreen = QDir::toNativeSeparators(qApp->applicationFilePath());
- QImage out(img.width(), h, QImage::Format_MonoLSB);
- QImage outmask(img.width(), h, QImage::Format_MonoLSB);
+ if (hide)
+ lightscreen.append(" -h");
- for (int i=0;i<h; ++i) {
- const quint32 *srcimg = reinterpret_cast<const quint32 *>(img.scanLine(i + h));
- const quint32 *srcmask = reinterpret_cast<const quint32 *>(img.scanLine(i));
+#ifdef Q_WS_WIN
+ // Windows startup settings
+ QSettings init("Microsoft", "Windows");
+ init.beginGroup("CurrentVersion");
+ init.beginGroup("Run");
- quint32 *dstimg = reinterpret_cast<quint32 *>(out.scanLine(i));
- quint32 *dstmask = reinterpret_cast<quint32 *>(outmask.scanLine(i));
+ if (startup) {
+ init.setValue("Lightscreen", lightscreen);
+ }
+ else {
+ init.remove("Lightscreen");
+ }
- for (int j=0;j<w;++j) {
- dstmask[j] = srcmask[j];
- dstimg[j] = srcimg[j];
- }
- }
+ init.endGroup();
+ init.endGroup();
+#endif
- pixmap = QBitmap::fromImage(out, Qt::ColorOnly);
- }
+#if defined(Q_WS_X11)
+ QFile desktopFile(QDir::homePath() + "/.config/autostart/lightscreen.desktop");
- if (info.hbmMask)
- ::DeleteObject(info.hbmMask);
+ desktopFile.remove();
- if (info.hbmColor)
- ::DeleteObject(info.hbmColor);
+ if (startup) {
+ desktopFile.open(QIODevice::WriteOnly);
+ desktopFile.write(QString("[Desktop Entry]\nExec=%1\nType=Application").arg(lightscreen).toAscii());
}
-
- return pixmap;
-#else
- return QPixmap();
#endif
}
+QGraphicsEffect* os::shadow(QColor color, int blurRadius, int offset) {
+ QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect;
+ shadowEffect->setBlurRadius(blurRadius);
+ shadowEffect->setOffset(offset);
+ shadowEffect->setColor(color);
+
+ return shadowEffect;
+}
+
void os::translate(QString language)
{
static QTranslator *translator = 0;
static QTranslator *translator_qt = 0;
if ((language.compare("English", Qt::CaseInsensitive) == 0
|| language.isEmpty()) && translator) {
qApp->removeTranslator(translator);
qApp->removeTranslator(translator_qt);
QLocale::setDefault(QLocale::c());
return;
}
if (translator) {
delete translator;
delete translator_qt;
}
translator = new QTranslator(qApp);
translator_qt = new QTranslator(qApp);
if (language == "Espa?ol")
QLocale::setDefault(QLocale::Spanish);
if (translator->load(language, ":/translations")) {
qApp->installTranslator(translator);
}
if (translator_qt->load(language, ":/translations_qt")) {
qApp->installTranslator(translator_qt);
}
}
-void os::effect(QObject* target, const char *slot, int frames, int duration, const char* cleanup)
-{
- QTimeLine* timeLine = new QTimeLine(duration);
- timeLine->setFrameRange(0, frames);
-
- timeLine->connect(timeLine, SIGNAL(frameChanged(int)), target, slot);
-
- if (cleanup != 0)
- timeLine->connect(timeLine, SIGNAL(finished()), target, SLOT(cleanup()));
-
- timeLine->connect(timeLine, SIGNAL(finished()), timeLine, SLOT(deleteLater()));
-
-
- timeLine->start();
-}
-
-QGraphicsEffect* os::shadow(QColor color, int blurRadius, int offset) {
- QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect;
- shadowEffect->setBlurRadius(blurRadius);
- shadowEffect->setOffset(offset);
- shadowEffect->setColor(color);
-
- return shadowEffect;
-}
-
#ifdef Q_WS_X11
// Taken from KSnapshot. Oh KDE, what would I do whithout you :D
Window os::findRealWindow(Window w, int depth)
{
if( depth > 5 ) {
return None;
}
static Atom wm_state = XInternAtom( QX11Info::display(), "WM_STATE", False );
Atom type;
int format;
unsigned long nitems, after;
unsigned char* prop;
if( XGetWindowProperty( QX11Info::display(), w, wm_state, 0, 0, False, AnyPropertyType,
&type, &format, &nitems, &after, &prop ) == Success ) {
if( prop != NULL ) {
XFree( prop );
}
if( type != None ) {
return w;
}
}
Window root, parent;
Window* children;
unsigned int nchildren;
Window ret = None;
if( XQueryTree( QX11Info::display(), w, &root, &parent, &children, &nchildren ) != 0 ) {
for( unsigned int i = 0;
i < nchildren && ret == None;
++i ) {
ret = os::findRealWindow( children[ i ], depth + 1 );
}
if( children != NULL ) {
XFree( children );
}
}
return ret;
}
Window os::windowUnderCursor(bool includeDecorations)
{
Window root;
Window child;
uint mask;
int rootX, rootY, winX, winY;
XQueryPointer( QX11Info::display(), QX11Info::appRootWindow(), &root, &child,
&rootX, &rootY, &winX, &winY, &mask );
if( child == None ) {
child = QX11Info::appRootWindow();
}
if( !includeDecorations ) {
Window real_child = os::findRealWindow( child );
if( real_child != None ) { // test just in case
child = real_child;
}
}
return child;
}
#endif
diff --git a/tools/os.h b/tools/os.h
index 1d44681..d284b6f 100644
--- a/tools/os.h
+++ b/tools/os.h
@@ -1,62 +1,75 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef OS_H_
#define OS_H_
#include <QWidget>
struct QPixmap;
struct QPoint;
struct QString;
struct QUrl;
class QGraphicsEffect;
-typedef unsigned long XID;
-typedef XID Window;
+
+#if defined(Q_WS_X11)
+ typedef unsigned long XID;
+ typedef XID Window;
+#endif
namespace os
{
- // Gives the target widget a full aero glass background
- bool aeroGlass(QWidget *target);
// Adds the filename to the Windows recent document list (useful for Windows 7 jump lists)
void addToRecentDocuments(QString fileName);
+
+ // Gives the target widget a full aero glass background
+ bool aeroGlass(QWidget *target);
+
// Returns the cursor pixmap in Windows
QPixmap cursor();
- // Adds lightscreen to the startup list in Windows & Linux (KDE, Gnome and Xfce for now).
- void setStartup(bool startup, bool hide);
- // Set the target window as the foreground window (Windows only)
- void setForegroundWindow(QWidget *window);
+
+ // A QTimeLine based effect for a slot (TODO: look at the new effect classes)
+ void effect(QObject* target, const char* slot, int frames, int duration = 400, const char* cleanup = 0);
+
// Returns the current users's Documents/My Documents folder
QString getDocumentsPath();
+
// Returns the pixmap of the given window id.
QPixmap grabWindow(WId winId);
- // Translates the ui to the given language name.
- void translate(QString language);
- // A QTimeLine based effect for a slot (TODO: look at the new effect classes)
- void effect(QObject* target, const char* slot, int frames, int duration = 400, const char* cleanup = 0);
+
+ // Set the target window as the foreground window (Windows only)
+ void setForegroundWindow(QWidget *window);
+
+ // Adds lightscreen to the startup list in Windows & Linux (KDE, Gnome and Xfce for now).
+ void setStartup(bool startup, bool hide);
+
// Creates a new QGraphicsDropShadowEffect to apply to widgets.
QGraphicsEffect* shadow(QColor color = Qt::black, int blurRadius = 6, int offset = 1);
+
+ // Translates the ui to the given language name.
+ void translate(QString language);
+
// X11-specific functions for the Window Picker
#if defined(Q_WS_X11)
Window findRealWindow(Window w, int depth = 0);
Window windowUnderCursor(bool includeDecorations = true);
#endif
}
#endif /*OS_H_*/
diff --git a/tools/qtimgur.cpp b/tools/qtimgur.cpp
index 10932a6..7ddbd51 100644
--- a/tools/qtimgur.cpp
+++ b/tools/qtimgur.cpp
@@ -1,133 +1,134 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "qtimgur.h"
+#include <QFile>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
-#include <QFile>
#include <QXmlStreamReader>
+
#include <QDebug>
QtImgur::QtImgur(const QString &APIKey, QObject *parent) : QObject(parent), mAPIKey(APIKey)
{
mNetworkManager = new QNetworkAccessManager(this);
connect(mNetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(reply(QNetworkReply*)));
}
+void QtImgur::cancel(const QString &fileName)
+{
+ QNetworkReply *reply = mFiles.key(fileName);
+
+ if (!reply) {
+ return;
+ }
+
+ reply->abort();
+ mFiles.remove(reply);
+ reply->deleteLater();
+}
+
void QtImgur::upload(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
emit error(fileName, QtImgur::ErrorFile);
return;
}
QByteArray image = file.readAll().toBase64();
file.close();
QByteArray data;
data.append(QString("key=").toUtf8());
data.append(QUrl::toPercentEncoding(mAPIKey));
data.append(QString("&image=").toUtf8());
data.append(QUrl::toPercentEncoding(image));
QNetworkReply *reply = mNetworkManager->post(QNetworkRequest(QUrl("http://api.imgur.com/2/upload.xml")), data);
connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));
mFiles.insert(reply, fileName);
}
-void QtImgur::cancel(const QString &fileName)
+void QtImgur::progress(qint64 bytesSent, qint64 bytesTotal)
{
- QNetworkReply *reply = mFiles.key(fileName);
+ qint64 totalSent, totalTotal;
- if (!reply) {
- return;
+ QNetworkReply *senderReply = qobject_cast<QNetworkReply*>(sender());
+
+ senderReply->setProperty("bytesSent", bytesSent);
+ senderReply->setProperty("bytesTotal", bytesTotal);
+
+ totalSent = bytesSent;
+ totalTotal = bytesTotal;
+
+ foreach (QNetworkReply *reply, mFiles.keys()) {
+ if (reply != senderReply) {
+ totalSent += reply->property("bytesSent").toLongLong();
+ totalTotal += reply->property("bytesTotal").toLongLong();
+ }
}
- reply->abort();
- mFiles.remove(reply);
- reply->deleteLater();
+ emit uploadProgress(totalSent, totalTotal);
}
void QtImgur::reply(QNetworkReply *reply)
{
QString fileName = mFiles[reply];
mFiles.remove(reply);
if (reply->error() != QNetworkReply::NoError) {
emit error(fileName, QtImgur::ErrorNetwork);
return;
}
if (reply->error() == QNetworkReply::OperationCanceledError) {
emit error(fileName, QtImgur::ErrorCancel);
return;
}
if (reply->rawHeader("X-RateLimit-Remaining") == "0") {
emit error(fileName, QtImgur::ErrorCredits);
return;
}
QXmlStreamReader reader(reply->readAll());
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement()) {
if (reader.name() == "error") {
emit error(fileName, QtImgur::ErrorUpload);
}
if (reader.name() == "imgur_page") {
QString url = reader.readElementText();
emit uploaded(fileName, url);
}
}
}
reply->deleteLater();
}
-
-void QtImgur::progress(qint64 bytesSent, qint64 bytesTotal)
-{
- qint64 totalSent, totalTotal;
-
- QNetworkReply *senderReply = qobject_cast<QNetworkReply*>(sender());
-
- senderReply->setProperty("bytesSent", bytesSent);
- senderReply->setProperty("bytesTotal", bytesTotal);
-
- totalSent = bytesSent;
- totalTotal = bytesTotal;
-
- foreach (QNetworkReply *reply, mFiles.keys()) {
- if (reply != senderReply) {
- totalSent += reply->property("bytesSent").toLongLong();
- totalTotal += reply->property("bytesTotal").toLongLong();
- }
- }
-
- emit uploadProgress(totalSent, totalTotal);
-}
diff --git a/tools/qtimgur.h b/tools/qtimgur.h
index b18016a..bf1f51e 100644
--- a/tools/qtimgur.h
+++ b/tools/qtimgur.h
@@ -1,61 +1,61 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef QTIMGUR_H
#define QTIMGUR_H
#include <QObject>
#include <QHash>
#include <QNetworkReply>
class QNetworkAccessManager;
class QtImgur: public QObject {
Q_OBJECT
public:
enum Error {
ErrorFile,
ErrorNetwork,
ErrorCredits,
ErrorUpload,
ErrorCancel
};
QtImgur(const QString &APIKey, QObject *parent);
public slots:
- void upload(const QString &fileName);
void cancel(const QString &fileName);
+ void upload(const QString &fileName);
protected slots:
- void reply(QNetworkReply* reply);
void progress(qint64, qint64);
+ void reply(QNetworkReply* reply);
signals:
- void uploaded(QString file, QString url);
void error(QString, QtImgur::Error);
void uploadProgress(qint64, qint64);
+ void uploaded(QString file, QString url);
private:
QString mAPIKey;
QNetworkAccessManager *mNetworkManager;
QHash<QNetworkReply*, QString> mFiles;
};
#endif // QTIMGUR_H
diff --git a/tools/screenshot.cpp b/tools/screenshot.cpp
index b6fda1a..aab6061 100644
--- a/tools/screenshot.cpp
+++ b/tools/screenshot.cpp
@@ -1,400 +1,407 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
#include <QClipboard>
#include <QDateTime>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QPainter>
#include <QPixmap>
+
#include <QDebug>
#include "windowpicker.h"
#include "../dialogs/areadialog.h"
#include "screenshot.h"
#include "os.h"
#ifdef Q_WS_WIN
#include <windows.h>
#endif
#ifdef Q_WS_X11
#include <QX11Info>
#include <X11/X.h>
#include <X11/Xlib.h>
#endif
Screenshot::Screenshot(QObject *parent, Screenshot::Options options):
QObject(parent),
mOptions(options),
mPixmapDelay(false),
mUnloaded(false),
mUnloadFilename()
{
// Here be crickets
}
Screenshot::~Screenshot()
{
if (mUnloaded) {
QFile::remove(mUnloadFilename);
}
}
-Screenshot::Options &Screenshot::options()
-{
- return mOptions;
-}
-
-QPixmap &Screenshot::pixmap()
-{
- if (mUnloaded) {
- // A local reference.. what could go wrong? Nothing! Right guys? Guys?
- QPixmap p;
- p.load(mUnloadFilename);
- return p;
- }
-
- return mPixmap;
-}
-
-void Screenshot::activeWindow()
-{
-#ifdef Q_WS_WIN
- HWND fWindow = GetForegroundWindow();
-
- if (fWindow == NULL)
- return;
-
- if (fWindow == GetDesktopWindow()) {
- wholeScreen();
- return;
- }
-
- mPixmap = os::grabWindow(GetForegroundWindow());
-#endif
-
-#if defined(Q_WS_X11)
- Window focus;
- int revert;
-
- XGetInputFocus(QX11Info::display(), &focus, &revert);
-
- mPixmap = QPixmap::grabWindow(focus);
-#endif
-}
-
QString Screenshot::getName(NamingOptions options, QString prefix, QDir directory)
{
QString naming;
int naming_largest = 0;
if (options.flip) {
naming = "%1" + prefix;
}
else {
naming = prefix + "%1";
}
switch (options.naming)
{
case Screenshot::Numeric: // Numeric
// Iterating through the folder to find the largest numeric naming.
foreach(QString file, directory.entryList(QDir::Files))
{
if (file.contains(prefix)) {
file.chop(file.size() - file.lastIndexOf("."));
file.remove(prefix);
if (file.toInt()> naming_largest) {
naming_largest = file.toInt();
}
}
}
if (options.leadingZeros > 0) {
//Pretty, huh?
QString format;
QTextStream (&format) << "%0" << (options.leadingZeros+1) << "d";
naming = naming.arg(QString().sprintf(format.toAscii(), naming_largest + 1));
}
else {
naming = naming.arg(naming_largest + 1);
}
break;
case Screenshot::Date: // Date
naming = naming.arg(QLocale().toString(QDateTime::currentDateTime(), options.dateFormat));
break;
case Screenshot::Timestamp: // Timestamp
naming = naming.arg(QDateTime::currentDateTime().toTime_t());
break;
case Screenshot::Empty:
naming = naming.arg("");
break;
}
return naming;
}
-QString Screenshot::newFileName() const
-{
- if (!mOptions.directory.exists())
- mOptions.directory.mkpath(mOptions.directory.path());
-
- QString naming = Screenshot::getName(mOptions.namingOptions, mOptions.prefix, mOptions.directory);
-
- QString fileName;
-
- QString path = QDir::toNativeSeparators(mOptions.directory.path());
-
- // Cleanup
- if (path.at(path.size()-1) != QDir::separator() && !path.isEmpty())
- path.append(QDir::separator());
-
- fileName.append(path);
- fileName.append(naming);
-
- return fileName;
-}
-
-void Screenshot::markUpload()
-{
- mOptions.upload = true;
-}
-
-QString Screenshot::extension() const
+Screenshot::Options &Screenshot::options()
{
- switch (mOptions.format) {
- case Screenshot::PNG:
- return ".png";
- break;
- case Screenshot::BMP:
- return ".bmp";
- break;
- case Screenshot::JPEG:
- default:
- return ".jpg";
- break;
- }
+ return mOptions;
}
-void Screenshot::selectedArea()
+QPixmap &Screenshot::pixmap()
{
- grabDesktop();
-
- if (mPixmap.isNull())
- return;
-
- AreaDialog selector(this);
- int result = selector.exec();
-
- if (result == QDialog::Accepted) {
- mPixmap = mPixmap.copy(selector.resultRect());
- }
- else {
- mPixmap = QPixmap();
+ if (mUnloaded) {
+ // A local reference.. what could go wrong? Nothing! Right guys? Guys?
+ QPixmap p;
+ p.load(mUnloadFilename);
+ return p;
}
-}
-
-void Screenshot::selectedWindow()
-{
- WindowPicker* windowPicker = new WindowPicker;
- mPixmapDelay = true;
-
- connect(windowPicker, SIGNAL(pixmap(QPixmap)), this, SLOT(setPixmap(QPixmap)));
+ return mPixmap;
}
-void Screenshot::wholeScreen()
-{
- grabDesktop();
-}
+//
-void Screenshot::grabDesktop()
+void Screenshot::confirm(bool result)
{
- QRect geometry;
-
- if (mOptions.currentMonitor) {
- geometry = qApp->desktop()->screenGeometry(QCursor::pos());
+ if (result) {
+ save();
}
else {
- geometry = qApp->desktop()->geometry();
+ mOptions.result = Screenshot::Cancel;
}
- mPixmap = QPixmap::grabWindow(qApp->desktop()->winId(), geometry.x(), geometry.y(), geometry.width(), geometry.height());
-
- if (mOptions.cursor && !mPixmap.isNull()) {
- QPainter painter(&mPixmap);
- painter.drawPixmap(QCursor::pos(), os::cursor());
- }
+ mPixmap = QPixmap(); // Cleanup just in case.
+ emit finished();
}
-void Screenshot::take()
+void Screenshot::confirmation()
{
- switch (mOptions.mode)
- {
- case Screenshot::WholeScreen:
- wholeScreen();
- break;
-
- case Screenshot::SelectedArea:
- selectedArea();
- break;
-
- case Screenshot::ActiveWindow:
- activeWindow();
- break;
+ emit askConfirmation();
- case Screenshot::SelectedWindow:
- selectedWindow();
- break;
+ if (!mOptions.file) {
+ return;
}
- if (mPixmapDelay)
- return;
+ // Unloading the pixmap to reduce memory usage during previews
+ mUnloadFilename = mOptions.directory.path() + QDir::separator() + QString(".lstemp.%1%2").arg(qrand() * qrand() + QDateTime::currentDateTime().toTime_t()).arg(extension());
+ mUnloaded = mPixmap.save(mUnloadFilename, 0, mOptions.quality);
- if (mPixmap.isNull()) {
- confirm(false);
- }
- else {
- confirmation();
+ if (mUnloaded) {
+ mPixmap = QPixmap();
}
}
-void Screenshot::confirm(bool result)
+void Screenshot::discard()
{
- if (result) {
- save();
- }
- else {
- mOptions.result = Screenshot::Cancel;
- }
-
- mPixmap = QPixmap(); // Cleanup just in case.
- emit finished();
+ confirm(false);
}
-void Screenshot::discard()
+void Screenshot::markUpload()
{
- confirm(false);
+ mOptions.upload = true;
}
void Screenshot::save()
{
QString name = "";
QString fileName = "";
Screenshot::Result result = Screenshot::Fail;
if (mOptions.file && !mOptions.saveAs) {
name = newFileName();
}
else if (mOptions.file && mOptions.saveAs) {
name = QFileDialog::getSaveFileName(0, tr("Save as.."), newFileName(), "*" + extension());
}
if (!mOptions.replace && QFile::exists(name+extension())) {
// Ugly? You should see my wife!
int count = 0;
int cunt = 0;
QString naming = QFileInfo(name).fileName();
foreach(QString file, QFileInfo(name+extension()).dir().entryList(QDir::Files)) {
if (file.contains(naming)) {
file.remove(naming);
file.remove(" (");
file.remove(")");
file.remove(extension());
cunt = file.toInt();
if (cunt > count) {
count = cunt;
}
}
}
name = name + " (" + QString::number(count+1) + ")";
}
fileName = name + extension();
// In the following code I use (Screenshot::Result)1 instead of Screenshot::Success because of some weird issue with the X11 headers. //TODO
if (mOptions.file) {
if (fileName.isEmpty()) {
result = Screenshot::Fail;
}
else if (mUnloaded) {
result = (QFile::rename(mUnloadFilename, fileName)) ? (Screenshot::Result)1: Screenshot::Fail;
}
else if (mPixmap.save(fileName, 0, mOptions.quality)) {
result = (Screenshot::Result)1;
}
else {
result = Screenshot::Fail;
}
os::addToRecentDocuments(fileName);
}
if (mOptions.clipboard) {
QApplication::clipboard()->setPixmap(mPixmap, QClipboard::Clipboard);
if (!mOptions.file) {
result = (Screenshot::Result)1;
}
}
mPixmap = QPixmap();
mOptions.fileName = fileName;
mOptions.result = result;
}
void Screenshot::setPixmap(QPixmap pixmap)
{
mPixmap = pixmap;
if (mPixmap.isNull()) {
emit confirm(false);
}
else {
confirmation();
}
}
-void Screenshot::confirmation()
+void Screenshot::take()
{
- emit askConfirmation();
+ switch (mOptions.mode)
+ {
+ case Screenshot::WholeScreen:
+ wholeScreen();
+ break;
- if (!mOptions.file) {
+ case Screenshot::SelectedArea:
+ selectedArea();
+ break;
+
+ case Screenshot::ActiveWindow:
+ activeWindow();
+ break;
+
+ case Screenshot::SelectedWindow:
+ selectedWindow();
+ break;
+ }
+
+ if (mPixmapDelay)
return;
+
+ if (mPixmap.isNull()) {
+ confirm(false);
+ }
+ else {
+ confirmation();
}
+}
- // Unloading the pixmap to reduce memory usage during previews
- mUnloadFilename = mOptions.directory.path() + QDir::separator() + QString(".lstemp.%1%2").arg(qrand() * qrand() + QDateTime::currentDateTime().toTime_t()).arg(extension());
- mUnloaded = mPixmap.save(mUnloadFilename, 0, mOptions.quality);
+//
- if (mUnloaded) {
+void Screenshot::activeWindow()
+{
+#ifdef Q_WS_WIN
+ HWND fWindow = GetForegroundWindow();
+
+ if (fWindow == NULL)
+ return;
+
+ if (fWindow == GetDesktopWindow()) {
+ wholeScreen();
+ return;
+ }
+
+ mPixmap = os::grabWindow(GetForegroundWindow());
+#endif
+
+#if defined(Q_WS_X11)
+ Window focus;
+ int revert;
+
+ XGetInputFocus(QX11Info::display(), &focus, &revert);
+
+ mPixmap = QPixmap::grabWindow(focus);
+#endif
+}
+
+QString Screenshot::extension() const
+{
+ switch (mOptions.format) {
+ case Screenshot::PNG:
+ return ".png";
+ break;
+ case Screenshot::BMP:
+ return ".bmp";
+ break;
+ case Screenshot::JPEG:
+ default:
+ return ".jpg";
+ break;
+ }
+}
+
+void Screenshot::grabDesktop()
+{
+ QRect geometry;
+
+ if (mOptions.currentMonitor) {
+ geometry = qApp->desktop()->screenGeometry(QCursor::pos());
+ }
+ else {
+ geometry = qApp->desktop()->geometry();
+ }
+
+ mPixmap = QPixmap::grabWindow(qApp->desktop()->winId(), geometry.x(), geometry.y(), geometry.width(), geometry.height());
+
+ if (mOptions.cursor && !mPixmap.isNull()) {
+ QPainter painter(&mPixmap);
+ painter.drawPixmap(QCursor::pos(), os::cursor());
+ }
+}
+
+QString Screenshot::newFileName() const
+{
+ if (!mOptions.directory.exists())
+ mOptions.directory.mkpath(mOptions.directory.path());
+
+ QString naming = Screenshot::getName(mOptions.namingOptions, mOptions.prefix, mOptions.directory);
+
+ QString fileName;
+
+ QString path = QDir::toNativeSeparators(mOptions.directory.path());
+
+ // Cleanup
+ if (path.at(path.size()-1) != QDir::separator() && !path.isEmpty())
+ path.append(QDir::separator());
+
+ fileName.append(path);
+ fileName.append(naming);
+
+ return fileName;
+}
+
+void Screenshot::selectedArea()
+{
+ grabDesktop();
+
+ if (mPixmap.isNull())
+ return;
+
+ AreaDialog selector(this);
+ int result = selector.exec();
+
+ if (result == QDialog::Accepted) {
+ mPixmap = mPixmap.copy(selector.resultRect());
+ }
+ else {
mPixmap = QPixmap();
}
}
+
+void Screenshot::selectedWindow()
+{
+ WindowPicker* windowPicker = new WindowPicker;
+ mPixmapDelay = true;
+
+ connect(windowPicker, SIGNAL(pixmap(QPixmap)), this, SLOT(setPixmap(QPixmap)));
+}
+
+void Screenshot::wholeScreen()
+{
+ grabDesktop();
+}
+
+
+
diff --git a/tools/screenshot.h b/tools/screenshot.h
index 56f2e98..22d539d 100644
--- a/tools/screenshot.h
+++ b/tools/screenshot.h
@@ -1,132 +1,132 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef SCREENSHOT_H
#define SCREENSHOT_H
#include <QObject>
#include <QDir>
#include <QPixmap>
class Screenshot : public QObject
{
Q_OBJECT
public:
enum Format
{
PNG = 0,
JPEG = 1,
BMP = 2,
TIFF = 3
};
enum Naming
{
Numeric = 0,
Date = 1,
Timestamp = 2,
Empty = 3
};
enum Mode
{
WholeScreen = 0,
ActiveWindow = 1,
SelectedArea = 2,
SelectedWindow = 3
};
enum Result
{
Fail = 0,
Success = 1,
Cancel = 2
};
struct NamingOptions
{
Naming naming;
bool flip;
int leadingZeros;
QString dateFormat;
};
struct Options
{
QString fileName;
Result result;
Format format;
QString prefix;
NamingOptions namingOptions;
QDir directory;
int mode;
int quality;
bool currentMonitor;
bool clipboard;
bool file;
bool preview;
bool magnify;
bool cursor;
bool saveAs;
bool animations;
bool replace;
bool upload;
};
Screenshot(QObject *parent, Screenshot::Options options);
~Screenshot();
Screenshot::Options &options();
QPixmap &pixmap();
static QString getName(NamingOptions options, QString prefix, QDir directory);
public slots:
- void take();
void confirm(bool result = true);
+ void confirmation();
void discard();
+ void markUpload();
void save();
void setPixmap(QPixmap pixmap);
- void confirmation();
- void markUpload();
+ void take();
signals:
void askConfirmation();
void finished();
private:
- void activeWindow();
+ void activeWindow();
+ QString extension() const;
+ void grabDesktop();
QString newFileName() const;
- QString extension() const;
- void selectedArea();
- void selectedWindow();
- void wholeScreen();
- void grabDesktop();
+ void selectedArea();
+ void selectedWindow();
+ void wholeScreen();
private:
Screenshot::Options mOptions;
QPixmap mPixmap;
bool mPixmapDelay;
bool mUnloaded;
QString mUnloadFilename;
};
#endif // SCREENSHOT_H
diff --git a/tools/screenshotmanager.cpp b/tools/screenshotmanager.cpp
index 01164bc..0d23873 100644
--- a/tools/screenshotmanager.cpp
+++ b/tools/screenshotmanager.cpp
@@ -1,114 +1,116 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "screenshotmanager.h"
#include "screenshot.h"
-#include <QSettings>
#include <QApplication>
-#include <QFile>
+#include <QDateTime>
#include <QDebug>
#include <QDesktopServices>
-#include <QDateTime>
+#include <QFile>
+#include <QSettings>
ScreenshotManager::ScreenshotManager(QObject *parent = 0) : QObject(parent), mCount(0)
{
if (QFile::exists(qApp->applicationDirPath() + "/config.ini")) {
mSettings = new QSettings(qApp->applicationDirPath() + QDir::separator() + "config.ini", QSettings::IniFormat);
mHistoryPath = qApp->applicationDirPath() + QDir::separator() + "history";
mPortableMode = true;
}
else {
mSettings = new QSettings();
mHistoryPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QDir::separator() + "history";
mPortableMode = false;
}
}
ScreenshotManager::~ScreenshotManager()
{
delete mSettings;
}
+QString& ScreenshotManager::historyPath()
+{
+ return mHistoryPath;
+}
+
+bool ScreenshotManager::portableMode()
+{
+ return mPortableMode;
+}
+
void ScreenshotManager::saveHistory(QString fileName, QString url)
{
if (!mSettings->value("/options/history", true).toBool())
return;
QFile historyFile(mHistoryPath);
QTextStream out(&historyFile);
if (!historyFile.exists())
{
QString path = mHistoryPath;
path.chop(7);
if (!QDir().mkpath(path))
return;
}
if (historyFile.open(QFile::WriteOnly | QFile::Append)) {
out << QString("%1|%2|%3").arg(fileName).arg(url).arg(QDateTime::currentMSecsSinceEpoch()) << "\n";
}
historyFile.close();
}
-QString& ScreenshotManager::historyPath()
+//
+
+void ScreenshotManager::askConfirmation()
{
- return mHistoryPath;
+ Screenshot* s = qobject_cast<Screenshot*>(sender());
+ emit confirm(s);
}
-bool ScreenshotManager::portableMode()
+void ScreenshotManager::cleanup()
{
- return mPortableMode;
+ Screenshot* s = qobject_cast<Screenshot*>(sender());
+ emit windowCleanup(s->options());
+ s->deleteLater();
}
void ScreenshotManager::take(Screenshot::Options &options)
{
Screenshot* newScreenshot = new Screenshot(this, options);
connect(newScreenshot, SIGNAL(askConfirmation()), this, SLOT(askConfirmation()));
connect(newScreenshot, SIGNAL(finished()) , this, SLOT(cleanup()));
newScreenshot->take();
}
-void ScreenshotManager::askConfirmation()
-{
- Screenshot* s = qobject_cast<Screenshot*>(sender());
- emit confirm(s);
-}
-
-void ScreenshotManager::cleanup()
-{
- Screenshot* s = qobject_cast<Screenshot*>(sender());
- emit windowCleanup(s->options());
- s->deleteLater();
-}
-
// Singleton
ScreenshotManager* ScreenshotManager::mInstance = 0;
ScreenshotManager *ScreenshotManager::instance()
{
if (!mInstance)
mInstance = new ScreenshotManager();
return mInstance;
}
diff --git a/tools/screenshotmanager.h b/tools/screenshotmanager.h
index 322f29e..adb9f61 100644
--- a/tools/screenshotmanager.h
+++ b/tools/screenshotmanager.h
@@ -1,71 +1,70 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef SCREENSHOTMANAGER_H
#define SCREENSHOTMANAGER_H
#include <QObject>
#include <QList>
#include "screenshot.h"
#include "qxtcsvmodel.h"
class QSettings;
class ScreenshotManager : public QObject
{
Q_OBJECT
public:
enum State
{
Idle = 0,
Busy = 1,
Disabled = 2
};
public:
ScreenshotManager(QObject *parent);
~ScreenshotManager();
static ScreenshotManager *instance();
- void setCount(const unsigned int c){ mCount = c; }
unsigned int count() const { return mCount; }
- QSettings *settings() const { return mSettings; }
- void saveHistory(QString fileName, QString url = QObject::tr("- not uploaded -"));
QString &historyPath();
bool portableMode();
+ void saveHistory(QString fileName, QString url = QObject::tr("- not uploaded -"));
+ void setCount(const unsigned int c){ mCount = c; }
+ QSettings *settings() const { return mSettings; }
public slots:
- void take(Screenshot::Options &options);
void askConfirmation();
void cleanup();
+ void take(Screenshot::Options &options);
signals:
void confirm(Screenshot* screenshot);
void windowCleanup(Screenshot::Options &options);
private:
static ScreenshotManager* mInstance;
QSettings *mSettings;
QString mHistoryPath;
bool mPortableMode;
- int mCount; // Concurrent screenshot count.
-
+ int mCount; // Concurrent screenshot count.
};
#endif // SCREENSHOTMANAGER_H
diff --git a/tools/uploader.cpp b/tools/uploader.cpp
index c52ce4e..091418e 100644
--- a/tools/uploader.cpp
+++ b/tools/uploader.cpp
@@ -1,151 +1,152 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "uploader.h"
#include "qtimgur.h"
#include "screenshotmanager.h"
#include <QList>
#include <QPair>
+
#include <QDebug>
+Uploader* Uploader::mInstance = 0;
+
+
Uploader::Uploader(QObject *parent) : QObject(parent), mUploading(0)
{
mImgur = new QtImgur("6920a141451d125b3e1357ce0e432409", this);
connect(mImgur, SIGNAL(uploaded(QString, QString)), this, SLOT(uploaded(QString, QString)));
connect(mImgur, SIGNAL(error(QString, QtImgur::Error)), this, SLOT(imgurError(QString, QtImgur::Error)));
connect(mImgur, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(progress(qint64,qint64)));
}
-void Uploader::upload(const QString &fileName)
+Uploader *Uploader::instance()
{
- if (fileName.isEmpty()) {
- return;
- }
-
- // Cancel on duplicate
- for (int i = 0; i < mScreenshots.size(); ++i) {
- if (mScreenshots.at(i).first == fileName) {
- return;
- }
- }
+ if (!mInstance)
+ mInstance = new Uploader();
- mImgur->upload(fileName);
+ return mInstance;
+}
- QPair<QString, QString> screenshot;
- screenshot.first = fileName;
- screenshot.second = tr("Uploading...");
+QString Uploader::lastUrl() const
+{
+ QListIterator< QPair<QString, QString> > i(mScreenshots);
+ i.toBack();
- mScreenshots.append(screenshot);
+ QString url;
- mUploading++;
-}
+ while (i.hasPrevious()) {
+ url = i.previous().second;
-void Uploader::uploaded(const QString &file, const QString &url)
-{
- // Modifying uploaded list, adding url.
- for (int i = 0; i < mScreenshots.size(); ++i) {
- if (mScreenshots.at(i).first == file) {
- mScreenshots[i].second = url;
- break;
+ if (!url.contains(tr("Uploading..."))) {
+ return url;
}
}
- mUploading--;
-
- ScreenshotManager::instance()->saveHistory(file, url);
- emit done(file, url);
+ return url;
}
void Uploader::cancel(const QString &fileName)
{
mImgur->cancel(fileName);
}
-int Uploader::uploading()
-{
- return mUploading;
-}
-
void Uploader::imgurError(const QString &file, const QtImgur::Error e)
{
mUploading--;
// Removing the screenshot.
for (int i = 0; i < mScreenshots.size(); ++i) {
if (mScreenshots.at(i).first == file) {
mScreenshots.removeAt(i);
break;
}
}
if (e == mLastError) {
// Fail silently? Really? FINE
return;
}
QString errorString;
switch (e) {
case QtImgur::ErrorFile:
errorString = tr("Screenshot file not found.");
break;
case QtImgur::ErrorNetwork:
errorString = tr("Could not reach imgur.com");
break;
case QtImgur::ErrorCredits:
errorString = tr("You have exceeded your upload quota.");
break;
case QtImgur::ErrorUpload:
errorString = tr("Upload failed.");
break;
}
mLastError = e;
emit error(errorString);
}
-QString Uploader::lastUrl() const
+void Uploader::upload(const QString &fileName)
{
- QListIterator< QPair<QString, QString> > i(mScreenshots);
- i.toBack();
+ if (fileName.isEmpty()) {
+ return;
+ }
- QString url;
+ // Cancel on duplicate
+ for (int i = 0; i < mScreenshots.size(); ++i) {
+ if (mScreenshots.at(i).first == fileName) {
+ return;
+ }
+ }
- while (i.hasPrevious()) {
- url = i.previous().second;
+ mImgur->upload(fileName);
- if (!url.contains(tr("Uploading..."))) {
- return url;
+ QPair<QString, QString> screenshot;
+ screenshot.first = fileName;
+ screenshot.second = tr("Uploading...");
+
+ mScreenshots.append(screenshot);
+
+ mUploading++;
+}
+
+void Uploader::uploaded(const QString &file, const QString &url)
+{
+ // Modifying uploaded list, adding url.
+ for (int i = 0; i < mScreenshots.size(); ++i) {
+ if (mScreenshots.at(i).first == file) {
+ mScreenshots[i].second = url;
+ break;
}
}
- return url;
-}
+ mUploading--;
-// Singleton
-Uploader* Uploader::mInstance = 0;
+ ScreenshotManager::instance()->saveHistory(file, url);
+ emit done(file, url);
+}
-Uploader *Uploader::instance()
+int Uploader::uploading()
{
- if (!mInstance)
- mInstance = new Uploader();
-
- return mInstance;
+ return mUploading;
}
diff --git a/tools/uploader.h b/tools/uploader.h
index e1ea66a..e9e7fb5 100644
--- a/tools/uploader.h
+++ b/tools/uploader.h
@@ -1,61 +1,60 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef UPLOADER_H
#define UPLOADER_H
#include <QObject>
#include <QList>
#include <QPair>
#include "qtimgur.h"
class Uploader : public QObject
{
Q_OBJECT
public:
Uploader(QObject *parent = 0);
static Uploader* instance();
QString lastUrl() const;
QList< QPair<QString, QString> > &screenshots() { return mScreenshots; }
public slots:
+ void cancel(const QString &fileName);
+ void imgurError(const QString &file, const QtImgur::Error e);
void upload(const QString &fileName);
void uploaded(const QString &fileName, const QString &url);
- void cancel(const QString &fileName);
int uploading();
- void imgurError(const QString &file, const QtImgur::Error e);
signals:
void done(QString, QString);
void error(QString);
void progress(qint64, qint64);
private:
static Uploader* mInstance;
// Filename, url
QList< QPair<QString, QString> > mScreenshots;
QtImgur *mImgur;
QtImgur::Error mLastError;
int mUploading;
-
};
#endif // UPLOADER_H
diff --git a/tools/windowpicker.cpp b/tools/windowpicker.cpp
index 1811d50..92fa725 100644
--- a/tools/windowpicker.cpp
+++ b/tools/windowpicker.cpp
@@ -1,302 +1,304 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
-#include <QWidget>
#include <QDesktopWidget>
-#include <QMouseEvent>
-#include <QVBoxLayout>
#include <QLabel>
-#include <QDebug>
-#include <QRubberBand>
+#include <QMouseEvent>
#include <QPushButton>
#include <QRubberBand>
+#include <QRubberBand>
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include <QDebug>
#include "windowpicker.h"
#include "os.h"
#if defined(Q_OS_WIN)
#include <windows.h>
#elif defined(Q_WS_X11)
#include <QX11Info>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#endif
WindowPicker::WindowPicker() : QWidget(0), mCrosshair(":/icons/picker"), mWindowLabel(0), mTaken(false)
{
#if defined(Q_OS_WIN)
setWindowFlags(Qt::SplashScreen | Qt::WindowStaysOnTopHint);
#elif defined(Q_WS_X11)
setWindowFlags(Qt::WindowStaysOnTopHint);
#endif
setWindowTitle(tr("Lightscreen Window Picker"));
setStyleSheet("QWidget { color: #000; } #frame { padding: 7px 10px; border: 1px solid #898c95; background-color: qlineargradient(spread:pad, x1:1, y1:1, x2:0.988636, y2:0.608, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(255, 255, 255, 255)); border-radius: 8px; }");
QLabel *helpLabel = new QLabel(tr("Grab the window picker by clicking and holding down the mouse button, then drag it to the window of your choice and release it to capture."), this);
helpLabel->setMinimumWidth(400);
helpLabel->setMaximumWidth(400);
helpLabel->setWordWrap(true);
mWindowIcon = new QLabel(this);
mWindowIcon->setMinimumSize(22, 22);
mWindowIcon->setMaximumSize(22, 22);
mWindowIcon->setScaledContents(true);
mWindowLabel = new QLabel(tr(" - Start dragging to select windows"), this);
mWindowLabel->setStyleSheet("font-weight: bold");
mCrosshairLabel = new QLabel(this);
mCrosshairLabel->setAlignment(Qt::AlignHCenter);
mCrosshairLabel->setPixmap(mCrosshair);
QPushButton *closeButton = new QPushButton(tr("Close"));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
QHBoxLayout *windowLayout = new QHBoxLayout;
windowLayout->addWidget(mWindowIcon);
windowLayout->addWidget(mWindowLabel);
windowLayout->setMargin(0);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(0);
buttonLayout->addWidget(closeButton);
buttonLayout->setMargin(0);
QHBoxLayout *crosshairLayout = new QHBoxLayout;
crosshairLayout->addStretch(0);
crosshairLayout->addWidget(mCrosshairLabel);
crosshairLayout->addStretch(0);
crosshairLayout->setMargin(0);
QVBoxLayout *fl = new QVBoxLayout;
fl->addWidget(helpLabel);
fl->addLayout(windowLayout);
fl->addLayout(crosshairLayout);
fl->addLayout(buttonLayout);
fl->setMargin(0);
QFrame *frame = new QFrame(this);
frame->setObjectName("frame");
frame->setLayout(fl);
QVBoxLayout *l = new QVBoxLayout;
l->setMargin(0);
l->addWidget(frame);
setLayout(l);
resize(sizeHint());
move(QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(QCursor::pos())).center()-QPoint(width()/2, height()/2));
show();
}
WindowPicker::~WindowPicker() {
qApp->restoreOverrideCursor();
}
void WindowPicker::cancel() {
mWindowIcon->setPixmap(QPixmap());
mCrosshairLabel->setPixmap(mCrosshair);
qApp->restoreOverrideCursor();
}
-void WindowPicker::mouseReleaseEvent(QMouseEvent *event)
+void WindowPicker::closeEvent(QCloseEvent*)
{
- if (event->button() == Qt::LeftButton) {
-#if defined(Q_OS_WIN)
- POINT mousePos;
- mousePos.x = event->globalX();
- mousePos.y = event->globalY();
-
- HWND window = GetAncestor(WindowFromPoint(mousePos), GA_ROOT);
-#elif defined(Q_WS_X11)
- Window window = os::windowUnderCursor(false);
-#endif
-
- if (window == winId()) {
- cancel();
- return;
- }
-
- mTaken = true;
-
- setWindowFlags(windowFlags() ^ Qt::WindowStaysOnTopHint);
- close();
-
-#ifdef Q_WS_X11
- emit pixmap(QPixmap::grabWindow(mCurrentWindow));
-#else
- emit pixmap(os::grabWindow(window));
-#endif
-
- return;
- }
-
- close();
-}
+ if (!mTaken)
+ emit pixmap(QPixmap());
-void WindowPicker::mousePressEvent(QMouseEvent *event)
-{
- qApp->setOverrideCursor(QCursor(mCrosshair));
- mCrosshairLabel->setMinimumWidth(mCrosshairLabel->width());
- mCrosshairLabel->setMinimumHeight(mCrosshairLabel->height());
- mCrosshairLabel->setPixmap(QPixmap());
- QWidget::mousePressEvent(event);
+ qApp->restoreOverrideCursor();
+ deleteLater();
}
void WindowPicker::mouseMoveEvent(QMouseEvent *event)
{
QString windowName;
#if defined(Q_OS_WIN)
POINT mousePos;
mousePos.x = event->globalX();
mousePos.y = event->globalY();
HWND cWindow = GetAncestor(WindowFromPoint(mousePos), GA_ROOT);
mCurrentWindow = cWindow;
if (mCurrentWindow == winId()) {
mWindowIcon->setPixmap(QPixmap());
mWindowLabel->setText("");
return;
}
// Text
WCHAR str[60];
HICON icon;
::GetWindowText(mCurrentWindow, str, 60);
windowName = QString::fromWCharArray(str);
///
// Retrieving the application icon
icon = (HICON)::GetClassLong(mCurrentWindow, GCL_HICON);
if (icon != NULL) {
mWindowIcon->setPixmap(QPixmap::fromWinHICON(icon));
}
else {
mWindowIcon->setPixmap(QPixmap());
}
#elif defined(Q_WS_X11)
Window cWindow = os::windowUnderCursor(false);
if (cWindow == mCurrentWindow) {
return;
}
mCurrentWindow = cWindow;
if (mCurrentWindow == winId()) {
mWindowIcon->setPixmap(QPixmap());
mWindowLabel->setText("");
return;
}
// Getting the window name property.
XTextProperty tp;
char **text;
int count;
if (XGetTextProperty(QX11Info::display(), cWindow, &tp, XA_WM_NAME) != 0 && tp.value != NULL ) {
if (tp.encoding == XA_STRING) {
windowName = QString::fromLocal8Bit((const char*) tp.value);
}
else if (XmbTextPropertyToTextList( QX11Info::display(), &tp, &text, &count) == Success &&
text != NULL && count > 0) {
windowName = QString::fromLocal8Bit(text[0]);
XFreeStringList(text);
}
XFree(tp.value);
}
// Retrieving the _NET_WM_ICON property.
Atom type_ret = None;
unsigned char *data = 0;
int format = 0;
unsigned long n = 0;
unsigned long extra = 0;
int width = 0;
int height = 0;
Atom _net_wm_icon = XInternAtom(QX11Info::display(), "_NET_WM_ICON", False);
if (XGetWindowProperty(QX11Info::display(), cWindow, _net_wm_icon, 0, 1, False,
XA_CARDINAL, &type_ret, &format, &n, &extra, (unsigned char **)&data) == Success && data)
{
width = data[0];
XFree(data);
}
if (XGetWindowProperty(QX11Info::display(), cWindow, _net_wm_icon, 1, 1, False,
XA_CARDINAL, &type_ret, &format, &n, &extra, (unsigned char **)&data) == Success && data)
{
height = data[0];
XFree(data);
}
if (XGetWindowProperty(QX11Info::display(), cWindow, _net_wm_icon, 2, width*height, False,
XA_CARDINAL, &type_ret, &format, &n, &extra, (unsigned char **)&data) == Success && data)
{
QImage img(data, width, height, QImage::Format_ARGB32);
mWindowIcon->setPixmap(QPixmap::fromImage(img));
XFree(data);
}
else {
mWindowIcon->setPixmap(QPixmap());
}
#endif
QString windowText;
if (!mWindowIcon->pixmap()) {
windowText = QString(" - %1").arg(windowName);
}
else {
windowText = windowName;
}
if (windowText == " - ") {
mWindowLabel->setText("");
return;
}
if (windowText.length() == 62) {
mWindowLabel->setText(windowText + "...");
}
else {
mWindowLabel->setText(windowText);
}
}
-void WindowPicker::closeEvent(QCloseEvent*)
+void WindowPicker::mousePressEvent(QMouseEvent *event)
{
- if (!mTaken)
- emit pixmap(QPixmap());
+ qApp->setOverrideCursor(QCursor(mCrosshair));
+ mCrosshairLabel->setMinimumWidth(mCrosshairLabel->width());
+ mCrosshairLabel->setMinimumHeight(mCrosshairLabel->height());
+ mCrosshairLabel->setPixmap(QPixmap());
+ QWidget::mousePressEvent(event);
+}
- qApp->restoreOverrideCursor();
- deleteLater();
+void WindowPicker::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+#if defined(Q_OS_WIN)
+ POINT mousePos;
+ mousePos.x = event->globalX();
+ mousePos.y = event->globalY();
+
+ HWND window = GetAncestor(WindowFromPoint(mousePos), GA_ROOT);
+#elif defined(Q_WS_X11)
+ Window window = os::windowUnderCursor(false);
+#endif
+
+ if (window == winId()) {
+ cancel();
+ return;
+ }
+
+ mTaken = true;
+
+ setWindowFlags(windowFlags() ^ Qt::WindowStaysOnTopHint);
+ close();
+
+#ifdef Q_WS_X11
+ emit pixmap(QPixmap::grabWindow(mCurrentWindow));
+#else
+ emit pixmap(os::grabWindow(window));
+#endif
+
+ return;
+ }
+
+ close();
}
+
diff --git a/tools/windowpicker.h b/tools/windowpicker.h
index a2223f5..b1cf7aa 100644
--- a/tools/windowpicker.h
+++ b/tools/windowpicker.h
@@ -1,56 +1,56 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef WINDOWPICKER_H
#define WINDOWPICKER_H
#include <QWidget>
class QLabel;
class QRect;
class QRubberBand;
class WindowPicker : public QWidget
{
Q_OBJECT
public:
- WindowPicker();
- ~WindowPicker();
+ WindowPicker();
+ ~WindowPicker();
signals:
- void pixmap(QPixmap pixmap);
+ void pixmap(QPixmap pixmap);
protected:
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void closeEvent(QCloseEvent*);
+ void closeEvent(QCloseEvent*);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
private:
- void cancel();
+ void cancel();
private:
- QPixmap mCrosshair;
- QLabel *mWindowLabel;
- QLabel *mWindowIcon;
- QLabel *mCrosshairLabel;
- WId mCurrentWindow;
- bool mTaken;
+ QPixmap mCrosshair;
+ QLabel *mCrosshairLabel;
+ QLabel *mWindowIcon;
+ QLabel *mWindowLabel;
+ WId mCurrentWindow;
+ bool mTaken;
};
#endif // WINDOWPICKER_H
diff --git a/updater/updater.cpp b/updater/updater.cpp
index 33c32a5..56c7a94 100644
--- a/updater/updater.cpp
+++ b/updater/updater.cpp
@@ -1,77 +1,82 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
+#include <QApplication>
#include <QDate>
#include <QHttp>
-#include <QApplication>
+
#include <QDebug>
#include "updater.h"
#include "../dialogs/updaterdialog.cpp"
+Updater* Updater::mInstance = 0;
+
Updater::Updater(QObject *parent) :
QObject(parent)
{
connect(&mHttp, SIGNAL(done(bool)), this, SLOT(httpDone(bool)));
}
+Updater *Updater::instance()
+{
+ if (!mInstance)
+ mInstance = new Updater();
+
+ return mInstance;
+}
+
+//
+
void Updater::check()
{
if (mHttp.hasPendingRequests())
return;
QString platform = "unknown";
#ifdef Q_WS_WIN
platform = QString("Windows_%1").arg(QSysInfo::windowsVersion());
#else
platform = "Linux";
#endif
mHttp.setHost("lightscreen.sourceforge.net");
mHttp.get("/version?from=" + qApp->applicationVersion() + "&platform=" + platform);
}
void Updater::checkWithFeedback()
{
UpdaterDialog updaterDialog;
connect(this, SIGNAL(done(bool)), &updaterDialog, SLOT(updateDone(bool)));
check();
updaterDialog.exec();
}
+//
+
void Updater::httpDone(bool error)
{
Q_UNUSED(error)
QByteArray data = mHttp.readAll();
double version = QString(data).toDouble();
emit done((version > qApp->applicationVersion().toDouble()));
}
-
-Updater* Updater::mInstance = 0;
-
-Updater *Updater::instance()
-{
- if (!mInstance)
- mInstance = new Updater();
-
- return mInstance;
-}
diff --git a/updater/updater.h b/updater/updater.h
index 772d337..2b99d79 100644
--- a/updater/updater.h
+++ b/updater/updater.h
@@ -1,49 +1,49 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef UPDATER_H_
#define UPDATER_H_
#include <QObject>
#include <QHttp>
class Updater : public QObject
{
Q_OBJECT
public:
Updater(QObject *parent = 0);
static Updater *instance();
signals:
void done(bool result);
public slots:
- void checkWithFeedback();
void check();
+ void checkWithFeedback();
private slots:
void httpDone(bool error);
private:
QHttp mHttp;
static Updater* mInstance;
};
#endif /*UPDATER_H_*/
diff --git a/widgets/hotkeywidget.cpp b/widgets/hotkeywidget.cpp
index 24dc3af..4b477a3 100644
--- a/widgets/hotkeywidget.cpp
+++ b/widgets/hotkeywidget.cpp
@@ -1,160 +1,161 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
#include <QFocusEvent>
#include <QKeyEvent>
#include <QKeySequence>
-#include <QTimer>
#include <QStyle>
+#include <QTimer>
#include <QDebug>
#include "hotkeywidget.h"
HotkeyWidget::HotkeyWidget(QWidget *parent) :
QPushButton(parent), mHotkey(QKeySequence()), mShowingError(false), mKeyboardFocus(false)
{
mDefaultStyleSheet = "text-align: left; padding: 3px 6px;";
setStyleSheet(mDefaultStyleSheet);
setText(tr("Click to select hotkey..."));
setObjectName("HotkeyWidget");
if (qApp->style()->objectName() == "oxygen") {
setMinimumWidth(130);
}
else {
setMinimumWidth(110);
}
}
void HotkeyWidget::setHotkey(QKeySequence hotkey)
{
mHotkey = hotkey;
setHotkeyText();
}
QKeySequence &HotkeyWidget::hotkey()
{
return mHotkey;
}
+void HotkeyWidget::showError()
+{
+ if (mShowingError)
+ return;
+
+ mShowingError = true;
+
+ setStyleSheet(mDefaultStyleSheet + "color: #d90000;");
+ QTimer::singleShot(1000, this, SLOT(hideError()));
+}
+
void HotkeyWidget::setHotkeyText()
{
QString hotkeyText = mHotkey.toString(QKeySequence::NativeText);
setText(hotkeyText);
parentWidget()->setFocus();
}
bool HotkeyWidget::event(QEvent *event)
{
if (event->type() == QEvent::LanguageChange) {
setHotkeyText();
}
else if (event->type() == QEvent::FocusIn) {
QFocusEvent* focusEvent = static_cast<QFocusEvent*>(event);
if (focusEvent->reason() != Qt::TabFocusReason) {
setText(tr("Type your hotkey"));
mKeyboardFocus = false;
grabKeyboard();
}
else {
mKeyboardFocus = true;
}
}
else if (event->type() == QEvent::FocusOut) {
if (text() == tr("Invalid hotkey")) {
emit invalidHotkeyError();
showError();
}
releaseKeyboard();
setHotkeyText(); // Reset the text
}
return QPushButton::event(event);
}
void HotkeyWidget::keyPressEvent(QKeyEvent *event)
{
if (mKeyboardFocus)
return;
if (isModifier(event->key()))
return;
if (!isValid(event->key())) {
setText(tr("Invalid hotkey"));
parentWidget()->setFocus();
return;
}
mHotkey = QKeySequence(event->key() + (event->modifiers() & ~Qt::KeypadModifier));
setHotkeyText();
}
-void HotkeyWidget::showError()
-{
- if (mShowingError)
- return;
-
- mShowingError = true;
-
- setStyleSheet(mDefaultStyleSheet + "color: #d90000;");
- QTimer::singleShot(1000, this, SLOT(hideError()));
-}
-
void HotkeyWidget::hideError()
{
setStyleSheet(mDefaultStyleSheet);
mShowingError = false;
}
bool HotkeyWidget::isValid(int key) const
{
switch (key)
{
case 0:
case Qt::Key_Escape:
case Qt::Key_unknown:
return false;
}
return !isModifier(key);
}
bool HotkeyWidget::isModifier(int key) const
{
switch (key)
{
- case Qt::Key_Shift:
- case Qt::Key_Control:
- case Qt::Key_Meta:
- case Qt::Key_Alt:
- case Qt::Key_AltGr:
- case Qt::Key_Super_L:
- case Qt::Key_Super_R:
- case Qt::Key_Menu:
- return true;
+ case Qt::Key_Shift:
+ case Qt::Key_Control:
+ case Qt::Key_Meta:
+ case Qt::Key_Alt:
+ case Qt::Key_AltGr:
+ case Qt::Key_Super_L:
+ case Qt::Key_Super_R:
+ case Qt::Key_Menu:
+ return true;
}
+
return false;
}
diff --git a/widgets/hotkeywidget.h b/widgets/hotkeywidget.h
index bf73672..feec2f8 100644
--- a/widgets/hotkeywidget.h
+++ b/widgets/hotkeywidget.h
@@ -1,60 +1,59 @@
/*
* Copyright (C) 2011 Christian Kaiser
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef HOTKEYWIDGET_H
#define HOTKEYWIDGET_H
#include <QPushButton>
class HotkeyWidget : public QPushButton
{
Q_OBJECT
public:
HotkeyWidget(QWidget *parent = 0);
void setHotkey(QKeySequence hotkey);
QKeySequence &hotkey();
signals:
void invalidHotkeyError();
private:
void setHotkeyText();
void showError();
private slots:
void hideError();
protected:
// Event overrides:
bool event(QEvent* event);
void keyPressEvent(QKeyEvent* event);
private:
QKeySequence mHotkey;
bool mShowingError;
bool mKeyboardFocus;
QString mDefaultStyleSheet;
bool isValid(int key) const;
bool isModifier(int key) const;
-
};
#endif // HOTKEYWIDGET_H

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 17, 9:20 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70409
Default Alt Text
(236 KB)

Event Timeline