Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
60 KB
Referenced Files
None
Subscribers
None
diff --git a/.gitignore b/.gitignore
index 09b4d02..cc67ce3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-*.2-pre1
\ No newline at end of file
+*.2-pre1
+*.autosave
\ No newline at end of file
diff --git a/dialogs/historydialog.cpp b/dialogs/historydialog.cpp
index edfe4ef..d5fead6 100644
--- a/dialogs/historydialog.cpp
+++ b/dialogs/historydialog.cpp
@@ -1,277 +1,286 @@
#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);
}
- ui->uploadProgressBar->setValue(Uploader::instance()->progress());
+ 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->clearButton , SIGNAL(clicked()), this, SLOT(clear()));
+
+ 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)
{
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(QModelIndex index)
{
if (index.column() == 0) {
QDesktopServices::openUrl(QUrl("file:///" + index.data().toString()));
}
else {
QDesktopServices::openUrl(index.data().toUrl());
}
}
void HistoryDialog::selectionChanged(QItemSelection selected, 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->uploadButton->setEnabled(false);
+ ui->uploadProgressWidget->setVisible(true);
}
void HistoryDialog::uploadProgress(int progress)
{
- ui->uploadProgressBar->setEnabled(true);
+ 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() == "") {
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.ui b/dialogs/historydialog.ui
index 4dd6d64..d5a450e 100644
--- a/dialogs/historydialog.ui
+++ b/dialogs/historydialog.ui
@@ -1,132 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>HistoryDialog</class>
<widget class="QDialog" name="HistoryDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>327</width>
- <height>252</height>
+ <width>352</width>
+ <height>294</height>
</rect>
</property>
<property name="windowTitle">
<string>Screenshot History</string>
</property>
<property name="windowIcon">
<iconset resource="../lightscreen.qrc">
<normaloff>:/icons/view-history</normaloff>:/icons/view-history</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
- <property name="spacing">
- <number>4</number>
- </property>
- <property name="margin">
- <number>6</number>
- </property>
<item>
<widget class="QLineEdit" name="filterEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="whatsThis">
<string>Type here to filter through the screenshots in the list.</string>
</property>
<property name="styleSheet">
<string notr="true">color: palette(mid);</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="tableView">
<property name="whatsThis">
<string>Double click the path to open the image with the default picture viewer, you can also double-click the URL to open it on your web browser.
Right click items to get access to more options.</string>
</property>
</widget>
</item>
<item>
- <widget class="QProgressBar" name="uploadProgressBar">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- <property name="textVisible">
- <bool>false</bool>
- </property>
+ <widget class="QWidget" name="uploadProgressWidget" native="true">
+ <layout class="QHBoxLayout" name="uploadProgressLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QProgressBar" name="uploadProgressBar">
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelUploadButton">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="clearButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="uploadButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Upload</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>Close</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../lightscreen.qrc"/>
</resources>
<connections>
<connection>
<sender>closeButton</sender>
<signal>clicked()</signal>
<receiver>HistoryDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>230</y>
</hint>
<hint type="destinationlabel">
<x>163</x>
<y>125</y>
</hint>
</hints>
</connection>
</connections>
</ui>
diff --git a/lightscreenwindow.cpp b/lightscreenwindow.cpp
index 40eb350..d18bd73 100644
--- a/lightscreenwindow.cpp
+++ b/lightscreenwindow.cpp
@@ -1,1039 +1,1041 @@
/*
* Copyright (C) 2014 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>
#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/qxtglobalshortcut/qxtglobalshortcut.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()
{
ui.setupUi(this);
if (QtWin::isCompositionEnabled()) {
setAttribute(Qt::WA_NoSystemBackground);
QtWin::enableBlurBehindWindow(this);
QtWin::extendFrameIntoClientArea(this, QMargins(-1, -1, -1, -1));
}
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"));
setMaximumSize(size());
setMinimumSize(size());
setWindowFlags(windowFlags() ^ Qt::WindowMaximizeButtonHint);
#ifdef Q_OS_WIN
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
mTaskbarButton = new QWinTaskbarButton(this);
}
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
// 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()));
connect(ui.imgurPushButton, SIGNAL(clicked()), this, SLOT(createUploadMenu()));
// Shortcuts
connect(&mScreenShortcut , &QxtGlobalShortcut::activated, this, &LightscreenWindow::screenHotkey);
connect(&mAreaShortcut , &QxtGlobalShortcut::activated, this, &LightscreenWindow::areaHotkey);
connect(&mWindowShortcut , &QxtGlobalShortcut::activated, this, &LightscreenWindow::windowHotkey);
connect(&mWindowPickerShortcut, &QxtGlobalShortcut::activated, this, &LightscreenWindow::windowPickerHotkey);
connect(&mOpenShortcut , &QxtGlobalShortcut::activated, this, &LightscreenWindow::show);
connect(&mDirectoryShortcut , &QxtGlobalShortcut::activated, this, &LightscreenWindow::goToFolder);
// 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();
delete mTrayIcon;
}
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_WS_X11 // X is not quick enough and the notification ends up everywhere but in the icon
if (settings()->value("options/tray").toBool() && mTrayIcon) {
mTrayIcon->show();
}
#endif
if (mPreviewDialog) {
if (mPreviewDialog->count() <= 1 && mWasVisible) {
show();
}
mPreviewDialog->show();
}
else if (mWasVisible) {
show();
}
mHideTrigger = false;
}
if (settings()->value("options/tray").toBool() && mTrayIcon) {
notify(options.result);
if (settings()->value("options/message").toBool() && options.file && !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);
ui.imgurPushButton->showMenu();
}
void LightscreenWindow::goToFolder()
{
#ifdef Q_OS_WIN
if (!mLastScreenshot.isEmpty() && QFile::exists(mLastScreenshot)) {
QProcess::startDetached("explorer /select, \"" + mLastScreenshot +"\"");
}
else {
#endif
QString folder = settings()->value("file/target").toString();
if (folder.isEmpty())
folder = qApp->applicationDirPath();
if (QDir::toNativeSeparators(folder.at(folder.size()-1)) != QDir::separator())
folder.append(QDir::separator());
QDesktopServices::openUrl("file:///"+folder);
#ifdef Q_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();
}
void LightscreenWindow::notify(const Screenshot::Result &result)
{
switch (result)
{
case Screenshot::Success:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.yes"));
#ifdef Q_OS_WIN
if (mTaskbarButton)
mTaskbarButton->setOverlayIcon(os::icon("yes"));
#endif
setWindowTitle(tr("Success!"));
break;
case Screenshot::Fail:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.no"));
setWindowTitle(tr("Failed!"));
#ifdef Q_OS_WIN
if (mTaskbarButton) {
mTaskbarButton->setOverlayIcon(os::icon("no"));
}
#endif
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"));
#ifdef Q_OS_WIN
if (mTaskbarButton)
mTaskbarButton->clearOverlayIcon();
#endif
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_WS_X11 // X is not quick enough and the notification ends up everywhere but in the icon
if (mTrayIcon)
mTrayIcon->hide();
#endif
}
// Screenshot delay
delayms = settings()->value("options/delay", 0).toInt();
delayms = delayms * 1000; // Converting the delay to milliseconds.
delayms += 400;
if (optionsHide && mPreviewDialog) {
if (mPreviewDialog->count() >= 1) {
mPreviewDialog->hide();
}
}
// The delayed functions works using the static variable lastMode
// which keeps the argument so a QTimer can call this function again.
if (delayms > 0) {
if (mLastMode < 0) {
mLastMode = mode;
QTimer::singleShot(delayms, this, SLOT(screenshotAction()));
return;
}
else {
mode = mLastMode;
mLastMode = -1;
}
}
static Screenshot::Options options;
if (!mDoCache) {
// Populating the option object that will then be passed to the screenshot engine (sounds fancy huh?)
options.file = settings()->value("file/enabled").toBool();
options.format = (Screenshot::Format) settings()->value("file/format").toInt();
options.prefix = settings()->value("file/prefix").toString();
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;
- setStatus(tr("Processing..."));
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()
{
mScreenShortcut.setEnabled(false);
mAreaShortcut.setEnabled(false);
mWindowShortcut.setEnabled(false);
mWindowPickerShortcut.setEnabled(false);
mOpenShortcut.setEnabled(false);
mDirectoryShortcut.setEnabled(false);
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)
{
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 (uploadCount > 0) {
setStatus(tr("%1 uploading").arg(uploadCount));
emit uploading(true);
}
else {
- if (activeCount > 0) {
+ if (activeCount > 1) {
setStatus(tr("%1 processing").arg(activeCount));
}
+ else if (activeCount == 1) {
+ setStatus(tr("processing"));
+ }
else {
setStatus();
}
emit uploading(false);
#ifdef Q_OS_WIN
if (mTaskbarButton) {
mTaskbarButton->progress()->setVisible(false);
}
#endif
}
}
void LightscreenWindow::updaterDone(bool result)
{
settings()->setValue("lastUpdateCheck", QDate::currentDate().dayOfYear());
if (!result)
return;
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Lightscreen"));
msgBox.setText(tr("There's a new version of Lightscreen available.<br>Would you like to see more information?<br>(<em>You can turn this notification off</em>)"));
msgBox.setIcon(QMessageBox::Information);
QPushButton *yesButton = msgBox.addButton(QMessageBox::Yes);
QPushButton *turnOffButton = msgBox.addButton(tr("Turn Off"), QMessageBox::ActionRole);
QPushButton *remindButton = msgBox.addButton(tr("Remind Me Later"), QMessageBox::RejectRole);
Q_UNUSED(remindButton);
msgBox.exec();
if (msgBox.clickedButton() == yesButton) {
QDesktopServices::openUrl(QUrl("http://lightscreen.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)
{
#ifdef Q_OS_WIN
if (mTaskbarButton) {
mTaskbarButton->progress()->setRange(0, 100);
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));
}
}
#endif
}
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").toBool();
if (tray && !mTrayIcon) {
createTrayIcon();
mTrayIcon->show();
}
else if (!tray && mTrayIcon) {
mTrayIcon->deleteLater();
}
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()
{
bool screen = mScreenShortcut.setShortcut(settings()->value("actions/screen/hotkey").value<QKeySequence>());
mScreenShortcut.setEnabled(settings()->value("actions/screen/enabled").toBool());
bool area = mAreaShortcut.setShortcut(settings()->value("actions/area/hotkey").value<QKeySequence>());
mAreaShortcut.setEnabled(settings()->value("actions/area/enabled").toBool());
bool window = mWindowShortcut.setShortcut(settings()->value("actions/window/hotkey").value<QKeySequence>());
mWindowShortcut.setEnabled(settings()->value("actions/window/enabled").toBool());
bool windowPicker = mWindowPickerShortcut.setShortcut(settings()->value("actions/windowPicker/hotkey").value<QKeySequence>());
mWindowPickerShortcut.setEnabled(settings()->value("actions/windowPicker/enabled").toBool());
bool open = mOpenShortcut.setShortcut(settings()->value("actions/open/hotkey").value<QKeySequence>());
mOpenShortcut.setEnabled(settings()->value("actions/open/enabled").toBool());
bool directory = mOpenShortcut.setShortcut(settings()->value("actions/directory/hotkey").value<QKeySequence>());
mDirectoryShortcut.setEnabled(settings()->value("actions/directory/enabled").toBool());
QStringList failed;
if (!screen) failed << "screen";
if (!area) failed << "area";
if (!window) failed << "window";
if (!windowPicker) failed << "window picker";
if (!open) failed << "open";
if (!directory) failed << "directory";
if (!failed.isEmpty())
showHotkeyError(failed);
}
void LightscreenWindow::createTrayIcon()
{
mTrayIcon = new QSystemTrayIcon(QIcon(":/icons/lightscreen.small"), this);
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::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::Show) {
QPoint savedPosition = settings()->value("position").toPoint();
if (!savedPosition.isNull() && qApp->desktop()->availableGeometry().contains(QRect(savedPosition, size())))
move(savedPosition);
}
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/tools/screenshotmanager.cpp b/tools/screenshotmanager.cpp
index 52c21e0..21a4774 100644
--- a/tools/screenshotmanager.cpp
+++ b/tools/screenshotmanager.cpp
@@ -1,215 +1,212 @@
/*
* Copyright (C) 2014 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)
{
if (!mSettings->value("/options/history", true).toBool())
return;
QString deleteUrl;
if (!deleteHash.isEmpty())
deleteUrl = "http://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)
{
if (!mSettings->value("/options/history", true).toBool())
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 && !url.isEmpty()) {
// Makes sure to only update the latest file, in case something weird happened with the files (deleted screenshots, etc). Though that might still happen in some edge cases that I'm too lazy to account for.
QSqlQuery updateQuery;
updateQuery.prepare("UPDATE history SET URL = ?, deleteURL = ?, time = ? WHERE fileName = ?");
updateQuery.addBindValue(url);
updateQuery.addBindValue("http://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)
{
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)
{
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/uploader/uploader.cpp b/tools/uploader/uploader.cpp
index 9393e9f..00502f3 100644
--- a/tools/uploader/uploader.cpp
+++ b/tools/uploader/uploader.cpp
@@ -1,199 +1,200 @@
/*
* Copyright (C) 2014 Christian Kaiser
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "uploader.h"
#include "../screenshotmanager.h"
#include "imguruploader.h"
#include <QtNetwork>
#include <QSettings>
Uploader* Uploader::mInstance = 0;
Uploader::Uploader(QObject *parent) : QObject(parent)
{
mNetworkAccessManager = new QNetworkAccessManager(this);
}
Uploader *Uploader::instance()
{
if (!mInstance)
mInstance = new Uploader();
return mInstance;
}
int Uploader::progress() const
{
return mProgress;
}
QNetworkAccessManager* Uploader::nam()
{
return mNetworkAccessManager;
}
QString Uploader::lastUrl() const
{
return mLastUrl;
}
void Uploader::cancel()
{
mUploaders.clear();
+ mProgress = 0;
emit cancelAll();
}
void Uploader::upload(const QString &fileName)
{
if (fileName.isEmpty()) {
return;
}
QVariantHash options;
QSettings *s = ScreenshotManager::instance()->settings();
options["type"] = "imgur";
options["networkManager"].setValue(mNetworkAccessManager);
options["directUrl"] = s->value("options/uploadDirectLink", false).toBool();
options["anonymous"] = s->value("upload/imgur/anonymous", true).toBool();
options["album"] = s->value("upload/imgur/album", "").toString();
options["access_token"] = s->value("upload/imgur/access_token", "").toString();
options["refresh_token"] = s->value("upload/imgur/refresh_token", "").toString();
if (options["access_token"].toString().isEmpty() || options["refresh_token"].toString().isEmpty())
{
options["anonymous"] = true;
}
ImgurUploader *uploader = new ImgurUploader(options);
connect(uploader, &ImgurUploader::uploaded , this, &Uploader::uploaded);
connect(uploader, &ImgurUploader::error , this, &Uploader::uploaderError);
connect(uploader, &ImgurUploader::progressChange , this, &Uploader::progressChange);
connect(uploader, &ImgurUploader::needAuthRefresh, this, &Uploader::imgurAuthRefresh);
connect(this , SIGNAL(cancelAll()), uploader, SLOT(cancel()));
uploader->upload(fileName);
mUploaders.append(uploader);
}
void Uploader::uploaded(const QString &file, const QString &url, const QString &deleteHash)
{
mLastUrl = url;
mUploaders.removeAll(qobject_cast<ImageUploader*>(sender()));
sender()->deleteLater();
emit done(file, url, deleteHash);
}
void Uploader::imgurAuthRefresh()
{
for (int i = 0; i < mUploaders.size(); ++i) {
if (mUploaders[i]->options().value("type") == "imgur") {
mUploaders[i]->cancel();
}
}
QByteArray parameters;
parameters.append(QString("refresh_token=").toUtf8());
parameters.append(QUrl::toPercentEncoding(ScreenshotManager::instance()->settings()->value("upload/imgur/refresh_token").toString()));
parameters.append(QString("&client_id=").toUtf8());
parameters.append(QUrl::toPercentEncoding("3ebe94c791445c1"));
parameters.append(QString("&client_secret=").toUtf8());
parameters.append(QUrl::toPercentEncoding("0546b05d6a80b2092dcea86c57b792c9c9faebf0")); // TODO: TA.png
parameters.append(QString("&grant_type=refresh_token").toUtf8());
QNetworkRequest request(QUrl("https://api.imgur.com/oauth2/token"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QNetworkReply* reply = Uploader::instance()->nam()->post(request, parameters);
connect(reply, SIGNAL(finished()), this, SLOT(imgurToken()));
}
void Uploader::imgurToken()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if (reply->error() != QNetworkReply::NoError) {
emit error(reply->errorString());
return;
}
QJsonObject imgurResponse = QJsonDocument::fromJson(reply->readAll()).object();
QSettings* s = ScreenshotManager::instance()->settings();
s->setValue("upload/imgur/access_token" , imgurResponse["access_token"].toString());
s->setValue("upload/imgur/refresh_token" , imgurResponse["refresh_token"].toString());
s->setValue("upload/imgur/account_username", imgurResponse["account_username"].toString());
s->setValue("upload/imgur/expires_in" , imgurResponse["expires_in"].toString());
for (int i = 0; i < mUploaders.size(); ++i) {
if (mUploaders[i]->options().value("type") == "imgur") {
mUploaders[i]->options().remove("access_token");
mUploaders[i]->options().remove("refresh_token");
mUploaders[i]->options().insert("access_token" , imgurResponse["access_token"].toString());
mUploaders[i]->options().insert("refresh_token", imgurResponse["refresh_token"].toString());
mUploaders[i]->retry();
}
}
emit imgurAuthRefreshed();
}
void Uploader::uploaderError(ImageUploader::Error code, QString errorString, QString fileName)
{
mUploaders.removeAll(qobject_cast<ImageUploader*>(sender()));
sender()->deleteLater();
if (code != ImageUploader::CancelError) {
if (errorString.isEmpty()) {
emit error(tr("Upload Error ") + code);
}
else {
emit error(errorString);
}
}
emit done(fileName, "", "");
}
int Uploader::uploading()
{
return mUploaders.count();
}
void Uploader::progressChange(int p)
{
if (mUploaders.size() <= 0) {
emit progress(p);
return;
}
int totalProgress = 0;
for (int i = 0; i < mUploaders.size(); ++i) {
totalProgress += mUploaders[i]->progress();
}
mProgress = totalProgress / mUploaders.size();
emit progress(mProgress);
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jun 15, 11:35 PM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70118
Default Alt Text
(60 KB)

Event Timeline