# HG changeset patch # User Stepan777 # Date 1343325505 -14400 # Node ID 01111960a48d405a2bc1e12a2201c0803ab69a7a # Parent 9bb6abdb567541ca0c6381aeef28c44f593b90c9 uploading to youtube, it works, but user interface is still incomplete diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/binds.h --- a/QTfrontend/binds.h Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/binds.h Thu Jul 26 21:58:25 2012 +0400 @@ -21,7 +21,7 @@ #include -#define BINDS_NUMBER 45 +#define BINDS_NUMBER 46 struct BindAction { diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/res/css/birthday.css --- a/QTfrontend/res/css/birthday.css Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/res/css/birthday.css Thu Jul 26 21:58:25 2012 +0400 @@ -33,7 +33,7 @@ a { color:#c8c8ff; } QLineEdit, QListWidget, QTableView, QTextBrowser, QSpinBox, QComboBox, -QComboBox QAbstractItemView, QMenu::item { +QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item { background-color: rgba(13, 5, 68, 70%); } @@ -42,7 +42,7 @@ } QPushButton, QListWidget, QTableView, QLineEdit, QHeaderView, -QTextBrowser, QSpinBox, QToolBox, QComboBox, +QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget, QTabWidget::pane, QTabBar::tab { @@ -57,14 +57,14 @@ } QLineEdit, QListWidget,QTableView, QTextBrowser, -QSpinBox, QToolBox { +QSpinBox, QToolBox, QPlainTextEdit { border-radius: 10px; } QLineEdit, QLabel, QHeaderView, QListWidget, QTableView, QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, -SelWeaponWidget, QCheckBox, QRadioButton, QPushButton { +SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit { font: bold 13px; } SelWeaponWidget QTabWidget::pane, SelWeaponWidget QTabBar::tab:selected { diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/res/css/christmas.css --- a/QTfrontend/res/css/christmas.css Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/res/css/christmas.css Thu Jul 26 21:58:25 2012 +0400 @@ -33,7 +33,7 @@ a { color:#c8c8ff; } QLineEdit, QListWidget, QTableView, QTextBrowser, QSpinBox, QComboBox, -QComboBox QAbstractItemView, QMenu::item { +QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item { background-color: rgba(13, 5, 68, 70%); } @@ -42,7 +42,7 @@ } QPushButton, QListWidget, QTableView, QLineEdit, QHeaderView, -QTextBrowser, QSpinBox, QToolBox, QComboBox, +QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget, QTabWidget::pane, QTabBar::tab { @@ -57,14 +57,14 @@ } QLineEdit, QListWidget,QTableView, QTextBrowser, -QSpinBox, QToolBox { +QSpinBox, QToolBox, QPlainTextEdit { border-radius: 10px; } QLineEdit, QLabel, QHeaderView, QListWidget, QTableView, QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, -SelWeaponWidget, QCheckBox, QRadioButton, QPushButton { +SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit { font: bold 13px; } SelWeaponWidget QTabWidget::pane, SelWeaponWidget QTabBar::tab:selected { diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/res/css/easter.css --- a/QTfrontend/res/css/easter.css Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/res/css/easter.css Thu Jul 26 21:58:25 2012 +0400 @@ -33,7 +33,7 @@ a { color:#c8c8ff; } QLineEdit, QListWidget, QTableView, QTextBrowser, QSpinBox, QComboBox, -QComboBox QAbstractItemView, QMenu::item { +QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item { background-color: rgba(13, 5, 68, 70%); } @@ -42,7 +42,7 @@ } QPushButton, QListWidget, QTableView, QLineEdit, QHeaderView, -QTextBrowser, QSpinBox, QToolBox, QComboBox, +QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget, QTabWidget::pane, QTabBar::tab { @@ -57,14 +57,14 @@ } QLineEdit, QListWidget,QTableView, QTextBrowser, -QSpinBox, QToolBox { +QSpinBox, QToolBox, QPlainTextEdit { border-radius: 10px; } QLineEdit, QLabel, QHeaderView, QListWidget, QTableView, QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, -SelWeaponWidget, QCheckBox, QRadioButton, QPushButton { +SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit { font: bold 13px; } SelWeaponWidget QTabWidget::pane, SelWeaponWidget QTabBar::tab:selected { diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/res/css/qt.css --- a/QTfrontend/res/css/qt.css Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/res/css/qt.css Thu Jul 26 21:58:25 2012 +0400 @@ -33,7 +33,7 @@ a { color:#c8c8ff; } QLineEdit, QListWidget, QTableView, QTextBrowser, QSpinBox, QComboBox, -QComboBox QAbstractItemView, QMenu::item { +QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item { background-color: rgba(13, 5, 68, 70%); } @@ -42,7 +42,7 @@ } QPushButton, QListWidget, QTableView, QLineEdit, QHeaderView, -QTextBrowser, QSpinBox, QToolBox, QComboBox, +QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget, QTabWidget::pane, QTabBar::tab { @@ -57,14 +57,14 @@ } QLineEdit, QListWidget,QTableView, QTextBrowser, -QSpinBox, QToolBox { +QSpinBox, QToolBox, QPlainTextEdit { border-radius: 10px; } QLineEdit, QLabel, QHeaderView, QListWidget, QTableView, QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView, IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget, -SelWeaponWidget, QCheckBox, QRadioButton, QPushButton { +SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit { font: bold 13px; } SelWeaponWidget QTabWidget::pane, SelWeaponWidget QTabBar::tab:selected { diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/ui/dialog/ask_quit.cpp --- a/QTfrontend/ui/dialog/ask_quit.cpp Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/ui/dialog/ask_quit.cpp Thu Jul 26 21:58:25 2012 +0400 @@ -35,7 +35,7 @@ QVBoxLayout * layout = new QVBoxLayout(this); QLabel * lbLabel = new QLabel(this); - lbLabel->setText(QLabel::tr("There are videos that are currently being encoded.\n" + lbLabel->setText(QLabel::tr("There are videos that are currently being processed.\n" "Exiting now will abort them.\n" "Do yot really want to quit?")); layout->addWidget(lbLabel); diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/ui/dialog/upload_video.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/ui/dialog/upload_video.cpp Thu Jul 26 21:58:25 2012 +0400 @@ -0,0 +1,245 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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; version 2 of the License + * + * 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "upload_video.h" +#include "hwconsts.h" + +// User-agent string used in http requests. +static const QByteArray UserAgent = ("Hedgewars-QtFrontend/" + *cVersionString).toAscii(); + +// This is developer key obtained from http://code.google.com/apis/youtube/dashboard/ +// If you are reusing this code outside Hedgewars, don't use this developer key, +// obtain you own at http://code.google.com/apis/youtube/dashboard/ +static const QByteArray devKey = "AI39si5pKjxR0XgNIlmrEFF-LyYD31rps4g2O5dZTxLgD0fvJ2rHxrMrNFY8FYTZrzeI3VlaFVQLKfFnSBugvdZmy8vFzRDefQ"; + +HWUploadVideoDialog::HWUploadVideoDialog(QWidget* parent, const QString &filename, QNetworkAccessManager* netManager) : QDialog(parent) +{ + this->filename = filename; + this->netManager = netManager; + + setWindowTitle(tr("Upload video")); + + // Google requires us to display this, see https://developers.google.com/youtube/terms + QString GoogleNotice = + "By clicking 'upload,' you certify that you own all rights to the content or that\n" + "you are authorized by the owner to make the content publicly available on YouTube,\n" + "and that it otherwise complies with the YouTube Terms of Service located at\n" + "http://www.youtube.com/t/terms."; + + QGridLayout * layout = new QGridLayout(this); + + QLabel * lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr( + "Please provide either the YouTube account name\n" + "or the email address associated with the Google Account.")); + layout->addWidget(lbLabel, 0, 0, 1, 2); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Account name (or email): ")); + layout->addWidget(lbLabel, 1, 0); + + leAccount = new QLineEdit(this); + layout->addWidget(leAccount, 1, 1); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Password: ")); + layout->addWidget(lbLabel, 2, 0); + + lePassword = new QLineEdit(this); + lePassword->setEchoMode(QLineEdit::Password); + layout->addWidget(lePassword, 2, 1); + + cbSave = new QCheckBox(this); + cbSave->setText(QCheckBox::tr("Save account name and password")); + layout->addWidget(cbSave, 3, 0, 1, 2); + + QFrame * hr = new QFrame(this); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + layout->addWidget(hr, 4, 0, 1, 2); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Video title: ")); + layout->addWidget(lbLabel, 5, 0); + + leTitle = new QLineEdit(this); + leTitle->setText(filename); + layout->addWidget(leTitle, 5, 1); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Video description: ")); + layout->addWidget(lbLabel, 6, 0, 1, 2); + + teDescription = new QPlainTextEdit(this); + layout->addWidget(teDescription, 7, 0, 1, 2); + + hr = new QFrame(this); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + layout->addWidget(hr, 8, 0, 1, 2); + + lbLabel = new QLabel(this); + lbLabel->setText(GoogleNotice); + layout->addWidget(lbLabel, 9, 0, 1, 2); + + labelLog = new QLabel(this); + layout->addWidget(labelLog, 10, 0, 1, 2); + + QDialogButtonBox* dbbButtons = new QDialogButtonBox(this); + btnUpload = dbbButtons->addButton(tr("Upload"), QDialogButtonBox::ActionRole); + QPushButton * pbCancel = dbbButtons->addButton(QDialogButtonBox::Cancel); + layout->addWidget(dbbButtons, 11, 0, 1, 2); + + connect(btnUpload, SIGNAL(clicked()), this, SLOT(upload())); + connect(pbCancel, SIGNAL(clicked()), this, SLOT(reject())); +} + +void HWUploadVideoDialog::log(const QString& text) +{ + labelLog->setText(labelLog->text() + text); +} + +void HWUploadVideoDialog::setEditable(bool editable) +{ + leTitle->setEnabled(editable); + leAccount->setEnabled(editable); + lePassword->setEnabled(editable); + btnUpload->setEnabled(editable); +} + +void HWUploadVideoDialog::upload() +{ + setEditable(false); + + labelLog->clear(); + log(tr("Authenticating at www.google.com... ")); + + // Documentation is at https://developers.google.com/youtube/2.0/developers_guide_protocol_clientlogin#ClientLogin_Authentication + QNetworkRequest request; + request.setUrl(QUrl("https://www.google.com/accounts/ClientLogin")); + request.setRawHeader("User-Agent", UserAgent); + request.setRawHeader("Content-Type", "application/x-www-form-urlencoded"); + + QString account(QUrl::toPercentEncoding(leAccount->text())); + QString pass(QUrl::toPercentEncoding(lePassword->text())); + QByteArray data = QString("Email=%1&Passwd=%2&service=youtube&source=Hedgewars").arg(account).arg(pass).toAscii(); + + QNetworkReply *reply = netManager->post(request, data); + connect(reply, SIGNAL(finished()), this, SLOT(authFinished())); +} + +QString XmlEscape(const QString& str) +{ + QString str2 = str; + return "", "]]]]>") + "]]>"; +} + +void HWUploadVideoDialog::authFinished() +{ + QNetworkReply *reply = (QNetworkReply*)sender(); + reply->deleteLater(); + + QByteArray answer = reply->readAll(); + QString authToken = ""; + QList lines = answer.split('\n'); + foreach (const QByteArray& line, lines) + { + QString str(line); + if (!str.startsWith("Auth=", Qt::CaseInsensitive)) + continue; + str.remove(0, 5); + authToken = str; + break; + } + if (authToken.isEmpty()) + { + log(tr("failed\n")); + log(reply->errorString() + "\n"); + setEditable(true); + return; + } + log(tr("Ok\n")); + + log(tr("Sending metadata... ")); + + QByteArray auth = ("GoogleLogin auth=" + authToken).toAscii(); + + // We have authenticated, now we can send metadata and start upload + // Documentation is here: https://developers.google.com/youtube/2.0/developers_guide_protocol_resumable_uploads#Resumable_uploads + QByteArray body = + "" + "" + "" + "" + "Games" + "" + "" + + XmlEscape(leTitle->text()).toUtf8() + + "" + "" + ""; + + QNetworkRequest request; + request.setUrl(QUrl("http://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads")); + request.setRawHeader("User-Agent", UserAgent); + request.setRawHeader("Authorization", auth); + request.setRawHeader("GData-Version", "2"); + request.setRawHeader("X-GData-Key", "key=" + devKey); + request.setRawHeader("Slug", filename.toUtf8()); + request.setRawHeader("Content-Type", "application/atom+xml; charset=UTF-8"); + + reply = netManager->post(request, body); + connect(reply, SIGNAL(finished()), this, SLOT(startUpload())); +} + +void HWUploadVideoDialog::startUpload() +{ + QNetworkReply *reply = (QNetworkReply*)sender(); + reply->deleteLater(); + + location = QString::fromAscii(reply->rawHeader("Location")); + if (location.isEmpty()) + { + log(tr("failed\n")); + log(reply->errorString() + "\n"); + setEditable(true); + return; + } + + log(tr("Ok\n")); + accept(); +} diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/ui/dialog/upload_video.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/ui/dialog/upload_video.h Thu Jul 26 21:58:25 2012 +0400 @@ -0,0 +1,62 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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; version 2 of the License + * + * 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef UPLOAD_VIDEO_H +#define UPLOAD_VIDEO_H + +#include + +class QLineEdit; +class QCheckBox; +class QPlainTextEdit; +class QLabel; +class QNetworkAccessManager; + +class HWUploadVideoDialog : public QDialog +{ + Q_OBJECT + public: + HWUploadVideoDialog(QWidget* parent, const QString& filename, QNetworkAccessManager* netManager); + + QLineEdit* leAccount; + QLineEdit* lePassword; + QCheckBox* cbSave; + + QLineEdit* leTitle; + QPlainTextEdit* teDescription; + + QPushButton* btnUpload; + + QLabel* labelLog; + + QString location; + + private: + QNetworkAccessManager* netManager; + QString filename; + + void log(const QString& text); + void setEditable(bool editable); + + private slots: + void upload(); + void authFinished(); + void startUpload(); +}; + +#endif // UPLOAD_VIDEO_H diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/ui/page/pagevideos.cpp --- a/QTfrontend/ui/page/pagevideos.cpp Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/ui/page/pagevideos.cpp Thu Jul 26 21:58:25 2012 +0400 @@ -39,6 +39,9 @@ #include #include #include +#include +#include +#include #include "hwconsts.h" #include "pagevideos.h" @@ -47,8 +50,9 @@ #include "gameuiconfig.h" #include "recorder.h" #include "ask_quit.h" +#include "upload_video.h" -const QSize ThumbnailSize(350, 350*3/5); +static const QSize ThumbnailSize(350, 350*3/5); // columns in table with list of video files enum VideosColumns @@ -70,7 +74,9 @@ QString name; QString desc; // description + QString uploadReply; HWRecorder * pRecorder; // non NULL if file is being encoded + QNetworkReply * pUploading; // non NULL if file is being uploaded bool seen; // used when updating directory float lastSizeUpdate; float progress; @@ -87,6 +93,7 @@ { this->name = name; pRecorder = NULL; + pUploading = NULL; lastSizeUpdate = 0; progress = 0; } @@ -217,6 +224,7 @@ filesTable->setColumnCount(vcNumColumns); filesTable->setHorizontalHeaderLabels(columns); filesTable->setSelectionBehavior(QAbstractItemView::SelectRows); + filesTable->setSelectionMode(QAbstractItemView::SingleSelection); filesTable->setEditTriggers(QAbstractItemView::SelectedClicked); filesTable->verticalHeader()->hide(); filesTable->setMinimumWidth(400); @@ -272,6 +280,9 @@ btnDelete = new QPushButton(QPushButton::tr("Delete"), pDescGroup); btnDelete->setEnabled(false); pBottomDescLayout->addWidget(btnDelete); + btnToYouTube = new QPushButton(QPushButton::tr("Upload to YouTube"), pDescGroup); + btnToYouTube->setEnabled(false); + pBottomDescLayout->addWidget(btnToYouTube); pDescLayout->addStretch(1); pDescLayout->addLayout(pTopDescLayout, 0); @@ -300,14 +311,16 @@ connect(filesTable, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(currentCellChanged(int,int,int,int))); connect(btnPlay, SIGNAL(clicked()), this, SLOT(playSelectedFile())); connect(btnDelete, SIGNAL(clicked()), this, SLOT(deleteSelectedFiles())); + connect(btnToYouTube, SIGNAL(clicked()), this, SLOT(uploadToYouTube())); connect(btnOpenDir, SIGNAL(clicked()), this, SLOT(openVideosDirectory())); } PageVideos::PageVideos(QWidget* parent) : AbstractPage(parent), - config(0) + config(0), netManager(0) { nameChangedFromCode = false; numRecorders = 0; + numUploads = 0; initPage(); } @@ -521,6 +534,14 @@ numRecorders++; } +void PageVideos::setProgress(int row, VideoItem* item, float value) +{ + QProgressBar * progressBar = (QProgressBar*)filesTable->cellWidget(row, vcProgress); + progressBar->setValue(value*10000); + progressBar->setFormat(QString("%1%").arg(value*100, 0, 'f', 2)); + item->progress = value; +} + void PageVideos::updateProgress(float value) { HWRecorder * pRecorder = (HWRecorder*)sender(); @@ -534,11 +555,7 @@ item->lastSizeUpdate = value; } - // update progress bar - QProgressBar * progressBar = (QProgressBar*)filesTable->cellWidget(row, vcProgress); - progressBar->setValue(value*10000); - progressBar->setFormat(QString("%1%").arg(value*100, 0, 'f', 2)); - item->progress = value; + setProgress(row, item, value); } void PageVideos::encodingFinished(bool success) @@ -674,11 +691,13 @@ clearThumbnail(); btnPlay->setEnabled(false); btnDelete->setEnabled(false); + btnToYouTube->setEnabled(false); return; } btnPlay->setEnabled(item->ready()); btnDelete->setEnabled(true); + btnToYouTube->setEnabled(item->ready()); QString desc = item->name + "\n\n"; QString thumbName = ""; @@ -701,6 +720,8 @@ desc.remove(prefixBegin, prefixEnd + 7 - prefixBegin); thumbName = prefix; } + + desc += item->uploadReply; } else desc += tr("(in progress...)"); @@ -823,12 +844,12 @@ bool PageVideos::tryQuit(HWForm * form) { bool quit = true; - if (numRecorders != 0) + if (numRecorders != 0 || numUploads != 0) { // ask user what to do - abort or wait HWAskQuitDialog * askd = new HWAskQuitDialog(this, form); + askd->deleteLater(); quit = askd->exec(); - delete askd; } if (quit) clearTemp(); @@ -836,6 +857,10 @@ } // returns multi-line string with list of videos in progress +/* it will look like this: +foo.avi (15.21% - encoding) +bar.avi (18.21% - uploading) +*/ QString PageVideos::getVideosInProgress() { QString list = ""; @@ -843,11 +868,17 @@ for (int i = 0; i < count; i++) { VideoItem * item = nameItem(i); + QString process; + if (!item->ready()) + process = tr("encoding"); + else if (item->pUploading) + process = tr("uploading"); + else + continue; float progress = 100*item->progress; if (progress > 99.99) progress = 99.99; // displaying 100% may be confusing - if (!item->ready()) - list += item->name + " (" + QString::number(progress, 'f', 2) + "%)\n"; + list += item->name + " (" + QString::number(progress, 'f', 2) + "% - " + process + ")\n"; } return list; } @@ -880,3 +911,87 @@ addRecorder(pRecorder); } } + +void PageVideos::uploadProgress(qint64 bytesSent, qint64 bytesTotal) +{ + QNetworkReply* reply = (QNetworkReply*)sender(); + + VideoItem * item = NULL; + int row; + int count = filesTable->rowCount(); + // find corresponding item (maybe there is a better wat to implement this?) + for (int i = 0; i < count; i++) + { + item = nameItem(i); + if (item->pUploading == reply) + { + row = i; + break; + } + } + Q_ASSERT(item); + + setProgress(row, item, bytesSent*1.0/bytesTotal); +} + +void PageVideos::uploadFinished() +{ + QNetworkReply* reply = (QNetworkReply*)sender(); + + VideoItem * item = NULL; + int row; + int count = filesTable->rowCount(); + for (int i = 0; i < count; i++) + { + item = nameItem(i); + if (item->pUploading == reply) + { + row = i; + break; + } + } + Q_ASSERT(item); + + item->pUploading = NULL; + QByteArray answer = reply->readAll(); + item->uploadReply = QString::fromUtf8(answer.data()); + // QMessageBox::information(this,"",item->uploadReply,0); + filesTable->setCellWidget(row, vcProgress, NULL); // remove progress bar + numUploads--; +} + +void PageVideos::uploadToYouTube() +{ + int row = filesTable->currentRow(); + VideoItem * item = nameItem(row); + + if (!netManager) + netManager = new QNetworkAccessManager(this); + + HWUploadVideoDialog* dlg = new HWUploadVideoDialog(this, item->name, netManager); + dlg->deleteLater(); + if (!dlg->exec()) + return; + + QNetworkRequest request(QUrl(dlg->location)); + request.setRawHeader("Content-Type", "application/octet-stream"); + + QFile * file = new QFile(item->path(), this); + if (!file->open(QIODevice::ReadOnly)) + return; + + // add progress bar + QProgressBar * progressBar = new QProgressBar(filesTable); + progressBar->setMinimum(0); + progressBar->setMaximum(10000); + progressBar->setValue(0); + // make it different from encoding progress-bar + progressBar->setStyleSheet("* {color: #00ccff; selection-background-color: #00ccff;}" ); + filesTable->setCellWidget(row, vcProgress, progressBar); + + QNetworkReply* reply = netManager->put(request, file); + item->pUploading = reply; + connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64))); + connect(reply, SIGNAL(finished()), this, SLOT(uploadFinished())); + numUploads++; +} diff -r 9bb6abdb5675 -r 01111960a48d QTfrontend/ui/page/pagevideos.h --- a/QTfrontend/ui/page/pagevideos.h Thu Jul 26 21:56:47 2012 +0400 +++ b/QTfrontend/ui/page/pagevideos.h Thu Jul 26 21:58:25 2012 +0400 @@ -20,9 +20,9 @@ #ifndef PAGE_VIDEOS_H #define PAGE_VIDEOS_H -#include #include "AbstractPage.h" +class QNetworkAccessManager; class GameUIConfig; class HWRecorder; class VideoItem; @@ -41,7 +41,6 @@ QCheckBox *checkUseGameRes; QCheckBox *checkRecordAudio; - QString format() { return comboAVFormats->itemData(comboAVFormats->currentIndex()).toString(); } @@ -76,8 +75,10 @@ void updateDescription(); void clearTemp(); void clearThumbnail(); + void setProgress(int row, VideoItem* item, float value); GameUIConfig * config; + QNetworkAccessManager* netManager; // options group QComboBox *comboAVFormats; @@ -90,7 +91,7 @@ QPushButton *btnOpenDir; // description group - QPushButton *btnPlay, *btnDelete; + QPushButton *btnPlay, *btnDelete, *btnToYouTube; QLabel *labelDesc; QLabel *labelThumbnail; @@ -98,7 +99,7 @@ // (in signal cellChanged) bool nameChangedFromCode; - int numRecorders; + int numRecorders, numUploads; private slots: void changeAVFormat(int index); @@ -114,6 +115,9 @@ void deleteSelectedFiles(); void openVideosDirectory(); void updateFileList(const QString & path); + void uploadToYouTube(); + void uploadProgress(qint64 bytesSent, qint64 bytesTotal); + void uploadFinished(); }; #endif // PAGE_VIDEOS_H diff -r 9bb6abdb5675 -r 01111960a48d hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Thu Jul 26 21:56:47 2012 +0400 +++ b/hedgewars/hwengine.pas Thu Jul 26 21:58:25 2012 +0400 @@ -32,6 +32,9 @@ uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler, uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uRandom, uLandTexture, uCollisions, SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted + {$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF} + {$IFDEF SDL13}, uTouch{$ENDIF}{$IFDEF ANDROID}, GLUnit{$ENDIF}, uAILandMarks; + {$IFDEF HWLIBRARY} procedure initEverything(complete:boolean); diff -r 9bb6abdb5675 -r 01111960a48d hedgewars/uGame.pas --- a/hedgewars/uGame.pas Thu Jul 26 21:56:47 2012 +0400 +++ b/hedgewars/uGame.pas Thu Jul 26 21:58:25 2012 +0400 @@ -48,7 +48,7 @@ if (GameType = gmtDemo) then if isSpeed then - Lag:= Lag * 10 + begin i:= RealTicks-SpeedStart; if i < 2000 then Lag:= Lag*5 else if i < 4000 then Lag:= Lag*10 diff -r 9bb6abdb5675 -r 01111960a48d hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Thu Jul 26 21:56:47 2012 +0400 +++ b/hedgewars/uGearsHedgehog.pas Thu Jul 26 21:58:25 2012 +0400 @@ -617,7 +617,6 @@ AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y)); end else - or (GameType = gmtDemo) then begin // Add spawning here... AddRandomness(GameTicks); diff -r 9bb6abdb5675 -r 01111960a48d project_files/hedgewars.pro --- a/project_files/hedgewars.pro Thu Jul 26 21:56:47 2012 +0400 +++ b/project_files/hedgewars.pro Thu Jul 26 21:58:25 2012 +0400 @@ -108,7 +108,8 @@ ../QTfrontend/util/libav_iteraction.h \ ../QTfrontend/ui/page/pagevideos.h \ ../QTfrontend/net/recorder.h \ - ../QTfrontend/ui/dialog/ask_quit.h + ../QTfrontend/ui/dialog/ask_quit.h \ + ../QTfrontend/ui/dialog/upload_video.h SOURCES += ../QTfrontend/model/ammoSchemeModel.cpp \ ../QTfrontend/model/MapModel.cpp \ @@ -194,7 +195,8 @@ ../QTfrontend/util/libav_iteraction.cpp \ ../QTfrontend/ui/page/pagevideos.cpp \ ../QTfrontend/net/recorder.cpp \ - ../QTfrontend/ui/dialog/ask_quit.cpp + ../QTfrontend/ui/dialog/ask_quit.cpp \ + ../QTfrontend/ui/dialog/upload_video.cpp win32 { SOURCES += ../QTfrontend/xfire.cpp