Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
112 KB
Referenced Files
None
Subscribers
None
diff --git a/dialogs/areadialog.h b/dialogs/areadialog.h
index b3f355d..9b58bc3 100644
--- a/dialogs/areadialog.h
+++ b/dialogs/areadialog.h
@@ -1,99 +1,99 @@
/*
* Copyright (C) 2016 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>
#include <QRegion>
#include <QRect>
#include <QPoint>
class QPaintEvent;
class QResizeEvent;
class QMouseEvent;
class Screenshot;
class AreaDialog : public QDialog
{
Q_OBJECT
public:
- AreaDialog(Screenshot* screenshot);
+ AreaDialog(Screenshot *screenshot);
QRect &resultRect();
protected slots:
void animationTick(int frame);
void cancel();
void displayHelp();
void grabRect();
signals:
- void regionGrabbed( const QPixmap & );
+ void regionGrabbed(const QPixmap &);
protected:
- void keyPressEvent( QKeyEvent* e );
- void mouseDoubleClickEvent( QMouseEvent* );
- void mouseMoveEvent( QMouseEvent* e );
- void mousePressEvent( QMouseEvent* e );
- void mouseReleaseEvent( QMouseEvent* e );
- void paintEvent( QPaintEvent* e );
- void resizeEvent( QResizeEvent* e );
- void showEvent( QShowEvent* e );
+ void keyPressEvent(QKeyEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *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;
+ QPoint limitPointToRect(const QPoint &p, const QRect &r) const;
bool mAutoclose;
QPoint mDragStartPoint;
bool mGrabbing;
const int mHandleSize;
QTimer mIdleTimer;
bool mMouseDown;
bool mMouseMagnifier;
QRect *mMouseOverHandle;
QPoint mMousePos;
bool mNewSelection;
int mOverlayAlpha;
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 a8099a0..87dae6c 100644
--- a/dialogs/historydialog.cpp
+++ b/dialogs/historydialog.cpp
@@ -1,269 +1,269 @@
#include "historydialog.h"
#include "ui_historydialog.h"
#include "../tools/os.h"
#include "../tools/uploader/uploader.h"
#include "../tools/screenshotmanager.h"
#include <QClipboard>
#include <QDesktopServices>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFileSystemWatcher>
#include <QMenu>
#include <QMessageBox>
#include <QSettings>
#include <QSortFilterProxyModel>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlTableModel>
#include <QUrl>
HistoryDialog::HistoryDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::HistoryDialog)
{
ui->setupUi(this);
ui->filterEdit->setText(tr("Filter.."));
ui->filterEdit->installEventFilter(this);
if (QSqlDatabase::database().isOpen()) {
mModel = new QSqlTableModel(this);
mModel->setTable("history");
mModel->setHeaderData(0, Qt::Horizontal, tr("Screenshot"));
mModel->setHeaderData(1, Qt::Horizontal, tr("URL"));
mModel->select();
mFilterModel = new QSortFilterProxyModel(mModel);
mFilterModel->setSourceModel(mModel);
mFilterModel->setDynamicSortFilter(true);
mFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
mFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
mFilterModel->setFilterKeyColumn(-1);
while (mModel->canFetchMore()) {
mModel->fetchMore();
}
ui->tableView->setWordWrap(false);
ui->tableView->setModel(mFilterModel);
ui->tableView->hideColumn(2); // No delete hash.
ui->tableView->hideColumn(3); // No timestamp.
ui->tableView->horizontalHeader()->setSectionsClickable(false);
ui->tableView->horizontalHeader()->setSectionsMovable(false);
ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
ui->tableView->verticalHeader()->hide();
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->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)));
} else {
ui->tableView->setEnabled(false);
ui->clearButton->setEnabled(false);
}
if (Uploader::instance()->progress() > 0) {
ui->uploadProgressBar->setValue(Uploader::instance()->progress());
} else {
ui->uploadProgressWidget->setVisible(false);
}
ui->cancelUploadButton->setIcon(os::icon("no"));
connect(Uploader::instance(), SIGNAL(progress(int)), this, SLOT(uploadProgress(int)));
connect(Uploader::instance(), SIGNAL(done(QString, QString, QString)), this, SLOT(refresh()));
connect(ui->uploadButton , SIGNAL(clicked()), this , SLOT(upload()));
connect(ui->cancelUploadButton, SIGNAL(clicked()), Uploader::instance() , SLOT(cancel()));
connect(ui->cancelUploadButton, SIGNAL(clicked()), ui->uploadProgressWidget, SLOT(hide()));
connect(ui->clearButton , SIGNAL(clicked()), this , SLOT(clear()));
}
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;
}
ScreenshotManager::instance()->clearHistory();
close();
}
-void HistoryDialog::contextMenu(QPoint point)
+void HistoryDialog::contextMenu(const 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 deleteAction(tr("Delete from imgur.com"), &contextMenu);
QAction locationAction(tr("Open Location"), &contextMenu);
QAction removeAction(tr("Remove history entry"), &contextMenu);
if (mContextIndex.data().toString().isEmpty()) {
copyAction.setEnabled(false);
deleteAction.setEnabled(false);
}
if (mContextIndex.column() == 0) {
connect(&locationAction, SIGNAL(triggered()), this, SLOT(location()));
contextMenu.addAction(&locationAction);
} else {
connect(&deleteAction, SIGNAL(triggered()), this, SLOT(deleteImage()));
contextMenu.addAction(&deleteAction);
}
connect(&removeAction, SIGNAL(triggered()), this, SLOT(removeHistoryEntry()));
contextMenu.addAction(&removeAction);
contextMenu.exec(QCursor::pos());
}
void HistoryDialog::copy()
{
qApp->clipboard()->setText(mContextIndex.data().toString());
}
void HistoryDialog::deleteImage()
{
QDesktopServices::openUrl(mContextIndex.sibling(mContextIndex.row(), 2).data().toString());
}
void HistoryDialog::location()
{
QDesktopServices::openUrl("file:///" + QFileInfo(mContextIndex.data().toString()).absolutePath());
}
void HistoryDialog::removeHistoryEntry()
{
if (mContextIndex.column() == 0) {
// File got right clicked:
ScreenshotManager::instance()->removeHistory(mContextIndex.data().toString(), mContextIndex.sibling(mContextIndex.row(), 3).data().toLongLong());
} else {
// Screenshot URL got right clicked:
ScreenshotManager::instance()->removeHistory(mContextIndex.sibling(mContextIndex.row(), 0).data().toString(), mContextIndex.sibling(mContextIndex.row(), 3).data().toLongLong());
}
refresh();
}
void HistoryDialog::refresh()
{
mModel->select();
}
void HistoryDialog::open(const QModelIndex &index)
{
if (index.column() == 0) {
QDesktopServices::openUrl(QUrl("file:///" + index.data().toString()));
} else {
QDesktopServices::openUrl(index.data().toUrl());
}
}
void HistoryDialog::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
Q_UNUSED(deselected);
if (selected.indexes().count() == 0) {
return;
}
QModelIndex index = selected.indexes().at(0);
QString screenshot;
if (index.column() == 0) {
screenshot = index.data().toString();
} else {
screenshot = ui->tableView->model()->index(index.row(), 0).data().toString();
}
mSelectedScreenshot = screenshot;
ui->uploadButton->setEnabled(QFile::exists(screenshot));
}
void HistoryDialog::upload()
{
Uploader::instance()->upload(mSelectedScreenshot);
ui->uploadProgressWidget->setVisible(true);
}
void HistoryDialog::uploadProgress(int progress)
{
ui->uploadProgressWidget->setVisible(true);
ui->uploadProgressBar->setValue(progress);
}
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(3, Qt::DescendingOrder);
}
} else if (event->type() == QEvent::FocusOut) {
if (ui->filterEdit->text().isEmpty()) {
ui->filterEdit->setStyleSheet("color: palette(mid);");
ui->filterEdit->setText(tr("Filter.."));
mFilterModel->sort(3, 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(3, Qt::DescendingOrder);
} else {
mFilterModel->setFilterWildcard("");
mFilterModel->sort(3, Qt::DescendingOrder);
}
}
}
return QDialog::eventFilter(object, event);
}
bool HistoryDialog::event(QEvent *event)
{
if (event->type() == QEvent::Show) {
restoreGeometry(ScreenshotManager::instance()->settings()->value("geometry/historyDialog").toByteArray());
} else if (event->type() == QEvent::Close) {
ScreenshotManager::instance()->settings()->setValue("geometry/historyDialog", saveGeometry());
}
return QDialog::event(event);
}
diff --git a/dialogs/historydialog.h b/dialogs/historydialog.h
index 2321d69..01ffe19 100644
--- a/dialogs/historydialog.h
+++ b/dialogs/historydialog.h
@@ -1,46 +1,46 @@
#ifndef UPLOADDIALOG_H
#define UPLOADDIALOG_H
#include <QDialog>
#include <QItemSelection>
namespace Ui {
- class HistoryDialog;
+class HistoryDialog;
}
class QSqlTableModel;
class QSortFilterProxyModel;
class HistoryDialog : public QDialog
{
Q_OBJECT
public:
- explicit HistoryDialog(QWidget *parent = 0);
- ~HistoryDialog();
+ explicit HistoryDialog(QWidget *parent = 0);
+ ~HistoryDialog();
private slots:
- void clear();
- void contextMenu(QPoint point);
- void copy();
- void deleteImage();
- void location();
- void removeHistoryEntry();
- void refresh();
- void open(const QModelIndex &index);
- void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
- void upload();
- void uploadProgress(int progress);
+ void clear();
+ void contextMenu(const QPoint &point);
+ void copy();
+ void deleteImage();
+ void location();
+ void removeHistoryEntry();
+ void refresh();
+ void open(const QModelIndex &index);
+ void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void upload();
+ void uploadProgress(int progress);
protected:
- bool eventFilter(QObject *object, QEvent *event);
- bool event(QEvent *event);
+ bool eventFilter(QObject *object, QEvent *event);
+ bool event(QEvent *event);
private:
- Ui::HistoryDialog *ui;
- QSqlTableModel *mModel;
- QSortFilterProxyModel *mFilterModel;
- QString mSelectedScreenshot;
- QModelIndex mContextIndex;
+ Ui::HistoryDialog *ui;
+ QSqlTableModel *mModel;
+ QSortFilterProxyModel *mFilterModel;
+ QString mSelectedScreenshot;
+ QModelIndex mContextIndex;
};
#endif // UPLOADDIALOG_H
diff --git a/dialogs/namingdialog.cpp b/dialogs/namingdialog.cpp
index ebe61c8..0baa369 100644
--- a/dialogs/namingdialog.cpp
+++ b/dialogs/namingdialog.cpp
@@ -1,90 +1,90 @@
/*
* Copyright (C) 2016 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 <QDesktopServices>
#include <QKeyEvent>
#include <QSettings>
#include <QUrl>
NamingDialog::NamingDialog(Screenshot::Naming naming, QWidget *parent) :
QDialog(parent)
{
ui.setupUi(this);
setModal(true);
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
ui.dateFormatComboBox->installEventFilter(this);
// 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)
+void NamingDialog::openUrl(const 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());
}
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 501f04b..b19a9f8 100644
--- a/dialogs/namingdialog.h
+++ b/dialogs/namingdialog.h
@@ -1,45 +1,45 @@
/*
* Copyright (C) 2016 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);
private slots:
- void openUrl(QString url);
- void saveSettings();
+ void openUrl(const QString &url);
+ void saveSettings();
protected:
- bool eventFilter(QObject *object, QEvent *event);
+ bool eventFilter(QObject *object, QEvent *event);
private:
Ui::NamingDialog ui;
};
#endif // NAMINGDIALOG_H
diff --git a/dialogs/optionsdialog.h b/dialogs/optionsdialog.h
index 9d30ac7..2c5c39e 100644
--- a/dialogs/optionsdialog.h
+++ b/dialogs/optionsdialog.h
@@ -1,73 +1,73 @@
/*
* Copyright (C) 2016 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 <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 exportSettings();
- void imgurAlbumList();
- void imgurAuthorize();
- void imgurRequestAlbumList();
- void imgurToken();
- void importSettings();
- void loadSettings();
- void openUrl(QString url);
- void restoreDefaults();
- void saveSettings();
- void updatePreview();
- void viewHistory();
+ void accepted();
+ void checkUpdatesNow();
+ void exportSettings();
+ void imgurAlbumList();
+ void imgurAuthorize();
+ void imgurRequestAlbumList();
+ void imgurToken();
+ void importSettings();
+ void loadSettings();
+ void openUrl(QString url);
+ void restoreDefaults();
+ void saveSettings();
+ void updatePreview();
+ void viewHistory();
protected:
- bool event(QEvent *event);
+ bool event(QEvent *event);
#ifdef Q_OS_WIN
- bool nativeEvent(const QByteArray &eventType, void *message, long *result);
+ bool nativeEvent(const QByteArray &eventType, void *message, long *result);
#endif
private slots:
- void browse();
- void dialogButtonClicked(QAbstractButton *button);
- void flipToggled(bool checked);
- void init();
- void namingOptions();
+ void browse();
+ void dialogButtonClicked(QAbstractButton *button);
+ void flipToggled(bool checked);
+ void init();
+ void namingOptions();
private:
- bool hotkeyCollision();
- QSettings *settings() const;
+ bool hotkeyCollision();
+ QSettings *settings() const;
private:
Ui::OptionsDialog ui;
};
#endif // OPTIONSDIALOG_H
diff --git a/dialogs/previewdialog.h b/dialogs/previewdialog.h
index c77994d..a9765f4 100644
--- a/dialogs/previewdialog.h
+++ b/dialogs/previewdialog.h
@@ -1,69 +1,69 @@
/*
* Copyright (C) 2016 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);
+ PreviewDialog(QWidget *parent);
- void add(Screenshot* screenshot);
- int count() const;
+ void add(Screenshot *screenshot);
+ int count() const;
public slots:
- void setWidth(int w) { resize(w, height()); }
- void setHeight(int h) { resize(width(), h); }
+ void setWidth(int w) { resize(w, height()); }
+ void setHeight(int h) { resize(width(), h); }
signals:
- void acceptAll();
- void rejectAll();
- void uploadAll();
+ void acceptAll();
+ void rejectAll();
+ void uploadAll();
private slots:
- void closePreview();
- void enlargePreview();
- void indexChanged(int i);
- void next();
- void previous();
- void relocate();
+ void closePreview();
+ void enlargePreview();
+ void indexChanged(int i);
+ void next();
+ void previous();
+ void relocate();
protected:
- bool event(QEvent *event);
- void timerEvent(QTimerEvent *event);
+ bool event(QEvent *event);
+ void timerEvent(QTimerEvent *event);
private:
- int mAutoclose;
- int mAutocloseAction;
- 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;
+ int mAutoclose;
+ int mAutocloseAction;
+ 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/updaterdialog.h b/dialogs/updaterdialog.h
index b40da44..6703d89 100644
--- a/dialogs/updaterdialog.h
+++ b/dialogs/updaterdialog.h
@@ -1,39 +1,39 @@
/*
* Copyright (C) 2016 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 UPDATERDIALOG_H
#define UPDATERDIALOG_H
#include <QProgressDialog>
class UpdaterDialog : public QProgressDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- UpdaterDialog(QWidget* parent = 0);
+ UpdaterDialog(QWidget *parent = 0);
public slots:
- void updateDone(bool result);
+ void updateDone(bool result);
private slots:
- void link(QString url);
+ void link(QString url);
};
#endif // UPDATERDIALOG_H
diff --git a/lightscreenwindow.cpp b/lightscreenwindow.cpp
index ac0628d..3040ed6 100644
--- a/lightscreenwindow.cpp
+++ b/lightscreenwindow.cpp
@@ -1,1033 +1,1033 @@
/*
* Copyright (C) 2016 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 <QDesktopWidget>
#include <QFileInfo>
#include <QKeyEvent>
#include <QMainWindow>
#include <QMenu>
#include <QMessageBox>
#include <QPointer>
#include <QProcess>
#include <QSettings>
#include <QSystemTrayIcon>
#include <QTimer>
#include <QToolTip>
#include <QUrl>
#include <QSound>
#include <QKeyEvent>
#ifdef Q_OS_WIN
#include <windows.h>
#include <QtWinExtras>
#endif
/*
* Lightscreen includes
*/
#include "lightscreenwindow.h"
#include "dialogs/optionsdialog.h"
#include "dialogs/previewdialog.h"
#include "dialogs/historydialog.h"
#include "tools/os.h"
#include "tools/screenshot.h"
#include "tools/screenshotmanager.h"
#include "tools/UGlobalHotkey/uglobalhotkeys.h"
#include "tools/uploader/uploader.h"
#include "updater/updater.h"
LightscreenWindow::LightscreenWindow(QWidget *parent) :
QMainWindow(parent),
mDoCache(false),
mHideTrigger(false),
mReviveMain(false),
mWasVisible(true),
mLastMessage(0),
mLastMode(-1),
mLastScreenshot(),
mHasTaskbarButton(false)
{
ui.setupUi(this);
ui.screenPushButton->setIcon(os::icon("screen.big"));
ui.areaPushButton->setIcon(os::icon("area.big"));
ui.windowPushButton->setIcon(os::icon("pickWindow.big"));
ui.optionsPushButton->setIcon(os::icon("configure"));
ui.folderPushButton->setIcon(os::icon("folder"));
ui.imgurPushButton->setIcon(os::icon("imgur"));
createUploadMenu();
#ifdef Q_OS_WIN
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7) {
mTaskbarButton = new QWinTaskbarButton(this);
mHasTaskbarButton = true;
if (QtWin::isCompositionEnabled()) {
setAttribute(Qt::WA_NoSystemBackground);
QtWin::enableBlurBehindWindow(this);
QtWin::extendFrameIntoClientArea(this, QMargins(-1, -1, -1, -1));
}
}
if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS7) {
ui.centralWidget->setStyleSheet("QPushButton { padding: 2px; border: 1px solid #acacac; background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #eaeaea, stop:1 #e5e5e5);} QPushButton:hover { border: 1px solid #7eb4ea; background-color: #e4f0fc; }");
}
#endif
setMaximumSize(size());
setMinimumSize(size());
setWindowFlags(windowFlags() ^ Qt::WindowMaximizeButtonHint);
// Actions
connect(ui.screenPushButton, SIGNAL(clicked()), this, SLOT(screenshotAction()));
connect(ui.areaPushButton , SIGNAL(clicked()), this, SLOT(areaHotkey()));
connect(ui.windowPushButton, SIGNAL(clicked()), this, SLOT(windowPickerHotkey()));
connect(ui.optionsPushButton, SIGNAL(clicked()), this, SLOT(showOptions()));
connect(ui.folderPushButton , SIGNAL(clicked()), this, SLOT(goToFolder()));
// Shortcuts
mGlobalHotkeys = new UGlobalHotkeys(this);
connect(mGlobalHotkeys, &UGlobalHotkeys::activated, [&](size_t id) {
if (id <= 3) {
screenshotAction(id);
} else if (id == 4) {
show();
} else if (id == 5) {
goToFolder();
} else {
qWarning() << "Uknown hotkey ID: " << id;
}
});
// Uploader
connect(Uploader::instance(), SIGNAL(progress(int)), this, SLOT(uploadProgress(int)));
connect(Uploader::instance(), SIGNAL(done(QString, 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 &)));
connect(ScreenshotManager::instance(), SIGNAL(activeCountChange()), this, SLOT(updateStatus()));
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);
settings()->sync();
mGlobalHotkeys->unregisterAllHotkeys();
}
void LightscreenWindow::action(int mode)
{
if (mode == 4) {
goToFolder();
} else {
show();
}
}
void LightscreenWindow::areaHotkey()
{
screenshotAction(2);
}
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.
}
mUpdater = new Updater(this);
connect(mUpdater, SIGNAL(done(bool)), this, SLOT(updaterDone(bool)));
mUpdater->check();
}
void LightscreenWindow::cleanup(Screenshot::Options &options)
{
// Reversing settings
if (settings()->value("options/hide").toBool()) {
#ifndef Q_OS_LINUX // 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 && !options.upload) {
// This message wll get shown only when messages are enabled and the file won't get another upload pop-up soon.
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_OS_WIN
QSound::play("afakepathtomakewindowsplaythedefaultsoundtheresprobablyabetterwaybuticantbebothered");
#else
QSound::play("sound/ls.error.wav");
#endif
}
}
updateStatus();
if (options.result != Screenshot::Success) {
return;
}
mLastScreenshot = options.fileName;
}
void LightscreenWindow::closeToTrayWarning()
{
if (!settings()->value("options/closeToTrayWarning", true).toBool()) {
return;
}
mLastMessage = 3;
mTrayIcon->showMessage(tr("Closed to tray"), tr("Lightscreen will keep running, you can disable this in the options menu."));
settings()->setValue("options/closeToTrayWarning", false);
}
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 true;
} else if (msgBox.clickedButton() == enableAndDenotifyButton) {
settings()->setValue("options/disableHideAlert", true);
applySettings();
return true;
} else if (msgBox.clickedButton() == enableButton) {
settings()->setValue("options/tray", true);
applySettings();
return true;
}
return false; // Cancel.
}
void LightscreenWindow::createUploadMenu()
{
QMenu *imgurMenu = new QMenu(tr("Upload"));
QAction *uploadAction = new QAction(os::icon("imgur"), tr("&Upload last"), imgurMenu);
uploadAction->setToolTip(tr("Upload the last screenshot you took to imgur.com"));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(uploadLast()));
QAction *cancelAction = new QAction(os::icon("no"), tr("&Cancel upload"), imgurMenu);
cancelAction->setToolTip(tr("Cancel the currently uploading screenshots"));
cancelAction->setEnabled(false);
connect(this, SIGNAL(uploading(bool)), cancelAction, SLOT(setEnabled(bool)));
connect(cancelAction, SIGNAL(triggered()), this, SLOT(uploadCancel()));
QAction *historyAction = new QAction(os::icon("view-history"), tr("View &History"), imgurMenu);
connect(historyAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog()));
imgurMenu->addAction(uploadAction);
imgurMenu->addAction(cancelAction);
imgurMenu->addAction(historyAction);
imgurMenu->addSeparator();
connect(imgurMenu, SIGNAL(aboutToShow()), this, SLOT(uploadMenuShown()));
ui.imgurPushButton->setMenu(imgurMenu);
}
void LightscreenWindow::goToFolder()
{
#ifdef Q_OS_WIN
if (!mLastScreenshot.isEmpty() && QFile::exists(mLastScreenshot)) {
QProcess::startDetached("explorer /select, \"" + mLastScreenshot + "\"");
} else {
#endif
QDir path(settings()->value("file/target").toString());
// We might want to go to the folder without it having been created by taking a screenshot yet.
if (!path.exists()) {
path.mkpath(path.absolutePath());
}
QDesktopServices::openUrl(QUrl::fromLocalFile(path.absolutePath() + QDir::separator()));
#ifdef Q_OS_WIN
}
#endif
}
void LightscreenWindow::messageClicked()
{
if (mLastMessage == 1) {
goToFolder();
} else if (mLastMessage == 3) {
QTimer::singleShot(0, this, SLOT(showOptions()));
} 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") {
showHistoryDialog();
} else if (message == "--options") {
showOptions();
} else if (message == "--quit") {
qApp->quit();
}
}
void LightscreenWindow::notify(const Screenshot::Result &result)
{
switch (result) {
case Screenshot::Success:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.yes"));
if (mHasTaskbarButton) {
mTaskbarButton->setOverlayIcon(os::icon("yes"));
}
setWindowTitle(tr("Success!"));
break;
case Screenshot::Fail:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.no"));
setWindowTitle(tr("Failed!"));
if (mHasTaskbarButton) {
mTaskbarButton->setOverlayIcon(os::icon("no"));
}
break;
case Screenshot::Cancel:
setWindowTitle(tr("Cancelled!"));
break;
}
QTimer::singleShot(2000, this, SLOT(restoreNotification()));
}
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());
int answer = 0;
QString doing;
if (ScreenshotManager::instance()->activeCount() > 0) {
doing = tr("processing");
}
if (Uploader::instance()->uploading() > 0) {
if (doing.isEmpty()) {
doing = tr("uploading");
} else {
doing = tr("processing and uploading");
}
}
if (!doing.isEmpty()) {
answer = QMessageBox::question(this,
tr("Are you sure you want to quit?"),
tr("Lightscreen is currently %1 screenshots. Are you sure you want to quit?").arg(doing),
tr("Quit"),
tr("Don't Quit"));
}
if (answer == 0) {
emit finished();
}
}
void LightscreenWindow::restoreNotification()
{
if (mTrayIcon) {
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.small"));
}
if (mHasTaskbarButton) {
mTaskbarButton->clearOverlayIcon();
mTaskbarButton->progress()->setVisible(false);
mTaskbarButton->progress()->stop();
mTaskbarButton->progress()->reset();
}
updateStatus();
}
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_OS_LINUX // 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();
QDir dir(settings()->value("file/target").toString());
dir.makeAbsolute();
options.directory = dir;
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.imgurClipboard = settings()->value("options/imgurClipboard", false).toBool();
options.preview = settings()->value("options/preview", false).toBool();
options.magnify = settings()->value("options/magnify", false).toBool();
options.cursor = settings()->value("options/cursor", true).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();
options.optimize = settings()->value("options/optipng", 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::screenHotkey()
{
screenshotAction(0);
}
void LightscreenWindow::showHotkeyError(const QStringList &hotkeys)
{
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>");
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Lightscreen"));
msgBox.setText(messageText);
QPushButton *changeButton = msgBox.addButton(tr("Change") , QMessageBox::ActionRole);
QPushButton *disableButton = msgBox.addButton(tr("Disable"), QMessageBox::ActionRole);
QPushButton *exitButton = msgBox.addButton(tr("Quit") , QMessageBox::ActionRole);
msgBox.exec();
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);
}
}
}
void LightscreenWindow::showHistoryDialog()
{
HistoryDialog historyDialog(this);
historyDialog.exec();
updateStatus();
}
void LightscreenWindow::showOptions()
{
mGlobalHotkeys->unregisterAllHotkeys();
QPointer<OptionsDialog> optionsDialog = new OptionsDialog(this);
optionsDialog->exec();
optionsDialog->deleteLater();
applySettings();
}
void LightscreenWindow::showScreenshotMessage(const Screenshot::Result &result, const QString &fileName)
{
if (result == Screenshot::Cancel) {
return;
}
// Showing message.
QString title;
QString message;
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.");
}
mLastMessage = 1;
mTrayIcon->showMessage(title, message);
}
void LightscreenWindow::showUploaderError(const QString &error)
{
mLastMessage = -1;
updateStatus();
if (mTrayIcon && !error.isEmpty() && settings()->value("options/message").toBool()) {
mTrayIcon->showMessage(tr("Upload error"), error);
}
notify(Screenshot::Fail);
}
-void LightscreenWindow::showUploaderMessage(QString fileName, QString url)
+void LightscreenWindow::showUploaderMessage(const QString &fileName, const QString &url)
{
if (mTrayIcon && settings()->value("options/message").toBool() && !url.isEmpty()) {
QString screenshot = QFileInfo(fileName).fileName();
if (screenshot.startsWith(".lstemp.")) {
screenshot = tr("Screenshot");
}
mLastMessage = 2;
mTrayIcon->showMessage(tr("%1 uploaded").arg(screenshot), tr("Click here to go to %1").arg(url));
}
updateStatus();
}
void LightscreenWindow::toggleVisibility(QSystemTrayIcon::ActivationReason reason)
{
if (reason != QSystemTrayIcon::DoubleClick) {
return;
}
if (isVisible()) {
hide();
} else {
show();
os::setForegroundWindow(this);
}
}
void LightscreenWindow::updateStatus()
{
int uploadCount = Uploader::instance()->uploading();
int activeCount = ScreenshotManager::instance()->activeCount();
if (mHasTaskbarButton) {
mTaskbarButton->progress()->setPaused(true);
mTaskbarButton->progress()->setVisible(true);
}
if (uploadCount > 0) {
setStatus(tr("%1 uploading").arg(uploadCount));
if (mHasTaskbarButton) {
mTaskbarButton->progress()->setRange(0, 100);
mTaskbarButton->progress()->resume();
}
emit uploading(true);
} else {
if (activeCount > 1) {
setStatus(tr("%1 processing").arg(activeCount));
} else if (activeCount == 1) {
setStatus(tr("processing"));
} else {
setStatus();
if (mHasTaskbarButton) {
mTaskbarButton->progress()->setVisible(false);
}
}
emit uploading(false);
}
}
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("https://lightscreen.com.ar/whatsnew?from=" + qApp->applicationVersion()));
} else if (msgBox.clickedButton() == turnOffButton) {
settings()->setValue("options/disableUpdater", true);
}
mUpdater->deleteLater();
}
void LightscreenWindow::upload(const QString &fileName)
{
Uploader::instance()->upload(fileName);
}
void LightscreenWindow::uploadCancel()
{
if (Uploader::instance()->uploading() <= 0) {
return;
}
int confirm = QMessageBox::question(this, tr("Upload cancel"), tr("Do you want to cancel all screenshot uploads?"), tr("Cancel"), tr("Don't Cancel"));
if (confirm == 0) {
Uploader::instance()->cancel();
updateStatus();
}
}
void LightscreenWindow::uploadLast()
{
upload(mLastScreenshot);
updateStatus();
}
void LightscreenWindow::uploadProgress(int progress)
{
if (mHasTaskbarButton) {
mTaskbarButton->progress()->setVisible(true);
mTaskbarButton->progress()->setValue(progress);
}
if (isVisible() && progress > 0) {
int uploadCount = Uploader::instance()->uploading();
if (uploadCount > 1) {
setWindowTitle(tr("%1% of %2 uploads - Lightscreen").arg(progress).arg(uploadCount));
} else {
setWindowTitle(tr("%1% - Lightscreen").arg(progress));
}
}
}
void LightscreenWindow::uploadMenuShown()
{
QMenu *imgurMenu = qobject_cast<QMenu *>(sender());
imgurMenu->actions().at(0)->setEnabled(!mLastScreenshot.isEmpty());
}
void LightscreenWindow::windowHotkey()
{
screenshotAction(1);
}
void LightscreenWindow::windowPickerHotkey()
{
screenshotAction(3);
}
void LightscreenWindow::applySettings()
{
bool tray = settings()->value("options/tray", true).toBool();
if (tray && !mTrayIcon) {
createTrayIcon();
mTrayIcon->setVisible(true);
} else if (!tray && mTrayIcon) {
mTrayIcon->setVisible(false);
}
connectHotkeys();
mDoCache = false;
if (settings()->value("lastScreenshot").isValid() && mLastScreenshot.isEmpty()) {
mLastScreenshot = settings()->value("lastScreenshot").toString();
}
os::setStartup(settings()->value("options/startup").toBool(), settings()->value("options/startupHide").toBool());
}
void LightscreenWindow::connectHotkeys()
{
QStringList failed;
QStringList actions = {"screen", "window", "area", "windowPicker", "open", "directory"};
size_t i = 0;
foreach (const QString &action, actions) {
if (settings()->value("actions/" + action + "/enabled").toBool()) {
if (!mGlobalHotkeys->registerHotkey(settings()->value("actions/" + action + "/hotkey").toString(), i)) {
failed << action;
}
}
i++;
}
if (!failed.isEmpty()) {
showHotkeyError(failed);
}
}
void LightscreenWindow::createTrayIcon()
{
mTrayIcon = new QSystemTrayIcon(QIcon(":/icons/lightscreen.small"), this);
updateStatus();
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(os::icon("screen"), tr("&Screen"), mTrayIcon);
screenAction->setData(QVariant(0));
QAction *windowAction = new QAction(os::icon("window"), tr("Active &Window"), this);
windowAction->setData(QVariant(1));
QAction *windowPickerAction = new QAction(os::icon("pickWindow"), tr("&Pick Window"), this);
windowPickerAction->setData(QVariant(3));
QAction *areaAction = new QAction(os::icon("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(os::icon("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 *cancelAction = new QAction(os::icon("no"), tr("&Cancel upload"), mTrayIcon);
cancelAction->setToolTip(tr("Cancel the currently uploading screenshots"));
cancelAction->setEnabled(false);
connect(this, SIGNAL(uploading(bool)), cancelAction, SLOT(setEnabled(bool)));
connect(cancelAction, SIGNAL(triggered()), this, SLOT(uploadCancel()));
QAction *historyAction = new QAction(os::icon("view-history"), tr("View History"), mTrayIcon);
connect(historyAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog()));
//
QAction *optionsAction = new QAction(os::icon("configure"), tr("View &Options"), mTrayIcon);
connect(optionsAction, SIGNAL(triggered()), this, SLOT(showOptions()));
QAction *goAction = new QAction(os::icon("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(areaAction);
screenshotMenu->addAction(windowAction);
screenshotMenu->addAction(windowPickerAction);
// Duplicated for the screenshot button :(
QMenu *imgurMenu = new QMenu(tr("Upload"));
imgurMenu->addAction(uploadAction);
imgurMenu->addAction(cancelAction);
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);
}
void LightscreenWindow::setStatus(QString status)
{
if (status.isEmpty()) {
status = tr("Lightscreen");
} else {
status += tr(" - Lightscreen");
}
if (mTrayIcon) {
mTrayIcon->setToolTip(status);
}
setWindowTitle(status);
}
QSettings *LightscreenWindow::settings() const
{
return ScreenshotManager::instance()->settings();
}
// Event handling
bool LightscreenWindow::event(QEvent *event)
{
if (event->type() == QEvent::Show) {
QPoint savedPosition = settings()->value("position").toPoint();
if (!savedPosition.isNull() && qApp->desktop()->availableGeometry().contains(QRect(savedPosition, size()))) {
move(savedPosition);
}
if (mHasTaskbarButton) {
mTaskbarButton->setWindow(windowHandle());
}
} else if (event->type() == QEvent::Hide) {
settings()->setValue("position", pos());
} else if (event->type() == QEvent::Close) {
if (settings()->value("options/tray").toBool() && settings()->value("options/closeHide").toBool()) {
closeToTrayWarning();
hide();
} else if (settings()->value("options/closeHide").toBool()) {
if (closingWithoutTray()) {
hide();
}
} else {
quit();
}
} 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 QMainWindow::event(event);
}
diff --git a/lightscreenwindow.h b/lightscreenwindow.h
index cf2b7f9..75bbb75 100644
--- a/lightscreenwindow.h
+++ b/lightscreenwindow.h
@@ -1,149 +1,149 @@
/*
* Copyright (C) 2016 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 <QMainWindow>
#include <QPointer>
#include <QSystemTrayIcon>
#include "updater/updater.h"
#include "tools/screenshot.h"
#include "dialogs/previewdialog.h"
#include "ui_lightscreenwindow.h"
class Updater;
class QSettings;
class QProgressBar;
class QWinTaskbarButton;
class UGlobalHotkeys;
class LightscreenWindow : public QMainWindow
{
Q_OBJECT
public:
LightscreenWindow(QWidget *parent = 0);
~LightscreenWindow();
public slots:
void action(int mode = 3);
void areaHotkey();
void checkForUpdates();
void cleanup(Screenshot::Options &options);
void closeToTrayWarning();
bool closingWithoutTray();
void createUploadMenu();
void goToFolder();
void messageClicked();
void messageReceived(const QString &message);
void notify(const Screenshot::Result &result);
void preview(Screenshot *screenshot);
void quit();
void restoreNotification();
void setStatus(QString status = "");
void screenshotAction(int mode = 0);
void screenshotActionTriggered(QAction *action);
void screenHotkey();
void showHotkeyError(const QStringList &hotkeys);
void showHistoryDialog();
void showOptions();
void showScreenshotMessage(const Screenshot::Result &result, const QString &fileName);
void showUploaderError(const QString &error);
- void showUploaderMessage(QString fileName, QString url);
+ void showUploaderMessage(const QString &fileName, const QString &url);
void toggleVisibility(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::DoubleClick);
void updateStatus();
void updaterDone(bool result);
void upload(const QString &fileName);
void uploadCancel();
void uploadLast();
void uploadProgress(int progress);
void uploadMenuShown();
void windowHotkey();
void windowPickerHotkey();
private slots:
void applySettings();
signals:
void uploading(bool uploading);
void finished();
private:
void connectHotkeys();
void createTrayIcon();
#ifdef Q_OS_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 mLastMessage;
int mLastMode;
QString mLastScreenshot;
QPointer<QSystemTrayIcon> mTrayIcon;
QPointer<PreviewDialog> mPreviewDialog;
QPointer<Updater> mUpdater;
Ui::LightscreenWindowClass ui;
QPointer<UGlobalHotkeys> mGlobalHotkeys;
bool mHasTaskbarButton;
#ifdef Q_OS_WIN
QPointer<QWinTaskbarButton> mTaskbarButton;
#else
class QWinTaskbarProgressDummy
{
public:
void setVisible(bool v) { Q_UNUSED(v) }
void setPaused(bool p) { Q_UNUSED(p) }
void resume() {}
void stop() {}
void reset() {}
void setRange(int m, int m2) { Q_UNUSED(m) Q_UNUSED(m2) }
void setValue(int v) { Q_UNUSED(v) }
};
class QWinTaskbarDummy : public QObject
{
public:
void setOverlayIcon(QIcon i) { Q_UNUSED(i) }
void clearOverlayIcon() {}
QWinTaskbarProgressDummy *progress() { return 0; }
void setWindow(QWindow *w) { Q_UNUSED(w) }
};
QWinTaskbarDummy *mTaskbarButton;
#endif
};
#endif // LIGHTSCREENWINDOW_H
diff --git a/tools/os.cpp b/tools/os.cpp
index 8529e44..30627b7 100644
--- a/tools/os.cpp
+++ b/tools/os.cpp
@@ -1,376 +1,376 @@
/*
* Copyright (C) 2016 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 <QGraphicsDropShadowEffect>
#include <QIcon>
#include <QLibrary>
#include <QLocale>
#include <QMessageBox>
#include <QPixmap>
#include <QPointer>
#include <QProcess>
#include <QSettings>
#include <QTextEdit>
#include <QTimeLine>
#include <QTimer>
#include <QUrl>
#include <QWidget>
#include <string>
#include <QMessageBox>
#include <QPainter>
#ifdef Q_OS_WIN
#include <QtWin>
#include <qt_windows.h>
#include <shlobj.h>
#elif defined(Q_OS_LINUX)
#include <QX11Info>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#endif
#include "os.h"
QPixmap os::cursor()
{
#ifdef Q_OS_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 = cursorInfo.hCursor;
ICONINFO iconInfo;
::GetIconInfo(cursor, &iconInfo);
ICONINFO info;
ZeroMemory(&info, sizeof(info));
if (::GetIconInfo(cursor, &info)) {
if (info.hbmColor) {
pixmap = QtWin::fromHBITMAP(info.hbmColor, QtWin::HBitmapAlpha);
} else {
QBitmap orig(QtWin::fromHBITMAP(info.hbmMask));
QImage img = orig.toImage();
int h = img.height() / 2;
int w = img.bytesPerLine() / sizeof(quint32);
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_OS_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_OS_WIN
RECT rcWindow;
HWND hwndId = (HWND)winId;
GetWindowRect(hwndId, &rcWindow);
int margin = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER) / 2;
rcWindow.right -= margin;
rcWindow.left += margin;
if (IsZoomed(hwndId)) {
rcWindow.top += margin;
} else {
rcWindow.top += GetSystemMetrics(SM_CXPADDEDBORDER);
}
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(hwndId);
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(hwndId);
hdcMem = CreateCompatibleDC(hdcWindow);
hbmCapture = CreateCompatibleBitmap(hdcWindow, width, height);
SelectObject(hdcMem, hbmCapture);
BitBlt(hdcMem, 0, 0, width, height, hdcWindow, 0, 0, SRCCOPY);
}
ReleaseDC(hwndId, hdcMem);
DeleteDC(hdcMem);
pixmap = QtWin::fromHBITMAP(hbmCapture);
DeleteObject(hbmCapture);
return pixmap;
#else
return QPixmap::grabWindow(winId);
#endif
}
void os::setForegroundWindow(QWidget *window)
{
#ifdef Q_OS_WIN
ShowWindow((HWND)window->winId(), SW_RESTORE);
SetForegroundWindow((HWND)window->winId());
#else
Q_UNUSED(window)
#endif
}
void os::setStartup(bool startup, bool hide)
{
QString lightscreen = QDir::toNativeSeparators(qApp->applicationFilePath());
if (hide) {
lightscreen.append(" -h");
}
#ifdef Q_OS_WIN
// Windows startup settings
QSettings init("Microsoft", "Windows");
init.beginGroup("CurrentVersion");
init.beginGroup("Run");
if (startup) {
init.setValue("Lightscreen", lightscreen);
} else {
init.remove("Lightscreen");
}
init.endGroup();
init.endGroup();
#endif
#if defined(Q_OS_LINUX)
QFile desktopFile(QDir::homePath() + "/.config/autostart/lightscreen.desktop");
desktopFile.remove();
if (startup) {
desktopFile.open(QIODevice::WriteOnly);
desktopFile.write(QString("[Desktop Entry]\nExec=%1\nType=Application").arg(lightscreen).toLatin1());
}
#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;
}
-QIcon os::icon(QString name, QColor backgroundColor)
+QIcon os::icon(const QString &name, QColor backgroundColor)
{
if (!backgroundColor.isValid()) {
backgroundColor = qApp->palette().color(QPalette::Button);
}
if (backgroundColor.value() > 125) {
return QIcon(":/icons/" + name);
} else {
return QIcon(":/icons/inv/" + name);
}
}
#ifdef Q_OS_LINUX
// Taken from KSnapshot. Oh KDE, what would I do without 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 4eef6de..ce90d95 100644
--- a/tools/os.h
+++ b/tools/os.h
@@ -1,72 +1,69 @@
/*
* Copyright (C) 2016 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>
class QPixmap;
class QPoint;
class QString;
class QUrl;
class QGraphicsEffect;
class QIcon;
#if defined(Q_OS_LINUX)
typedef unsigned long XID;
typedef XID Window;
#endif
namespace os {
// Returns the cursor pixmap in Windows
QPixmap cursor();
// 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);
// 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);
-
// Returns a QIcon for the given icon name (taking into account color schemes and whatnot).
-QIcon icon(QString name, QColor backgroundColor = QColor());
+QIcon icon(const QString &name, QColor backgroundColor = QColor());
// X11-specific functions for the Window Picker
#if defined(Q_OS_LINUX)
Window findRealWindow(Window w, int depth = 0);
Window windowUnderCursor(bool includeDecorations = true);
#endif
}
#endif /*OS_H_*/
diff --git a/tools/screenshot.cpp b/tools/screenshot.cpp
index 888a99f..096bac3 100644
--- a/tools/screenshot.cpp
+++ b/tools/screenshot.cpp
@@ -1,487 +1,487 @@
/*
* Copyright (C) 2016 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 <QProcess>
#include <QTextStream>
#include <QScreen>
#include "windowpicker.h"
#include "../dialogs/areadialog.h"
#include "uploader/uploader.h"
#include "screenshot.h"
#include "screenshotmanager.h"
#include "os.h"
#ifdef Q_OS_WIN
#include <windows.h>
#endif
#ifdef Q_OS_LINUX
#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 (!mUnloadFilename.isEmpty()) {
QFile::remove(mUnloadFilename);
}
}
QString Screenshot::getName(const NamingOptions &options, const QString &prefix, const 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.toLatin1(), 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::unloadedFileName()
{
return mUnloadFilename;
}
Screenshot::Options &Screenshot::options()
{
return mOptions;
}
QPixmap &Screenshot::pixmap()
{
return mPixmap;
}
//
void Screenshot::confirm(bool result)
{
if (result) {
save();
} else {
mOptions.result = Screenshot::Cancel;
emit finished();
}
emit cleanup();
mPixmap = QPixmap();
}
void Screenshot::confirmation()
{
emit askConfirmation();
if (mOptions.file) {
unloadPixmap();
}
}
void Screenshot::discard()
{
confirm(false);
}
void Screenshot::markUpload()
{
mOptions.upload = true;
}
void Screenshot::optimize()
{
QProcess *process = new QProcess(this);
// Delete the QProcess once it's done.
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this , SLOT(optimizationDone()));
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), process, SLOT(deleteLater()));
QString optiPNG;
#ifdef Q_OS_UNIX
optiPNG = "optipng";
#else
optiPNG = qApp->applicationDirPath() + QDir::separator() + "optipng.exe";
#endif
if (!QFile::exists(optiPNG)) {
emit optimizationDone();
}
process->start(optiPNG, QStringList() << mOptions.fileName);
if (process->state() == QProcess::NotRunning) {
emit optimizationDone();
process->deleteLater();
}
}
void Screenshot::optimizationDone()
{
if (mOptions.upload) {
upload();
} else {
emit finished();
}
}
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) + ")";
}
if (mOptions.clipboard && !(mOptions.upload && mOptions.imgurClipboard)) {
if (mUnloaded) {
mUnloaded = false;
mPixmap = QPixmap(mUnloadFilename);
}
QApplication::clipboard()->setPixmap(mPixmap, QClipboard::Clipboard);
if (!mOptions.file) {
result = (Screenshot::Result)1;
}
}
// 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) {
fileName = name + extension();
if (name.isEmpty()) {
result = Screenshot::Cancel;
} 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;
}
}
mOptions.fileName = fileName;
mOptions.result = result;
if (!mOptions.result) {
emit finished();
}
if (mOptions.format == Screenshot::PNG && mOptions.optimize && mOptions.file) {
if (!mOptions.upload) {
ScreenshotManager::instance()->saveHistory(mOptions.fileName);
}
optimize();
} else if (mOptions.upload) {
upload();
} else if (mOptions.file) {
ScreenshotManager::instance()->saveHistory(mOptions.fileName);
emit finished();
} else {
emit finished();
}
}
-void Screenshot::setPixmap(QPixmap pixmap)
+void Screenshot::setPixmap(const QPixmap &pixmap)
{
mPixmap = pixmap;
if (mPixmap.isNull()) {
emit confirm(false);
} else {
confirmation();
}
}
void Screenshot::take()
{
switch (mOptions.mode) {
case Screenshot::WholeScreen:
wholeScreen();
break;
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();
}
}
void Screenshot::upload()
{
if (mOptions.file) {
Uploader::instance()->upload(mOptions.fileName);
} else if (unloadPixmap()) {
Uploader::instance()->upload(mUnloadFilename);
} else {
emit finished();
}
}
-void Screenshot::uploadDone(QString url)
+void Screenshot::uploadDone(const QString &url)
{
if (mOptions.imgurClipboard && !url.isEmpty()) {
QApplication::clipboard()->setText(url, QClipboard::Clipboard);
}
emit finished();
}
//
void Screenshot::activeWindow()
{
#ifdef Q_OS_WIN
HWND fWindow = GetForegroundWindow();
if (fWindow == NULL) {
return;
}
if (fWindow == GetDesktopWindow()) {
wholeScreen();
return;
}
mPixmap = os::grabWindow((WId)GetForegroundWindow());
#endif
#if defined(Q_OS_LINUX)
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 = QApplication::primaryScreen()->geometry();
} else {
foreach (QScreen *screen, QGuiApplication::screens()) {
geometry = geometry.united(screen->geometry());
}
}
mPixmap = QApplication::primaryScreen()->grabWindow(QApplication::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.setDevicePixelRatio(QApplication::desktop()->devicePixelRatio());
}
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 path = QDir::toNativeSeparators(mOptions.directory.path());
// Cleanup
if (path.at(path.size() - 1) != QDir::separator() && !path.isEmpty()) {
path.append(QDir::separator());
}
QString fileName;
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)));
}
bool Screenshot::unloadPixmap()
{
if (mUnloaded) {
return true;
}
// 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) {
mPixmap = QPixmap();
}
return mUnloaded;
}
void Screenshot::wholeScreen()
{
grabDesktop();
}
diff --git a/tools/screenshot.h b/tools/screenshot.h
index c713cfe..27dc26e 100644
--- a/tools/screenshot.h
+++ b/tools/screenshot.h
@@ -1,136 +1,136 @@
/*
* Copyright (C) 2016 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;
NamingOptions namingOptions;
QDir directory;
QString prefix;
int mode;
int quality;
bool animations;
bool clipboard;
bool imgurClipboard;
bool currentMonitor;
bool cursor;
bool file;
bool magnify;
bool optimize;
bool preview;
bool replace;
bool saveAs;
bool upload;
};
Screenshot(QObject *parent, Screenshot::Options options);
~Screenshot();
Screenshot::Options &options();
QPixmap &pixmap();
static QString getName(const NamingOptions &options, const QString &prefix, const QDir &directory);
QString &unloadedFileName();
public slots:
void confirm(bool result = true);
void confirmation();
void discard();
void markUpload();
void optimize();
void optimizationDone();
void save();
- void setPixmap(QPixmap pixmap);
+ void setPixmap(const QPixmap &pixmap);
void take();
void upload();
- void uploadDone(QString url);
+ void uploadDone(const QString &url);
signals:
void askConfirmation();
void cleanup();
void finished();
private:
void activeWindow();
QString extension() const;
void grabDesktop();
QString newFileName() const;
void selectedArea();
void selectedWindow();
bool unloadPixmap();
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 2117b02..f978a89 100644
--- a/tools/screenshotmanager.cpp
+++ b/tools/screenshotmanager.cpp
@@ -1,215 +1,215 @@
/*
* Copyright (C) 2016 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 "uploader/uploader.h"
#include <QApplication>
#include <QDateTime>
#include <QStandardPaths>
#include <QFile>
#include <QSettings>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlRecord>
ScreenshotManager::ScreenshotManager(QObject *parent = 0) : QObject(parent)
{
if (QFile::exists(qApp->applicationDirPath() + QDir::separator() + "config.ini")) {
mSettings = new QSettings(qApp->applicationDirPath() + QDir::separator() + "config.ini", QSettings::IniFormat);
mPortableMode = true;
mHistoryPath = qApp->applicationDirPath() + QDir::separator();
} else {
mSettings = new QSettings();
mPortableMode = false;
mHistoryPath = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QDir::separator();
}
initHistory();
connect(Uploader::instance(), SIGNAL(done(QString, QString, QString)), this, SLOT(uploadDone(QString, QString, QString)));
}
ScreenshotManager::~ScreenshotManager()
{
delete mSettings;
}
void ScreenshotManager::initHistory()
{
// Creating the SQLite database.
QSqlDatabase history = QSqlDatabase::addDatabase("QSQLITE");
QDir hp(mHistoryPath);
if (!hp.exists()) {
hp.mkpath(mHistoryPath);
}
history.setHostName("localhost");
history.setDatabaseName(mHistoryPath + "history.sqlite");
if (history.open()) {
history.exec("CREATE TABLE IF NOT EXISTS history (fileName text, URL text, deleteURL text, time integer)");
} else {
qCritical() << "Could not open SQLite DB.";
}
}
int ScreenshotManager::activeCount() const
{
return mScreenshots.count();
}
bool ScreenshotManager::portableMode()
{
return mPortableMode;
}
-void ScreenshotManager::saveHistory(QString fileName, QString url, QString deleteHash)
+void ScreenshotManager::saveHistory(const QString &fileName, const QString &url, const QString &deleteHash)
{
if (!mSettings->value("/options/history", true).toBool()) {
return;
}
QString deleteUrl;
if (!deleteHash.isEmpty()) {
deleteUrl = "https://imgur.com/delete/" + deleteHash;
}
QSqlQuery query;
query.prepare("INSERT INTO history (fileName, URL, deleteURL, time) VALUES(?, ?, ?, ?)");
query.addBindValue(fileName);
query.addBindValue(url);
query.addBindValue(deleteUrl);
query.addBindValue(QDateTime::currentMSecsSinceEpoch());
query.exec();
}
-void ScreenshotManager::updateHistory(QString fileName, QString url, QString deleteHash)
+void ScreenshotManager::updateHistory(const QString &fileName, const QString &url, const QString &deleteHash)
{
if (!mSettings->value("/options/history", true).toBool() || url.isEmpty()) {
return;
}
QSqlQuery query;
query.prepare("SELECT fileName FROM history WHERE URL IS NOT EMPTY AND fileName = ?");
query.addBindValue(fileName);
query.exec();
if (query.record().count() > 0) {
QSqlQuery updateQuery;
updateQuery.prepare("UPDATE history SET URL = ?, deleteURL = ?, time = ? WHERE fileName = ?");
updateQuery.addBindValue(url);
updateQuery.addBindValue("https://imgur.com/delete/" + deleteHash);
updateQuery.addBindValue(QDateTime::currentMSecsSinceEpoch());
updateQuery.addBindValue(fileName);
updateQuery.exec();
} else {
saveHistory(fileName, url, deleteHash);
}
}
-void ScreenshotManager::removeHistory(QString fileName, qint64 time)
+void ScreenshotManager::removeHistory(const QString &fileName, qint64 time)
{
QSqlQuery removeQuery;
removeQuery.prepare("DELETE FROM history WHERE fileName = ? AND time = ?");
removeQuery.addBindValue(fileName);
removeQuery.addBindValue(time);
removeQuery.exec();
}
void ScreenshotManager::clearHistory()
{
QSqlQuery clearQuery("DROP TABLE history");
clearQuery.exec();
initHistory();
}
//
void ScreenshotManager::askConfirmation()
{
Screenshot *s = qobject_cast<Screenshot *>(sender());
emit confirm(s);
}
void ScreenshotManager::cleanup()
{
Screenshot *screenshot = qobject_cast<Screenshot *>(sender());
emit windowCleanup(screenshot->options());
}
void ScreenshotManager::finished()
{
Screenshot *screenshot = qobject_cast<Screenshot *>(sender());
mScreenshots.removeOne(screenshot);
emit activeCountChange();
screenshot->deleteLater();
}
void ScreenshotManager::take(Screenshot::Options &options)
{
Screenshot *newScreenshot = new Screenshot(this, options);
mScreenshots.append(newScreenshot);
connect(newScreenshot, SIGNAL(askConfirmation()), this, SLOT(askConfirmation()));
connect(newScreenshot, SIGNAL(cleanup()) , this, SLOT(cleanup()));
connect(newScreenshot, SIGNAL(finished()) , this, SLOT(finished()));
newScreenshot->take();
}
-void ScreenshotManager::uploadDone(QString fileName, QString url, QString deleteHash)
+void ScreenshotManager::uploadDone(const QString &fileName, const QString &url, const QString &deleteHash)
{
foreach (Screenshot *screenshot, mScreenshots) {
if (screenshot->options().fileName == fileName
|| screenshot->unloadedFileName() == fileName) {
screenshot->uploadDone(url);
if (screenshot->options().file) {
updateHistory(fileName, url, deleteHash);
} else {
saveHistory("", url, deleteHash);
}
return;
}
}
// If we get here, it's because the screenshot upload wasn't on the current screenshot list, which means it's a View History/Upload Later upload.
updateHistory(fileName, url, deleteHash);
}
// 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 e114fb0..c08bb6f 100644
--- a/tools/screenshotmanager.h
+++ b/tools/screenshotmanager.h
@@ -1,73 +1,73 @@
/*
* Copyright (C) 2016 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"
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 initHistory();
int activeCount() const;
bool portableMode();
- void saveHistory(QString fileName, QString url = "", QString deleteHash = "");
- void updateHistory(QString fileName, QString url, QString deleteHash);
- void removeHistory(QString fileName, qint64 time);
+ void saveHistory(const QString &fileName, const QString &url = "", const QString &deleteHash = "");
+ void updateHistory(const QString &fileName, const QString &url, const QString &deleteHash);
+ void removeHistory(const QString &fileName, qint64 time);
void clearHistory();
QSettings *settings() const { return mSettings; }
public slots:
void askConfirmation();
void cleanup();
void finished();
void take(Screenshot::Options &options);
- void uploadDone(QString fileName, QString url, QString deleteHash);
+ void uploadDone(const QString &fileName, const QString &url, const QString &deleteHash);
signals:
void confirm(Screenshot *screenshot);
void windowCleanup(Screenshot::Options &options);
void activeCountChange();
private:
static ScreenshotManager *mInstance;
QList<Screenshot *> mScreenshots;
QSettings *mSettings;
QString mHistoryPath;
bool mPortableMode;
};
#endif // SCREENSHOTMANAGER_H
diff --git a/tools/windowpicker.h b/tools/windowpicker.h
index f08b7f3..43ef45b 100644
--- a/tools/windowpicker.h
+++ b/tools/windowpicker.h
@@ -1,56 +1,56 @@
/*
* Copyright (C) 2016 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();
signals:
- void pixmap(QPixmap pixmap);
+ void pixmap(const QPixmap &pixmap);
protected:
void closeEvent(QCloseEvent *);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private:
void cancel();
private:
QPixmap mCrosshair;
QLabel *mCrosshairLabel;
QLabel *mWindowIcon;
QLabel *mWindowLabel;
WId mCurrentWindow;
bool mTaken;
};
#endif // WINDOWPICKER_H
diff --git a/widgets/hotkeywidget.cpp b/widgets/hotkeywidget.cpp
index 418e66a..f4c6eec 100644
--- a/widgets/hotkeywidget.cpp
+++ b/widgets/hotkeywidget.cpp
@@ -1,162 +1,162 @@
/*
* Copyright (C) 2016 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 <QStyle>
#include <QTimer>
#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(QString hotkeyString)
+void HotkeyWidget::setHotkey(const QString &hotkeyString)
{
mHotkey = QKeySequence().fromString(hotkeyString, QKeySequence::NativeText);
setHotkeyText();
}
QString HotkeyWidget::hotkey() const
{
return mHotkey.toString(QKeySequence::PortableText);
}
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::KeyPress) {
keyPressEvent(static_cast<QKeyEvent *>(event));
return true;
} 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
} else if ((event->type() == QEvent::KeyPress || event->type() == QEvent::ShortcutOverride || event->type() == QEvent::Shortcut) && hasFocus()) {
event->accept();
return true;
}
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::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;
}
return false;
}
diff --git a/widgets/hotkeywidget.h b/widgets/hotkeywidget.h
index 1c1f756..b56d4a2 100644
--- a/widgets/hotkeywidget.h
+++ b/widgets/hotkeywidget.h
@@ -1,59 +1,59 @@
/*
* Copyright (C) 2016 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(QString hotkey);
+ void setHotkey(const QString &hotkey);
QString hotkey() const;
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
Tue, Jun 16, 12:13 AM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70696
Default Alt Text
(112 KB)

Event Timeline