rendered paste body#include "discburner.h"
#include "backupthread.h"
#include "burnimagethread.h"
#include "formatthread.h"
#include <QApplication>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <QCursor>
#include <QDebug>
#include <QMessageBox>
#include <QPainter>
#include <QPaintEngine>
#include <QProcess>
#include <QStyleOptionGraphicsItem>
#include <QSizePolicy>
#include <QFont>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>
#include <QTimer>
#include <QTreeWidgetItem>
#include <KDebug>
#include <KUrl>
#include <KIcon>
#include <KLocalizedString>
#include <KSharedConfig>
#include <KToolInvocation>
#include <KDialog>
#include <KFileDialog>
#include <KColorScheme>
#include <KComboBox>
#include <KConfigDialog>
#include <KGlobalSettings>
#include <KPushButton>
#include <KMessageBox>
#include <kworkspace/kworkspace.h>
#include <solid/block.h>
#include <solid/opticaldrive.h>
#include <solid/opticaldisc.h>
#include <solid/device.h>
#include <solid/devicenotifier.h>
#include <solid/deviceinterface.h>
#include <Plasma/Svg>
#include <Plasma/Theme>
#include <Plasma/Animator>
#include <Plasma/Extender>
#include <Plasma/ExtenderItem>
#include <Plasma/PopupApplet>
#include <Plasma/Label>
#include <Plasma/Slider>
#include <Plasma/PushButton>
#include <Plasma/ToolTipManager>
#include <Plasma/TreeView>
#include <Plasma/CheckBox>
#include <Plasma/ComboBox>
#include <Plasma/IconWidget>
#include <Plasma/Meter>
DiscBurner::DiscBurner(QObject *parent, const QVariantList &args)
: Plasma::PopupApplet(parent, args)
{
m_isEmbedded = false;
m_extenderVisible = true,
m_extenderLayout = 0;
m_actionsLayout = 0;
m_driveCombo = 0;
m_createButton = 0;
m_burnButton = 0;
m_backupButton = 0;
m_copyButton = 0;
m_ripButton = 0;
m_formatButton = 0;
m_meter = 0;
m_tree = 0;
m_animId = -1;
m_alpha = 1;
m_fadeIn = false;
m_appletAnimId = -1;
m_appletAlpha = 1;
m_appletFadeIn = true;
m_jobMaximum = 0;
m_jobProgress = 0;
m_isHovered = false;
m_isBusy = false;
m_firstRun = true;
m_hasAudioProjectLoaded = false;
m_hasVideoProjectLoaded = false;
m_hasDataProjectLoaded = false;
m_textRect = QRectF();
m_remainingMSecs = 0;
m_extenderApplet = 0;
m_newAudioImageMenu = new QMenu(this->widget());
m_newVideoImageMenu = new QMenu(this->widget());
m_newImageMenu = new QMenu(this->widget());
m_newAudioCDImageAction = new KAction(KIcon("media-optical-audio"), i18n("New Audio CD..."), this);
m_newMP3CDImageAction = new KAction(KIcon("media-optical-audio"), i18n("New MP3 CD..."), this);
m_newDataCDImageAction = new KAction(KIcon("media-optical"), i18n("New Data CD..."), this);
m_newVideoCDImageAction = new KAction(KIcon("media-optical-video"), i18n("New Video CD..."), this);
m_newDataDVDImageAction = new KAction(KIcon("media-optical-DVD"), i18n("New Data DVD..."), this);
m_newVideoDVDImageAction = new KAction(KIcon("media-optical-video"), i18n("New Video DVD..."), this);
m_newMixedModeImageAction = new KAction(KIcon("media-optical-audio"), i18n("New Mixed Mode CD..."), this);
m_overlayText = "Drop!";
m_trackDuplicateCount = 0;
setAcceptsHoverEvents(true);
setAcceptDrops(true);
setHasConfigurationInterface(true);
setPopupIcon(QIcon());
resize(150, 150);
setAspectRatioMode(Plasma::Square);
setBackgroundHints(NoBackground);
}
void DiscBurner::init()
{
KConfigGroup cg = config();
m_showOverlayLabel = cg.readEntry("showDropLabel", false);
showDiscBurner(true);
readColors();
setActionState(Idle);
setInteractionState(Waiting);
m_icon = new KIcon("k3b");
m_mainActionsLayout = new QGraphicsGridLayout(this);
m_ejectButton = new Plasma::IconWidget;
m_ejectButton->setIcon("media-eject");
m_ejectButton->setOpacity(0.5);
m_cancelButton = new Plasma::IconWidget;
m_cancelButton->setIcon("dialog-cancel");
m_cancelButton->setVisible(false);
m_meter = new Plasma::Meter;
m_meter->setMeterType(Plasma::Meter::BarMeterVertical);
m_meter->setVisible(false);
m_busyWidget = new Plasma::BusyWidget;
m_busyWidget->setRunning(true);
m_busyWidget->setVisible(false);
m_mainActionsLayout->addItem(m_ejectButton, 0, 2);
m_mainActionsLayout->addItem(m_busyWidget, 1, 2);
m_mainActionsLayout->addItem(m_meter, 0, 0, 3, 1);
m_mainActionsLayout->addItem(m_cancelButton, 2, 2);
m_mainActionsLayout->setColumnPreferredWidth(1, 70);
m_mainActionsLayout->setSpacing(0);
m_font = QApplication::font();
m_font.setWeight(QFont::Bold);
m_boxAlpha = 128;
m_boxHoverAlpha = 192;
m_hasAudioProjectLoaded = false;
m_hasVideoProjectLoaded = false;
m_hasDataProjectLoaded = false;
m_newImageMenu->addAction(m_newAudioCDImageAction);
m_newImageMenu->addAction(m_newVideoCDImageAction);
m_newImageMenu->addAction(m_newVideoDVDImageAction);
m_newImageMenu->addAction(m_newDataCDImageAction);
m_newImageMenu->addAction(m_newDataDVDImageAction);
m_newImageMenu->addAction(m_newMixedModeImageAction);
m_newAudioImageMenu->addAction(m_newAudioCDImageAction);
m_newAudioImageMenu->addAction(m_newMP3CDImageAction);
m_newAudioImageMenu->addAction(m_newMixedModeImageAction);
m_newVideoImageMenu->addAction(m_newVideoCDImageAction);
m_newVideoImageMenu->addAction(m_newVideoDVDImageAction);
m_newVideoImageMenu->addAction(m_newDataCDImageAction);
m_newVideoImageMenu->addAction(m_newDataDVDImageAction);
m_newVideoImageMenu->addAction(m_newMixedModeImageAction);
m_treeModel = new QStandardItemModel;
m_treeModel->setSupportedDragActions(Qt::MoveAction);
m_currentDiscItem = new QStandardItem;
m_currentProjectItem = new QStandardItem;
m_currentProjectItems = new QList<QStandardItem*>;
connect(m_newAudioCDImageAction, SIGNAL(triggered()), this, SLOT(on_newAudioCDImage_clicked()));
connect(m_newVideoCDImageAction, SIGNAL(triggered()), this, SLOT(on_newVideoCDImage_clicked()));
connect(m_newVideoDVDImageAction, SIGNAL(triggered()), this, SLOT(on_newVideoDVDImage_clicked()));
connect(m_newDataCDImageAction, SIGNAL(triggered()), this, SLOT(on_newDataCDImage_clicked()));
connect(m_newDataDVDImageAction, SIGNAL(triggered()), this, SLOT(on_newDataDVDImage_clicked()));
connect(m_newMixedModeImageAction, SIGNAL(triggered()), this, SLOT(on_newMixedModeImage_clicked()));
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(readColors()));
connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), SLOT(readColors()));
connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(const QString&)), this, SLOT(updateDrives()));
connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(const QString&)), this, SLOT(updateDrives()));
//todo: solid tray ejection notification
connect(m_ejectButton, SIGNAL(clicked()), this, SLOT(on_ejectButton_clicked()));
connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(on_cancelButton_clicked()));
Plasma::ToolTipManager::self()->registerWidget(this);
Plasma::ToolTipManager::self()->setContent(this, *m_toolTipData);
if (!m_isEmbedded && !extender()->hasItem("discburnerlist"))
{
Plasma::ExtenderItem *eItem = new Plasma::ExtenderItem(extender());
eItem->setName("discburnerlist");
initExtenderItem(eItem);
}
}
void DiscBurner::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
Q_UNUSED( option );
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);
int iconsize = iconSize();
QPointF iconOrigin = QPointF(contentsRect.left() + (contentsRect.width() - iconsize) / 2, contentsRect.top() + (contentsRect.height() - iconsize) / 2);
QRectF iconRect = QRectF(iconOrigin, QSize(iconsize, iconsize));
QPixmap ico_pix = m_icon->pixmap(QSize(iconsize, iconsize));
QPixmap temp(QSize(iconsize, iconsize));
temp.fill(Qt::transparent);
if (temp.isNull())
return;
QPainter painter;
painter.begin(&temp);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.drawPixmap(QPoint(0,0), ico_pix);
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
painter.end();
p->drawPixmap(iconOrigin, temp);
if (m_isHovered)
{
paintOverlayText(p, contentsRect, m_overlayText);
}
update();
}
void DiscBurner::paintOverlayText(QPainter *p, const QRect &contentsRect, const QString& labelText)
{
int original_font_size = m_font.pointSize();
m_font.setPointSize(qMax(KGlobalSettings::smallestReadableFont().pointSize(), m_font.pointSize()));
QFontMetrics fm(m_font);
qreal text_width = fm.width(labelText);
if (labelText.length() > 4) {
if (original_font_size/1.5 < KGlobalSettings::smallestReadableFont().pointSize()) {
m_font.setPointSize((KGlobalSettings::smallestReadableFont().pointSize()));
}
else {
m_font.setPointSizeF(original_font_size/1.5);
}
fm = QFontMetrics(m_font);
text_width = (fm.width(labelText) * 1.2);
}
else {
text_width = (text_width * 1.4);
}
if (formFactor() == Plasma::Horizontal || formFactor() == Plasma::Vertical) {
m_font = KGlobalSettings::smallestReadableFont();
m_font.setWeight(QFont::Bold);
fm = QFontMetrics(m_font);
text_width = (fm.width(labelText)+8);
}
p->setFont(m_font);
m_textRect = QRectF(qMax(qreal(0.0), contentsRect.left() + (contentsRect.width() - text_width) / 2), contentsRect.top() + ((contentsRect.height() - (int)fm.height()) / 2 * 0.9), qMin(contentsRect.width(), (int)text_width), fm.height() * 1.2 );
m_boxColor.setAlphaF(m_alpha);
p->setPen(m_boxColor);
m_boxColor.setAlphaF(m_alpha*0.5);
p->setBrush(m_boxColor);
float round_prop = m_textRect.width() / m_textRect.height();
qreal round_radius = 35.0;
p->drawRoundedRect(m_textRect, round_radius / round_prop, round_radius, Qt::RelativeSize);
m_textColor.setAlphaF(m_alpha);
p->setPen(m_textColor);
p->drawText(m_textRect, Qt::AlignCenter, labelText);
m_font.setPointSize(original_font_size);
m_boxColor.setAlpha(m_boxAlpha);
}
void DiscBurner::constraintsEvent(Plasma::Constraints constraints)
{
int minWidth;
int minHeight;
if (constraints & (Plasma::FormFactorConstraint | Plasma::SizeConstraint)) {
if (formFactor() == Plasma::Vertical) {
minHeight = qMax(m_textRect.height(), size().width());
setMinimumWidth(0);
setMinimumHeight(minHeight);
}
else if (formFactor() == Plasma::Horizontal) {
minWidth = qMax(m_textRect.width(), size().height());
setMinimumWidth(minWidth);
setMinimumHeight(0);
}
else {
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
setMinimumSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
}
m_font.setPointSize(qMax(KGlobalSettings::smallestReadableFont().pointSize(), qRound(contentsRect().height() / 10)));
update();
}
}
void DiscBurner::readColors()
{
m_textColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
m_boxColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
}
void DiscBurner::showAppletLabel(bool show)
{
if (show != m_showOverlayLabel) {
showOverlayText(show);
m_showOverlayLabel = show;
}
}
void DiscBurner::showOverlayText(bool show)
{
if (m_fadeIn == show) {
return;
}
m_fadeIn = show;
const int FadeInDuration = 150;
if (m_animId != -1) {
Plasma::Animator::self()->stopCustomAnimation(m_animId);
}
m_animId = Plasma::Animator::self()->customAnimation(40 / (1000 / FadeInDuration), FadeInDuration, Plasma::Animator::EaseOutCurve, this, "animationUpdate");
}
void DiscBurner::showDiscBurner(bool show)
{
if (m_appletFadeIn == show) {
return;
}
m_appletFadeIn = show;
const int FadeInDuration = 300;
if (m_appletAnimId != -1) {
Plasma::Animator::self()->stopCustomAnimation(m_appletAnimId);
}
m_appletAnimId = Plasma::Animator::self()->customAnimation(40 / (1000 / FadeInDuration), FadeInDuration, Plasma::Animator::EaseOutCurve, this, "discburnerAnimationUpdate");
}
void DiscBurner::animationUpdate(qreal progress)
{
if (progress == 1) {
m_animId = -1;
}
if (!m_fadeIn) {
qreal new_alpha = m_fadeIn ? progress : 1 - progress;
m_alpha = qMin(new_alpha, m_alpha);
}
else {
m_alpha = m_fadeIn ? progress : 1 - progress;
}
m_alpha = qMax(qreal(0.0), m_alpha);
update();
}
void DiscBurner::appletAnimationUpdate(qreal progress)
{
if (progress == 1) {
m_appletAnimId = -1;
}
m_appletAlpha = m_appletFadeIn ? progress : 1 - progress;
update();
}
int DiscBurner::iconSize()
{
int c = qMin(contentsRect().width(), contentsRect().height());
int s;
if (c >= KIconLoader::SizeEnormous) { // 128
s = KIconLoader::SizeEnormous;
}
else if (c >= KIconLoader::SizeHuge) { // 64
s = KIconLoader::SizeHuge;
}
else if (c >= KIconLoader::SizeLarge) { // 48
s = KIconLoader::SizeLarge;
}
else if (c >= KIconLoader::SizeMedium) { // 32
s = KIconLoader::SizeMedium;
}
else if (c >= KIconLoader::SizeSmallMedium) { // 32
s = KIconLoader::SizeSmallMedium;
}
else { // 16
s = KIconLoader::SizeSmall;
}
return s;
}
void DiscBurner::setInteractionState(InteractionState state)
{
m_interactionState = state;
}
void DiscBurner::setActionState(ActionState state)
{
m_toolTipData = new Plasma::ToolTipContent();
m_toolTipData->setAutohide(true);
m_toolTipData->setMainText("DiscBurner");
if (!m_toolTipData)
return;
switch (state ) {
case Unset:
m_toolTipData->setSubText(i18nc("The status of the applet has not been set - i.e. it is unset.", "Unset"));
m_toolTipData->setImage(KIcon("media-optical-recordable"));
break;
case Idle:
setBusy(false);
m_toolTipData->setSubText(i18n("Drop files on me to create a disc."));
m_toolTipData->setImage(KIcon("media-optical-recordable"));
break;
case IdleError:
setBusy(false);
m_toolTipData->setSubText(i18n("Error. Sorry =["));
m_toolTipData->setImage(KIcon("dialog-cancel"));
QTimer::singleShot(10000, this, SLOT(resetActionState()));
break;
case IdleSuccess:
setBusy(false);
m_toolTipData->setSubText(i18n("Success!"));
m_toolTipData->setImage(KIcon("dialog-ok"));
QTimer::singleShot(10000, this, SLOT(resetActionState()));
break;
case Burning:
setBusy(true);
m_toolTipData->setSubText(i18n("Burning...."));
m_toolTipData->setImage(KIcon("tools-media-optical-burn"));
break;
case Formatting:
setBusy(true);
m_toolTipData->setSubText(i18n("Formatting...."));
m_toolTipData->setImage(KIcon("tools-media-optical-erase"));
break;
case Reading:
setBusy(true);
m_toolTipData->setSubText(i18n("Reading...."));
m_toolTipData->setImage(KIcon("tools-media-optical-burn-image"));
break;
default:
break;
}
Plasma::ToolTipManager::self()->setContent(this, *m_toolTipData);
m_actionState = state;
update();
}
void DiscBurner::createConfigurationInterface(KConfigDialog *parent)
{
QWidget *widget = new QWidget(parent);
ui.setupUi(widget);
parent->addPage(widget, i18n("General"), Applet::icon());
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
// ui.showDropLabelCheckBox->setChecked(m_showDropLabel ? Qt::Checked : Qt::Unchecked);
}
void DiscBurner::configAccepted()
{
KConfigGroup cg = config();
if (m_showOverlayLabel != ui.showDropLabelCheckBox->isChecked()) {
m_showOverlayLabel = !m_showOverlayLabel;
cg.writeEntry("showDropLabel", m_showOverlayLabel);
if (m_showOverlayLabel && m_showOverlayLabel == ui.showDropLabelCheckBox->isChecked()) {
showOverlayText(m_showOverlayLabel);
}
}
emit configNeedsSaving();
}
void DiscBurner::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
setInteractionState(Hovered);
showOverlayText(true);
m_isHovered = true;
Applet::hoverEnterEvent(event);
}
void DiscBurner::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
setInteractionState(Waiting);
if (!m_showOverlayLabel && !m_isEmbedded) {
showOverlayText(false);
m_isHovered = false;
}
Applet::hoverLeaveEvent(event);
}
DiscBurner::~DiscBurner()
{
KConfigGroup cg = config();
// cg.writeEntry("Config Option Name", variant);
}
void DiscBurner::setupConnections()
{
}
void DiscBurner::setEmbedded(const bool embedded)
{
m_isEmbedded = embedded;
}
void DiscBurner::setBusy(bool busy)
{
if(busy) {
m_overlayText = "Busy...";
}
else {
m_overlayText = "Drop!";
}
m_isBusy = busy;
}
void DiscBurner::initExtenderItem(Plasma::ExtenderItem *item)
{
if (!m_isEmbedded && item->name() == "discburnerlist") {
QGraphicsWidget *burnlist = new QGraphicsWidget(item);
burnlist->setMinimumSize(350, 250);
m_extenderLayout = new QGraphicsLinearLayout(burnlist);
m_extenderLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_extenderLayout->setOrientation(Qt::Vertical);
m_actionsLayout = new QGraphicsGridLayout(m_extenderLayout);
m_actionsLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_driveCombo = new Plasma::ComboBox(burnlist);
m_driveCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_extenderLayout->addItem(m_driveCombo);
m_tree = new Plasma::TreeView(burnlist);
m_tree->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_tree->nativeWidget()->setHeaderHidden(true);
m_tree->nativeWidget()->setDragDropMode(QAbstractItemView::InternalMove);
m_tree->nativeWidget()->setSelectionMode(QAbstractItemView::SingleSelection);
m_tree->nativeWidget()->setAnimated(true);
m_tree->nativeWidget()->viewport()->setAcceptDrops(true);
m_tree->setAcceptHoverEvents(true);
m_tree->setAcceptDrops(true);
m_tree->setModel(m_treeModel);
updateDrives();
m_extenderLayout->addItem(m_tree);
m_createButton = new Plasma::IconWidget(burnlist);
m_createButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_createButton->setIcon("media-optical");
m_createButton->setOrientation(Qt::Horizontal);
m_createButton->setDrawBackground(true);
m_createButton->setTextBackgroundColor(QColor());
m_createButton->setText(i18n("Create"));
m_createButton->setMaximumHeight(36);
m_actionsLayout->addItem(m_createButton, 0, 0);
m_burnButton = new Plasma::IconWidget(burnlist);
m_burnButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_burnButton->setIcon("tools-media-optical-burn");
m_burnButton->setOrientation(Qt::Horizontal);
m_burnButton->setDrawBackground(true);
m_burnButton->setTextBackgroundColor(QColor());
m_burnButton->setText(i18n("Burn"));
m_burnButton->setMaximumHeight(36);
m_actionsLayout->addItem(m_burnButton, 0, 1);
m_backupButton = new Plasma::IconWidget(burnlist);
m_backupButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_backupButton->setIcon("tools-media-optical-burn-image");
m_backupButton->setOrientation(Qt::Horizontal);
m_backupButton->setDrawBackground(true);
m_backupButton->setTextBackgroundColor(QColor());
m_backupButton->setText(i18n("Backup"));
m_backupButton->setMaximumHeight(36);
m_actionsLayout->addItem(m_backupButton, 0, 2);
m_copyButton = new Plasma::IconWidget(burnlist);
m_copyButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_copyButton->setIcon("tools-media-optical-copy");
m_copyButton->setOrientation(Qt::Horizontal);
m_copyButton->setDrawBackground(true);
m_copyButton->setTextBackgroundColor(QColor());
m_copyButton->setText(i18n("Copy"));
m_copyButton->setMaximumHeight(36);
m_actionsLayout->addItem(m_copyButton, 1, 0);
m_ripButton = new Plasma::IconWidget(burnlist);
m_ripButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_ripButton->setIcon("media-optical-audio");
m_ripButton->setOrientation(Qt::Horizontal);
m_ripButton->setDrawBackground(true);
m_ripButton->setTextBackgroundColor(QColor());
m_ripButton->setText(i18n("Rip"));
m_ripButton->setMaximumHeight(36);
m_actionsLayout->addItem(m_ripButton, 1, 1);
m_formatButton = new Plasma::IconWidget(burnlist);
m_formatButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_formatButton->setIcon("tools-media-optical-format");
m_formatButton->setOrientation(Qt::Horizontal);
m_formatButton->setDrawBackground(true);
m_formatButton->setTextBackgroundColor(QColor());
m_formatButton->setText(i18n("Format"));
m_formatButton->setMaximumHeight(36);
m_actionsLayout->addItem(m_formatButton, 1, 2);
m_extenderLayout->addItem(m_actionsLayout);
burnlist->setLayout(m_extenderLayout);
connect(m_createButton, SIGNAL(clicked()), this, SLOT(on_createButton_clicked()));
connect(m_burnButton, SIGNAL(clicked()), this, SLOT(on_burnButton_clicked()));
connect(m_backupButton, SIGNAL(clicked()), this, SLOT(on_backupButton_clicked()));
connect(m_copyButton, SIGNAL(clicked()), this, SLOT(on_copyButton_clicked()));
connect(m_ripButton, SIGNAL(clicked()), this, SLOT(on_ripButton_clicked()));
connect(m_formatButton, SIGNAL(clicked()), this, SLOT(on_formatButton_clicked()));
DiscBurner *m_extenderApplet = static_cast<DiscBurner*>(Plasma::Applet::load("discburner"));
if (m_extenderApplet) {
m_extenderApplet->setParent(this);
m_extenderApplet->setAcceptsHoverEvents(false);
m_extenderApplet->setParentItem(burnlist);
m_extenderApplet->setEmbedded(true);
m_extenderApplet->setMinimumSize(80, 80);
m_extenderApplet->resize(80, 80);
m_extenderApplet->setBackgroundHints(NoBackground);
m_extenderApplet->setFlag(QGraphicsItem::ItemIsMovable, false);
m_extenderApplet->init();
m_extenderApplet->updateConstraints(Plasma::StartupCompletedConstraint);
}
burnlist->setLayout(m_extenderLayout);
item->setIcon("tools-media-optical-burn");
item->setWidget(burnlist);
item->setTitle(i18n("DiscBurner"));
}
}
void DiscBurner::resetActionState()
{
setActionState(Idle);
update();
}
void DiscBurner::popupEvent(bool show)
{
m_extenderVisible = show;
updateStatus();
}
void DiscBurner::updateStatus()
{
if (!m_extenderVisible) {
return;
}
}
void DiscBurner::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
InteractionState istate = Rejected;
if (event->mimeData()->hasFormat("text/plain")) {
event->acceptProposedAction();
}
if (event->mimeData()->hasText()) {
istate = DraggedOver;
}
setInteractionState(istate);
showOverlayText(true);
m_isHovered = true;
Applet::dragEnterEvent(event);
}
void DiscBurner::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
{
setInteractionState(Waiting);
if (!m_showOverlayLabel && !m_isEmbedded) {
showOverlayText(false);
m_isHovered = false;
}
event->accept();
}
void DiscBurner::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
event->accept();
}
void DiscBurner::dropEvent(QGraphicsSceneDragDropEvent *event)
{
if (event->mimeData()->objectName() != QString("discburner-applet")) {
QList<QUrl> dropped_paths = event->mimeData()->urls();
kDebug() << dropped_paths;
foreach (QUrl path, dropped_paths)
{
QString s_path = path.toString().right(path.toString().length() - 7);
kDebug() << s_path;
if (s_path.right(3).toLower() == "mp3" || s_path.right(3).toLower() == "wav" || s_path.right(3).toLower() == "ogg") {
if(m_hasAudioProjectLoaded) {
addSong(s_path);
}
else {
m_newAudioImageMenu->exec(event->screenPos());
}
}
else if (s_path.right(3) == "mpg" || s_path.right(3) == "avi") {
if(m_hasVideoProjectLoaded) {
//addVideo(s_path);
}
else {
m_newVideoImageMenu->exec(event->screenPos());
}
}
else if (s_path.right(3).toLower() == "iso") {
burnIso(s_path);
}
else if (QDir(s_path).exists())
{
kDebug() << "folder dropped";
}
else {
if(m_hasDataProjectLoaded) {
// addFile(s_path);
}
else if(m_hasAudioProjectLoaded) {
}
else if (m_hasVideoProjectLoaded) {
}
else {
m_newImageMenu->exec(event->screenPos());
}
}
}
event->acceptProposedAction();
}
}
void DiscBurner::updateDrives()
{
m_devicesHash.clear();
foreach (const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::OpticalDrive, QString())) {
const Solid::Block *block_device = device.as<Solid::Block>();
m_currentDriveUdi = device.udi();
foreach (const Solid::Device &disc_dev, Solid::Device::listFromType(Solid::DeviceInterface::OpticalDisc, QString())) {
m_currentDiscUdi = disc_dev.udi();
m_currentDiscContentType = disc_dev.as<Solid::OpticalDisc>()->availableContent();
m_currentDiscUsage = QString::number((disc_dev.as<Solid::OpticalDisc>()->size() / 1024) / 1024) + " MB";
m_currentDiscCapacity = QString::number((disc_dev.as<Solid::OpticalDisc>()->capacity() / 1024) / 1024) + " MB";
m_currentDiscLabel = disc_dev.as<Solid::StorageVolume>()->label();
if (m_currentDiscContentType== Solid::OpticalDisc::Audio) {
m_icon = new KIcon("media-optical-audio");
m_currentDiscContentTypeString = "Audio Disc";
}
else if (m_currentDiscContentType== Solid::OpticalDisc::Data) {
m_icon = new KIcon("media-optical");
m_currentDiscContentTypeString = "Data Disc";
}
else if (disc_dev.as<Solid::OpticalDisc>()->isBlank()) {
m_icon = new KIcon("media-optical-recordable");
m_currentDiscContentTypeString = "Blank Disc";
}
else {
m_icon = new KIcon("media-optical-video");
m_currentDiscContentTypeString = "Video Disc";
}
}
m_devicesHash.insert(block_device->device(), device.product());
}
m_driveCombo->nativeWidget()->clear();
foreach(QString value, m_devicesHash) {
m_driveCombo->nativeWidget()->addItem(KIcon("drive-optical"), value);
}
if (m_devicesHash.isEmpty())
m_driveCombo->nativeWidget()->addItem(KIcon("drive-optical"), "No Devices Found");
updateCurrentDisc();
update();
}
void DiscBurner::on_createButton_clicked()
{
m_newImageMenu->exec(QCursor::pos());
}
void DiscBurner::on_burnButton_clicked()
{
if(m_hasAudioProjectLoaded)
{
}
else if (m_hasDataProjectLoaded)
{
}
else if (m_hasVideoProjectLoaded)
{
}
else if (m_currentDiscContentTypeString == "Blank Disc")
{
QString filename = KFileDialog::getOpenFileName(KUrl(QDir::homePath()), "*.iso|ISO9660 Image Files (*.iso)\n*.bin|Binary Image Files (*.bin)\n*.toc|Table of Contents Files (*.toc)\n*.nrg|Nero Image Files (*.nrg)\n*.cue|CloneImage Files (*.cue)", this->widget(), "Select Image File");
burnIso(filename);
}
}
void DiscBurner::on_backupButton_clicked()
{
if (m_currentDiscContentTypeString == "Blank Disc") {
QMessageBox::critical(this->widget(), "Error", "Can't backup a blank disc.");
return;
}
KUrl url ( QDir::homePath() );
QProcess p(0);
QString dev;
QString fileName;
if (m_currentDiscContentType== Solid::OpticalDisc::Audio) {
if(QMessageBox::question(this->widget(), "Really create .bin?", "Audio CDs are not ISO filesystems. They should be decoded into .ogg/.mp3. Continue creating .bin/.toc files? [FOR ADVANCED USERS]", QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel) == QMessageBox::Yes) {
fileName = KFileDialog::getSaveFileName(url, "BIN Files (*.bin)", this->widget(), "Save BIN file");
}
else {
return;
}
}
else {
fileName = KFileDialog::getSaveFileName(url, "ISO Files (*.iso)", this->widget(), "Save ISO file");
}
QHashIterator<QString, QString> i(m_devicesHash);
while (i.hasNext()) {
i.next();
if (i.value() == m_driveCombo->text()) {
dev = i.key();
}
}
if (!dev.isEmpty()) {
setActionState(Reading);
m_cancelButton->setVisible(true);
m_busyWidget->setVisible(true);
m_meter->setVisible(true);
BackupThread *backup = new BackupThread(this->widget(), dev, fileName, m_currentDiscUdi, m_currentDiscContentType);
connect(backup, SIGNAL(discCapacity(int)), this, SLOT(setJobMaximum(int)));
connect(backup, SIGNAL(progressMonitor(int)), this, SLOT(setJobProgress(int)));
connect(backup, SIGNAL(finished()), this, SLOT(jobCompleted()));
connect(this, SIGNAL(cancelProcesses()), backup, SLOT(cancelProcess()));
backup->run();
update();
}
}
void DiscBurner::on_copyButton_clicked()
{
}
void DiscBurner::on_ripButton_clicked()
{
}
void DiscBurner::on_formatButton_clicked()
{
if (m_currentDiscContentTypeString == "Blank Disc") {
if(QMessageBox::question(this->widget(), "Disc Already Blank", "This disc appears to already be blank. Format it again anyway?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
return;
}
}
QHashIterator<QString, QString> i(m_devicesHash);
QString dev;
while (i.hasNext()) {
i.next();
if (i.value() == m_driveCombo->text()) {
dev = i.key();
}
}
if (!dev.isEmpty()) {
this->hidePopup();
m_cancelButton->setVisible(false);
m_busyWidget->setVisible(true);
setActionState(Formatting);
FormatThread *formatter = new FormatThread(this->widget(), dev, m_currentDiscUdi);
connect(formatter, SIGNAL(finished()), this, SLOT(jobCompleted()));
connect(this, SIGNAL(cancelProcesses()), formatter, SLOT(cancelProcess()));
formatter->run();
update();
}
}
void DiscBurner::setJobMaximum(int max)
{
m_jobMaximum = max;
}
void DiscBurner::setJobProgress(int progress)
{
m_toolTipData = new Plasma::ToolTipContent();
m_toolTipData->setAutohide(true);
m_toolTipData->setMainText("DiscBurner");
m_jobProgress = progress;
if(m_jobMaximum > 0 && m_jobProgress > 0 && m_jobProgress < 100) {
m_currentProgress = (m_jobProgress * 100) / m_jobMaximum;
if (m_currentProgress == 0 || m_currentProgress == 100) {
qDebug() << "currentProgress=" << m_currentProgress;
qDebug() << "jobProgress=" << m_jobProgress;
qDebug() << "jobMaximum=" << m_jobMaximum;
}
}
if ((m_currentProgress > 100))
return;
if (m_actionState == Reading) {
m_toolTipData->setSubText("Creating backup...<br>" + QString::number(m_currentProgress) + "% Complete");
}
else if (m_actionState == Burning) {
if (m_currentProgress == 0) {
m_toolTipData->setSubText("Burning...<br>Caching Data");
}
else if (m_currentProgress == 100) {
m_toolTipData->setSubText("Burning...<br>Finalizing Media");
}
else {
m_toolTipData->setSubText("Burning...<br>" + QString::number(m_currentProgress) + "% Complete");
}
}
else if (m_actionState == Formatting) {
m_toolTipData->setSubText("Formatting...");
}
Plasma::ToolTipManager::self()->setContent(this, *m_toolTipData);
m_meter->setMaximum(100);
m_meter->setValue(m_currentProgress);
update();
}
void DiscBurner::jobCompleted()
{
m_jobProgress = m_jobMaximum;
m_currentProgress = 100;
setActionState(IdleSuccess);
setBusy(false);
m_cancelButton->setVisible(false);
m_busyWidget->setVisible(false);
m_meter->setVisible(false);
on_ejectButton_clicked();
update();
}
void DiscBurner::burnIso(QString url)
{
QString dev;
QHashIterator<QString, QString> i(m_devicesHash);
while (i.hasNext()) {
i.next();
if (i.value() == m_driveCombo->text()) {
dev = i.key();
}
}
if (!dev.isEmpty()) {
m_cancelButton->setVisible(true);
m_busyWidget->setVisible(true);
m_meter->setVisible(true);
setActionState(Burning);
BurnImageThread *burner = new BurnImageThread(this, dev, url, m_currentDiscUdi);
connect(burner, SIGNAL(discCapacity(int)), this, SLOT(setJobMaximum(int)));
connect(burner, SIGNAL(progressMonitor(int)), this, SLOT(setJobProgress(int)));
connect(burner, SIGNAL(finished()), this, SLOT(jobCompleted()));
connect(this, SIGNAL(cancelProcesses()), burner, SLOT(cancelProcess()));
burner->run();
}
}
void DiscBurner::updateCurrentDisc()
{
if (m_currentDiscUdi.isEmpty() || m_currentDiscUdi.isNull())
return;
m_tree->nativeWidget()->setIconSize(QSize(24,24));
m_currentDiscItem->setIcon(*m_icon);
m_currentDiscItem->setText(m_currentDiscContentTypeString + " " + m_currentDiscUsage + "/" + m_currentDiscCapacity + "\n" + m_currentDiscLabel);
m_currentDiscItem->setSizeHint(QSize(500,50));
m_currentDiscItem->setDropEnabled(false);
m_currentDiscItem->setDragEnabled(false);
m_currentDiscItem->setEditable(false);
if(!m_treeModel->itemFromIndex(m_currentDiscItem->index()))
{
m_treeModel->appendRow(m_currentDiscItem);
m_treeModel->setSupportedDragActions(Qt::MoveAction);
}
}
void DiscBurner::on_ejectButton_clicked()
{
// Solid::Device current_drive = Solid::Device::Device(m_currentDriveUdi);
// current_drive.as<Solid::OpticalDrive>()->eject();
QProcess::startDetached("eject -T");
updateDrives();
}
void DiscBurner::on_cancelButton_clicked()
{
emit cancelProcesses();
}
void DiscBurner::on_newAudioCDImage_clicked()
{
if(m_hasAudioProjectLoaded)
return;
m_currentProjectItem->setIcon(KIcon("folder-sound"));
m_currentProjectItem->setText("Audio Disc");
m_currentProjectItem->setToolTip("Double-Click to change disc label");
m_currentProjectItem->setEditable(true);
m_currentProjectItem->setEnabled(true);
m_currentProjectItem->setSelectable(false);
m_currentProjectItem->setDropEnabled(true);
m_currentProjectItem->setDragEnabled(false);
m_currentProjectItem->setSizeHint(QSize(500,32));
m_currentDiscItem->appendRow(m_currentProjectItem);
m_tree->nativeWidget()->expand(m_currentDiscItem->index());
m_tree->nativeWidget()->setIndentation(10);
m_tree->installEventFilter(this);
m_hasAudioProjectLoaded = true;
}
void DiscBurner::on_newVideoCDImage_clicked()
{
}
void DiscBurner::on_newVideoDVDImage_clicked()
{
}
void DiscBurner::on_newDataCDImage_clicked()
{
}
void DiscBurner::on_newDataDVDImage_clicked()
{
}
void DiscBurner::on_newMixedModeImage_clicked()
{
}
void DiscBurner::addSong(QString url)
{
QStandardItem *song = new QStandardItem;
QStandardItem *songFileName = new QStandardItem;
QStandardItem *songSize = new QStandardItem;
QStandardItem *songLength = new QStandardItem;
QStandardItem *songArtist = new QStandardItem;
QStandardItem *songTitle = new QStandardItem;
song->setText(QFileInfo(url).baseName());
song->setSizeHint(QSize(500,28));
song->setIcon(KIcon("audio-x-generic"));
m_currentProjectItem->appendRow(song);
m_tree->nativeWidget()->expand(m_currentProjectItem->index());
songFileName->setText("Filename: " + url);
songFileName->setToolTip(url);
m_tagFileRef = TagLib::FileRef(url.toAscii().data());
m_tagFileTags = m_tagFileRef.tag();
m_tagFileProperties = m_tagFileRef.audioProperties();
songLength->setText("Length: " + QString::number(m_tagFileProperties->length()));
songLength->setEditable(false);
songArtist->setText("Artist: " + TStringToQString(m_tagFileTags->artist()));
songTitle->setText("Title: " + TStringToQString(m_tagFileTags->title()));
songSize->setText("Size: " + QString::number(QFileInfo(url).size() / 1024 / 1024) + " MB");
songSize->setEditable(false);
song->appendRow(songArtist);
song->appendRow(songTitle);
song->appendRow(songLength);
song->appendRow(songFileName);
song->appendRow(songSize);
song->setDragEnabled(true);
song->setDropEnabled(false);
song->setEnabled(true);
song->setSelectable(true);
m_currentProjectItems->append(song);
}
bool DiscBurner::eventFilter(QObject *obj, QEvent *event)
{
if (qobject_cast< Plasma::TreeView* >(obj))
{
if (event->type() == QEvent::GraphicsSceneDrop)
{
int i = 0;
while(i < m_currentProjectItem->rowCount())
{
kDebug() << m_currentProjectItem->child(i)->text();
m_currentProjectItem->child(i)->setEnabled(true);
m_currentProjectItem->child(i)->setSelectable(true);
m_currentProjectItem->child(i)->setIcon(KIcon("audio-x-generic"));
kDebug() << "woot!";
i++;
kDebug() << i;
}
}
else
{
return QObject::eventFilter(obj, event);
}
}
else
{
return QObject::eventFilter(obj, event);
}
return QObject::eventFilter(obj, event);
}
#include "discburner.moc"