diff --git a/plugins/cffadaptor/src/UBCFFAdaptor.cpp b/plugins/cffadaptor/src/UBCFFAdaptor.cpp index 7de215dc..431c46e8 100644 --- a/plugins/cffadaptor/src/UBCFFAdaptor.cpp +++ b/plugins/cffadaptor/src/UBCFFAdaptor.cpp @@ -3,24 +3,24 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ + #include "UBCFFAdaptor.h" #include diff --git a/plugins/cffadaptor/src/UBCFFAdaptor.h b/plugins/cffadaptor/src/UBCFFAdaptor.h index da14d40d..93eb6166 100644 --- a/plugins/cffadaptor/src/UBCFFAdaptor.h +++ b/plugins/cffadaptor/src/UBCFFAdaptor.h @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ diff --git a/plugins/cffadaptor/src/UBCFFAdaptor_global.h b/plugins/cffadaptor/src/UBCFFAdaptor_global.h index cb21a4a6..182a649a 100644 --- a/plugins/cffadaptor/src/UBCFFAdaptor_global.h +++ b/plugins/cffadaptor/src/UBCFFAdaptor_global.h @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ diff --git a/plugins/cffadaptor/src/UBCFFConstants.h b/plugins/cffadaptor/src/UBCFFConstants.h index 8968fdae..7d03d55f 100644 --- a/plugins/cffadaptor/src/UBCFFConstants.h +++ b/plugins/cffadaptor/src/UBCFFConstants.h @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ diff --git a/plugins/cffadaptor/src/UBGlobals.h b/plugins/cffadaptor/src/UBGlobals.h index 46c39405..309004c2 100644 --- a/plugins/cffadaptor/src/UBGlobals.h +++ b/plugins/cffadaptor/src/UBGlobals.h @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ diff --git a/src/adaptors/UBCFFSubsetAdaptor.cpp b/src/adaptors/UBCFFSubsetAdaptor.cpp index 565b7ea4..6f26472d 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.cpp +++ b/src/adaptors/UBCFFSubsetAdaptor.cpp @@ -19,1531 +19,1531 @@ * along with Open-Sankoré. If not, see . */ - - -#include -#include -#include -#include -#include - -#include "core/UBPersistenceManager.h" - -#include "document/UBDocumentProxy.h" - -#include "domain/UBItem.h" -#include "domain/UBGraphicsPolygonItem.h" -#include "domain/UBGraphicsStroke.h" -#include "domain/UBGraphicsTextItem.h" -#include "domain/UBGraphicsSvgItem.h" -#include "domain/UBGraphicsPixmapItem.h" -#include "domain/UBGraphicsMediaItem.h" -#include "domain/UBGraphicsWidgetItem.h" -#include "domain/UBGraphicsTextItem.h" -#include "domain/UBGraphicsTextItemDelegate.h" -#include "domain/UBGraphicsWidgetItem.h" -#include "domain/UBGraphicsGroupContainerItem.h" - -#include "frameworks/UBFileSystemUtils.h" - -#include "UBCFFSubsetAdaptor.h" -#include "UBMetadataDcSubsetAdaptor.h" -#include "UBThumbnailAdaptor.h" -#include "UBSvgSubsetAdaptor.h" - -#include "core/UBApplication.h" -#include "QFile" - -#include "core/memcheck.h" -//#include "qtlogger.h" - -//tag names definition. Use them everiwhere! -static QString tElement = "element"; -static QString tGroup = "group"; -static QString tEllipse = "ellipse"; -static QString tIwb = "iwb"; -static QString tMeta = "meta"; -static QString tPage = "page"; -static QString tPageset = "pageset"; -static QString tG = "g"; -static QString tSwitch = "switch"; -static QString tPolygon = "polygon"; -static QString tPolyline = "polyline"; -static QString tRect = "rect"; -static QString tSvg = "svg"; -static QString tText = "text"; -static QString tTextarea = "textarea"; -static QString tTspan = "tspan"; -static QString tBreak = "tbreak"; -static QString tImage = "image"; -static QString tFlash = "flash"; -static QString tAudio = "a"; -static QString tVideo = "video"; - -//attribute names definition -static QString aFill = "fill"; -static QString aFillopacity = "fill-opacity"; -static QString aX = "x"; -static QString aY = "y"; -static QString aWidth = "width"; -static QString aHeight = "height"; -static QString aStroke = "stroke"; -static QString aStrokewidth = "stroke-width"; -static QString aCx = "cx"; -static QString aCy = "cy"; -static QString aRx = "rx"; -static QString aRy = "ry"; -static QString aTransform = "transform"; -static QString aViewbox = "viewbox"; -static QString aFontSize = "font-size"; -static QString aFontfamily = "font-family"; -static QString aFontstretch = "font-stretch"; -static QString aFontstyle = "font-style"; -static QString aFontweight = "font-weight"; -static QString aTextalign = "text-align"; -static QString aPoints = "points"; -static QString svgNS = "http://www.w3.org/2000/svg"; -static QString iwbNS = "http://www.imsglobal.org/xsd/iwb_v1p0"; -static QString aId = "id"; -static QString aRef = "ref"; -static QString aHref = "href"; -static QString aBackground = "background"; -static QString aLocked = "locked"; -static QString aEditable = "editable"; - -//attributes part names -static QString apRotate = "rotate"; -static QString apTranslate = "translate"; - - -UBCFFSubsetAdaptor::UBCFFSubsetAdaptor() -{} - -bool UBCFFSubsetAdaptor::ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentProxy* pDocument) -{ - //TODO - // fill document proxy metadata - // create persistance manager to save data using proxy - // create UBCFFSubsetReader and make it parse cffSourceFolder - QFile file(cffSourceFile); - - if (!file.open(QIODevice::ReadOnly)) - { - qWarning() << "Cannot open file " << cffSourceFile << " for reading ..."; - return false; - } - - UBCFFSubsetReader cffReader(pDocument, &file); - bool result = cffReader.parse(); - file.close(); - - return result; -} -UBCFFSubsetAdaptor::UBCFFSubsetReader::UBCFFSubsetReader(UBDocumentProxy *proxy, QFile *content) - : mProxy(proxy) - , mGSectionContainer(NULL) -{ - int errorLine, errorColumn; - QString errorStr; - if(!mDOMdoc.setContent(content, true, &errorStr, &errorLine, &errorColumn)){ - qWarning() << "Error:Parseerroratline" << errorLine << "," - << "column" << errorColumn << ":" << errorStr; - } else { - qDebug() << "well parsed to DOM"; - pwdContent = QFileInfo(content->fileName()).dir().absolutePath(); - } - qDebug() << "tmp path is" << pwdContent; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parse() -{ - UBMetadataDcSubsetAdaptor::persist(mProxy); - - mIndent = ""; - if (!getTempFileName() || !createTempFlashPath()) - return false; - - if (mDOMdoc.isNull()) - return false; - - bool result = parseDoc(); - if (result) - result = mProxy->pageCount() != 0; - - if (QFile::exists(mTempFilePath)) - QFile::remove(mTempFilePath); - -// if (mTmpFlashDir.exists()) -// UBFileSystemUtils::deleteDir(mTmpFlashDir.path()); - - return result; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseGSection(const QDomElement &element) -{ - mGSectionContainer = new UBGraphicsGroupContainerItem(); - - QDomElement currentSvgElement = element.firstChildElement(); - while (!currentSvgElement.isNull()) { - parseSvgElement(currentSvgElement); - currentSvgElement = currentSvgElement.nextSiblingElement(); - } - - if (mGSectionContainer->childItems().count()) - { - mCurrentScene->addGroup(mGSectionContainer); - } - else - { - delete mGSectionContainer; - } - mGSectionContainer = NULL; - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgSwitchSection(const QDomElement &element) -{ - - QDomElement currentSvgElement = element.firstChildElement(); - while (!currentSvgElement.isNull()) { - if (parseSvgElement(currentSvgElement)) - return true; - } - - return false; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgRect(const QDomElement &element) -{ - qreal x1 = element.attribute(aX).toDouble(); - qreal y1 = element.attribute(aY).toDouble(); - //rect dimensions - qreal width = element.attribute(aWidth).toDouble(); - qreal height = element.attribute(aHeight).toDouble(); - - QString textFillColor = element.attribute(aFill); - QString textStrokeColor = element.attribute(aStroke); - QString textStrokeWidth = element.attribute(aStrokewidth); - - QColor fillColor = !textFillColor.isNull() ? colorFromString(textFillColor) : QColor(); - QColor strokeColor = !textStrokeColor.isNull() ? colorFromString(textStrokeColor) : QColor(); - int strokeWidth = textStrokeWidth.toInt(); - - x1 -= strokeWidth/2; - y1 -= strokeWidth/2; - width += strokeWidth; - height += strokeWidth; - - //init svg generator with temp file - QSvgGenerator *generator = createSvgGenerator(width, height); - - //init painter to paint to svg - QPainter painter; - - painter.begin(generator); - - //fill rect - if (fillColor.isValid()) { - painter.setBrush(QBrush(fillColor)); - painter.fillRect(0, 0, width, height, fillColor); - } - QPen pen; - if (strokeColor.isValid()) { - pen.setColor(strokeColor); - } - if (strokeWidth) - pen.setWidth(strokeWidth); - painter.setPen(pen); - painter.drawRect(0, 0, width, height); - - painter.end(); - - UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - svgItem->setUuid(QUuid(uuid)); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - svgItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, svgItem); - } - - repositionSvgItem(svgItem, width, height, x1, y1, transform); - hashSceneItem(element, svgItem); - - if (mGSectionContainer) - { - addItemToGSection(svgItem); - } - - delete generator; - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgEllipse(const QDomElement &element) -{ - //ellipse horisontal and vertical radius - qreal rx = element.attribute(aRx).toDouble(); - qreal ry = element.attribute(aRy).toDouble(); - QSvgGenerator *generator = createSvgGenerator(rx * 2, ry * 2); - - //fill and stroke color - QColor fillColor = colorFromString(element.attribute(aFill)); - QColor strokeColor = colorFromString(element.attribute(aStroke)); - int strokeWidth = element.attribute(aStrokewidth).toInt(); - - //ellipse center coordinates - qreal cx = element.attribute(aCx).toDouble(); - qreal cy = element.attribute(aCy).toDouble(); - - //init painter to paint to svg - QPainter painter; - painter.begin(generator); - - QPen pen(strokeColor); - pen.setWidth(strokeWidth); - painter.setPen(pen); - painter.setBrush(QBrush(fillColor)); - - painter.drawEllipse(0, 0, rx * 2, ry * 2); - - painter.end(); - - UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - svgItem->setUuid(QUuid(uuid)); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - svgItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, svgItem); - } - - - repositionSvgItem(svgItem, rx * 2, ry * 2, cx - 2*rx, cy+ry, transform); - hashSceneItem(element, svgItem); - - if (mGSectionContainer) - { - addItemToGSection(svgItem); - } - - delete generator; - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolygon(const QDomElement &element) -{ - QString svgPoints = element.attribute(aPoints); - QPolygonF polygon; - - if (!svgPoints.isNull()) { - QStringList ts = svgPoints.split(QLatin1Char(' '), QString::SkipEmptyParts); - - foreach(const QString sPoint, ts) { - QStringList sCoord = sPoint.split(QLatin1Char(','), QString::SkipEmptyParts); - if (sCoord.size() == 2) { - QPointF point; - point.setX(sCoord.at(0).toFloat()); - point.setY(sCoord.at(1).toFloat()); - polygon << point; - } - else if (sCoord.size() == 4){ - //This is the case on system were the "," is used to seperate decimal - QPointF point; - QString x = sCoord.at(0) + "." + sCoord.at(1); - QString y = sCoord.at(2) + "." + sCoord.at(3); - point.setX(x.toFloat()); - point.setY(y.toFloat()); - polygon << point; - } - else { - qWarning() << "cannot make sense of a 'point' value" << sCoord; - } - } - } - - //bounding rect lef top corner coordinates - qreal x1 = polygon.boundingRect().topLeft().x(); - qreal y1 = polygon.boundingRect().topLeft().y(); - //bounding rect dimensions - qreal width = polygon.boundingRect().width(); - qreal height = polygon.boundingRect().height(); - - QString strokeColorText = element.attribute(aStroke); - QString fillColorText = element.attribute(aFill); - QString strokeWidthText = element.attribute(aStrokewidth); - - QColor strokeColor = !strokeColorText.isEmpty() ? colorFromString(strokeColorText) : QColor(); - QColor fillColor = !fillColorText.isEmpty() ? colorFromString(fillColorText) : QColor(); - int strokeWidth = strokeWidthText.toDouble(); - - QPen pen; - pen.setColor(strokeColor); - pen.setWidth(strokeWidth); - - QBrush brush; - brush.setColor(fillColor); - brush.setStyle(Qt::SolidPattern); - - - QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length())); - QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1)); - if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ - { - UBGraphicsPolygonItem *graphicsPolygon = mCurrentScene->polygonToPolygonItem(polygon); - - graphicsPolygon->setBrush(brush); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - graphicsPolygon->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, graphicsPolygon); - } - mCurrentScene->addItem(graphicsPolygon); - - graphicsPolygon->setUuid(itemUuid); - mRefToUuidMap.insert(element.attribute(aId), itemUuid); - - } - else // single CFF - { - QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); - QPainter painter; - - painter.begin(generator); //drawing to svg tmp file - - painter.translate(pen.widthF() / 2 - x1, pen.widthF() / 2 - y1); - painter.setBrush(brush); - painter.setPen(pen); - painter.drawPolygon(polygon); - - painter.end(); - - //add resulting svg file to scene - UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); - QTransform transform; - QString textTransform = element.attribute(aTransform); - - QUuid uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - svgItem->setUuid(uuid); - - svgItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, svgItem); - } - repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); - hashSceneItem(element, svgItem); - - if (mGSectionContainer) - { - addItemToGSection(svgItem); - } - - delete generator; - } - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolyline(const QDomElement &element) -{ - QString svgPoints = element.attribute(aPoints); - QPolygonF polygon; - - if (!svgPoints.isNull()) { - QStringList ts = svgPoints.split(QLatin1Char(' '), - QString::SkipEmptyParts); - - foreach(const QString sPoint, ts) { - QStringList sCoord = sPoint.split(QLatin1Char(','), QString::SkipEmptyParts); - if (sCoord.size() == 2) { - QPointF point; - point.setX(sCoord.at(0).toFloat()); - point.setY(sCoord.at(1).toFloat()); - polygon << point; - } - else if (sCoord.size() == 4){ - //This is the case on system were the "," is used to seperate decimal - QPointF point; - QString x = sCoord.at(0) + "." + sCoord.at(1); - QString y = sCoord.at(2) + "." + sCoord.at(3); - point.setX(x.toFloat()); - point.setY(y.toFloat()); - polygon << point; - } - else { - qWarning() << "cannot make sense of a 'point' value" << sCoord; - } - } - } - - //bounding rect lef top corner coordinates - qreal x1 = polygon.boundingRect().topLeft().x(); - qreal y1 = polygon.boundingRect().topLeft().y(); - - //bounding rect dimensions - qreal width = polygon.boundingRect().width(); - qreal height = polygon.boundingRect().height(); - - QString strokeColorText = element.attribute(aStroke); - QString strokeWidthText = element.attribute(aStrokewidth); - - QColor strokeColor = !strokeColorText.isEmpty() ? colorFromString(strokeColorText) : QColor(); - int strokeWidth = strokeWidthText.toDouble(); - - width += strokeWidth; - height += strokeWidth; - - QPen pen; - pen.setColor(strokeColor); - pen.setWidth(strokeWidth); - - QBrush brush; - brush.setColor(strokeColor); - brush.setStyle(Qt::SolidPattern); - - QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length())); - QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1)); - if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ - { - UBGraphicsPolygonItem *graphicsPolygon = new UBGraphicsPolygonItem(polygon); - - UBGraphicsStroke *stroke = new UBGraphicsStroke(); - graphicsPolygon->setStroke(stroke); - - graphicsPolygon->setBrush(brush); - QTransform transform; - QString textTransform = element.attribute(aTransform); - - graphicsPolygon->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, graphicsPolygon); - } - mCurrentScene->addItem(graphicsPolygon); - - graphicsPolygon->setUuid(itemUuid); - mRefToUuidMap.insert(element.attribute(aId), itemUuid); - - } - else // simple CFF - { - QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); - QPainter painter; - - painter.begin(generator); //drawing to svg tmp file - - painter.translate(pen.widthF() / 2 - x1, pen.widthF() / 2 - y1); - painter.setBrush(brush); - painter.setPen(pen); - painter.drawPolygon(polygon); - - painter.end(); - - //add resulting svg file to scene - UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - svgItem->setUuid(QUuid(uuid)); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - svgItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, svgItem); - } - repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); - hashSceneItem(element, svgItem); - - if (mGSectionContainer) - { - addItemToGSection(svgItem); - } - - delete generator; - } - - - return true; -} -void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextAttributes(const QDomElement &element, - qreal &fontSize, QColor &fontColor, QString &fontFamily, - QString &fontStretch, bool &italic, int &fontWeight, - int &textAlign, QTransform &fontTransform) -{ - //consider inch has 72 liens - //since svg font size is given in pixels, divide it by pixels per line - QString fontSz = element.attribute(aFontSize); - if (!fontSz.isNull()) fontSize = fontSz.toDouble() * 72 / QApplication::desktop()->physicalDpiY(); - - QString fontColorText = element.attribute(aFill); - if (!fontColorText.isNull()) fontColor = colorFromString(fontColorText); - - QString fontFamilyText = element.attribute(aFontfamily); - if (!fontFamilyText.isNull()) fontFamily = fontFamilyText; - - QString fontStretchText = element.attribute(aFontstretch); - if (!fontStretchText.isNull()) fontStretch = fontStretchText; - - if (!element.attribute(aFontstyle).isNull()) - italic = (element.attribute(aFontstyle) == "italic"); - - QString weight = element.attribute(aFontweight); - if (!weight.isNull()) { - if (weight == "normal") fontWeight = QFont::Normal; - else if (weight == "light") fontWeight = QFont::Light; - else if (weight == "demibold") fontWeight = QFont::DemiBold; - else if (weight == "bold") fontWeight = QFont::Bold; - else if (weight == "black") fontWeight = QFont::Black; - } - QString align = element.attribute(aTextalign); - if (!align.isNull()) { - if (align == "middle" || align == "center") textAlign = Qt::AlignHCenter; - else if (align == "start") textAlign = Qt::AlignLeft; - else if (align == "end") textAlign = Qt::AlignRight; - } - - if (!element.attribute(aTransform).isNull()) - fontTransform = transformFromString(element.attribute(aTransform)); -} -void UBCFFSubsetAdaptor::UBCFFSubsetReader::readTextBlockAttr(const QDomElement &element, QTextBlockFormat &format) -{ - QString fontStretchText = element.attribute(aFontstretch); - if (!fontStretchText.isNull()) format.setAlignment(Qt::AlignJustify); - - QString align = element.attribute(aTextalign); - if (!align.isNull()) { - if (align == "middle" || align == "center") format.setAlignment(Qt::AlignHCenter); - else if (align == "start") format.setAlignment(Qt::AlignLeft); - else if (align == "end") format.setAlignment(Qt::AlignRight); - else if (align == "justify") format.setAlignment(Qt::AlignJustify); - } -} -void UBCFFSubsetAdaptor::UBCFFSubsetReader::readTextCharAttr(const QDomElement &element, QTextCharFormat &format) -{ - QString fontSz = element.attribute(aFontSize); - if (!fontSz.isNull()) { - qreal fontSize = fontSz.remove("pt").toDouble(); - format.setFontPointSize(fontSize); - } - QString fontColorText = element.attribute(aFill); - if (!fontColorText.isNull()) { - QColor fontColor = colorFromString(fontColorText); - if (fontColor.isValid()) format.setForeground(fontColor); - } - QString fontFamilyText = element.attribute(aFontfamily); - if (!fontFamilyText.isNull()) { - format.setFontFamily(fontFamilyText); - } - if (!element.attribute(aFontstyle).isNull()) { - bool italic = (element.attribute(aFontstyle) == "italic"); - format.setFontItalic(italic); - } - QString weight = element.attribute(aFontweight); - if (!weight.isNull()) { - if (weight == "normal") format.setFontWeight(QFont::Normal); - else if (weight == "light") format.setFontWeight(QFont::Light); - else if (weight == "demibold") format.setFontWeight(QFont::DemiBold); - else if (weight == "bold") format.setFontWeight(QFont::Bold); - else if (weight == "black") format.setFontWeight(QFont::Black); - } -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgText(const QDomElement &element) -{ - qreal x = element.attribute(aX).toDouble(); - qreal y = element.attribute(aY).toDouble(); - qreal width = element.attribute(aWidth).toDouble(); - qreal height = element.attribute(aHeight).toDouble(); - - - qreal fontSize = 12; - QColor fontColor(qApp->palette().foreground().color()); - QString fontFamily = "Arial"; - QString fontStretch = "normal"; - bool italic = false; - int fontWeight = QFont::Normal; - int textAlign = Qt::AlignLeft; - QTransform fontTransform; - parseTextAttributes(element, fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); - - QFont startFont(fontFamily, fontSize, fontWeight, italic); - height = QFontMetrics(startFont).height(); - width = QFontMetrics(startFont).width(element.text()) + 5; - - QSvgGenerator *generator = createSvgGenerator(width, height); - QPainter painter; - painter.begin(generator); - painter.setFont(startFont); - - qreal curY = 0.0; - qreal curX = 0.0; - qreal linespacing = QFontMetricsF(painter.font()).leading(); - -// remember if text area has transform -// QString transformString; - QTransform transform = fontTransform; - - QRectF lastDrawnTextBoundingRect; - //parse text area tags - - //recursive call any tspan in text svg element - parseTSpan(element, painter - , curX, curY, width, height, linespacing, lastDrawnTextBoundingRect - , fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); - - painter.end(); - - //add resulting svg file to scene - UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - svgItem->setUuid(QUuid(uuid)); - - svgItem->resetTransform(); - repositionSvgItem(svgItem, width, height, x + transform.m31(), y + transform.m32(), transform); - hashSceneItem(element, svgItem); - - if (mGSectionContainer) - { - addItemToGSection(svgItem); - } - - delete generator; - return true; -} - -void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTSpan(const QDomElement &parent, QPainter &painter - , qreal &curX, qreal &curY, qreal &width, qreal &height, qreal &linespacing, QRectF &lastDrawnTextBoundingRect - , qreal &fontSize, QColor &fontColor, QString &fontFamily, QString &fontStretch, bool &italic - , int &fontWeight, int &textAlign, QTransform &fontTransform) -{ - QDomNode curNode = parent.firstChild(); - while (!curNode.isNull()) { - if (curNode.toElement().tagName() == tTspan) { - QDomElement curTSpan = curNode.toElement(); - parseTextAttributes(curTSpan, fontSize, fontColor, fontFamily, fontStretch, italic - , fontWeight, textAlign, fontTransform); - painter.setFont(QFont(fontFamily, fontSize, fontWeight, italic)); - painter.setPen(fontColor); - linespacing = QFontMetricsF(painter.font()).leading(); - parseTSpan(curTSpan, painter - , curX, curY, width, height, linespacing, lastDrawnTextBoundingRect - , fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); - } else if (curNode.nodeType() == QDomNode::CharacterDataNode - || curNode.nodeType() == QDomNode::CDATASectionNode - || curNode.nodeType() == QDomNode::TextNode) { - - QDomCharacterData textData = curNode.toCharacterData(); - QString text = textData.data().trimmed(); -// width = painter.fontMetrics().width(text); - //get bounding rect to obtain desired text height - lastDrawnTextBoundingRect = painter.boundingRect(QRectF(curX, curY, width, height - curY), textAlign|Qt::TextWordWrap, text); - painter.drawText(curX, curY, width, lastDrawnTextBoundingRect.height(), textAlign|Qt::TextWordWrap, text); - curX += lastDrawnTextBoundingRect.x() + lastDrawnTextBoundingRect.width(); - } else if (curNode.nodeType() == QDomNode::ElementNode - && curNode.toElement().tagName() == tBreak) { - - curY += lastDrawnTextBoundingRect.height() + linespacing; - curX = 0.0; - lastDrawnTextBoundingRect = QRectF(0,0,0,0); - } - curNode = curNode.nextSibling(); - } -} -void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTSpan(const QDomElement &element, QTextCursor &cursor - , QTextBlockFormat &blockFormat, QTextCharFormat &charFormat) -{ - QDomNode curNode = element.firstChild(); - while (!curNode.isNull()) { - if (curNode.toElement().tagName() == tTspan) { - QDomElement curTspan = curNode.toElement(); - readTextBlockAttr(curTspan, blockFormat); - readTextCharAttr(curTspan, charFormat); - cursor.setBlockFormat(blockFormat); - cursor.setCharFormat(charFormat); - parseTSpan(curTspan, cursor, blockFormat, charFormat); - - } else if (curNode.nodeType() == QDomNode::CharacterDataNode - || curNode.nodeType() == QDomNode::CDATASectionNode - || curNode.nodeType() == QDomNode::TextNode) { - - QDomCharacterData textData = curNode.toCharacterData(); - QString text = textData.data().trimmed(); - cursor.insertText(text, charFormat); - - } else if (curNode.nodeType() == QDomNode::ElementNode - && curNode.toElement().tagName() == tBreak) { - cursor.insertBlock(); - } - curNode = curNode.nextSibling(); - } -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgTextarea(const QDomElement &element) -{ - qreal x = element.attribute(aX).toDouble(); - qreal y = element.attribute(aY).toDouble(); - qreal width = element.attribute(aWidth).toDouble(); - qreal height = element.attribute(aHeight).toDouble(); - - QTextBlockFormat blockFormat; - blockFormat.setAlignment(Qt::AlignLeft); - - QTextCharFormat textFormat; - // default values - textFormat.setFontPointSize(12); - textFormat.setForeground(qApp->palette().foreground().color()); - textFormat.setFontFamily("Arial"); - textFormat.setFontItalic(false); - textFormat.setFontWeight(QFont::Normal); - - // readed values - readTextBlockAttr(element, blockFormat); - readTextCharAttr(element, textFormat); - - QTextDocument doc; - doc.setPlainText(""); - QTextCursor tCursor(&doc); - tCursor.setBlockFormat(blockFormat); - tCursor.setCharFormat(textFormat); - - parseTSpan(element, tCursor, blockFormat, textFormat); - - UBGraphicsTextItem *svgItem = mCurrentScene->addTextHtml(doc.toHtml()); - svgItem->resize(width, height); - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - svgItem->setUuid(QUuid(uuid)); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - svgItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, svgItem); - } - - //by default all the textAreas are not editable - UBGraphicsTextItemDelegate *curDelegate = dynamic_cast(svgItem->Delegate()); - if (curDelegate) { - curDelegate->setEditable(false); - } - - repositionSvgItem(svgItem, width, height, x + transform.m31(), y + transform.m32(), transform); - hashSceneItem(element, svgItem); - - if (mGSectionContainer) - { - addItemToGSection(svgItem); - } - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgImage(const QDomElement &element) -{ - qreal x = element.attribute(aX).toDouble(); - qreal y = element.attribute(aY).toDouble(); - qreal width = element.attribute(aWidth).toDouble(); - qreal height = element.attribute(aHeight).toDouble(); - - QString itemRefPath = element.attribute(aHref); - - QPixmap pix; - if (!itemRefPath.isNull()) { - QString imagePath = pwdContent + "/" + itemRefPath; - if (!QFile::exists(imagePath)) { - qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; - return false; - } else { -// qDebug() << "size of file" << itemRefPath << QFileInfo(itemRefPath).size(); - } - pix.load(imagePath); - if (pix.isNull()) { - qDebug() << "can't create pixmap for file" << pwdContent + "/" + itemRefPath << "maybe format does not supported"; - } - } - - UBGraphicsPixmapItem *pixItem = mCurrentScene->addPixmap(pix, NULL); - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - pixItem->setUuid(QUuid(uuid)); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - pixItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, pixItem); - } - repositionSvgItem(pixItem, width, height, x + transform.m31(), y + transform.m32(), transform); - hashSceneItem(element, pixItem); - - if (mGSectionContainer) - { - addItemToGSection(pixItem); - } - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgFlash(const QDomElement &element) -{ - QString itemRefPath = element.attribute(aHref); - - qreal x = element.attribute(aX).toDouble(); - qreal y = element.attribute(aY).toDouble(); - qreal width = element.attribute(aWidth).toDouble(); - qreal height = element.attribute(aHeight).toDouble(); - - QUrl urlPath; - QString flashPath; - if (!itemRefPath.isNull()) { - flashPath = pwdContent + "/" + itemRefPath; - if (!QFile::exists(flashPath)) { - qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; - return false; - } - urlPath = QUrl::fromLocalFile(flashPath); - } - QDir tmpFlashDir(mTmpFlashDir); - if (!tmpFlashDir.exists()) { - qDebug() << "Can't create temporary directory to put flash"; - return false; - } - - QString flashUrl = UBGraphicsW3CWidgetItem::createNPAPIWrapperInDir(flashPath, tmpFlashDir, "application/x-shockwave-flash" - ,QSize(mCurrentSceneRect.width(), mCurrentSceneRect.height())); - UBGraphicsWidgetItem *flashItem = mCurrentScene->addW3CWidget(QUrl::fromLocalFile(flashUrl)); - flashItem->setSourceUrl(urlPath); - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - flashItem->setUuid(QUuid(uuid)); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - flashItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, flashItem); - } - repositionSvgItem(flashItem, width, height, x + transform.m31(), y + transform.m32(), transform); - hashSceneItem(element, flashItem); - - if (mGSectionContainer) - { - addItemToGSection(flashItem); - } - - return true; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgAudio(const QDomElement &element) -{ - QDomElement parentOfAudio = element.firstChild().toElement(); - - qreal x = parentOfAudio.attribute(aX).toDouble(); - qreal y = parentOfAudio.attribute(aY).toDouble(); - - QString itemRefPath = element.attribute(aHref); - - QUrl concreteUrl; - if (!itemRefPath.isNull()) { - QString audioPath = pwdContent + "/" + itemRefPath; - if (!QFile::exists(audioPath)) { - qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; - return false; - } - concreteUrl = QUrl::fromLocalFile(audioPath); - } - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument( - mCurrentScene->document(), - concreteUrl.toLocalFile(), - UBPersistenceManager::audioDirectory, - QUuid(uuid), - destFile); - if (!b) - { - return false; - } - concreteUrl = QUrl::fromLocalFile(destFile); - - UBGraphicsMediaItem *audioItem = mCurrentScene->addAudio(concreteUrl, false); - - QTransform transform; - QString textTransform = parentOfAudio.attribute(aTransform); - - audioItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, audioItem); - } - repositionSvgItem(audioItem, audioItem->boundingRect().width(), audioItem->boundingRect().height(), x + transform.m31(), y + transform.m32(), transform); - hashSceneItem(element, audioItem); - - if (mGSectionContainer) - { - addItemToGSection(audioItem); - } - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgVideo(const QDomElement &element) -{ - QString itemRefPath = element.attribute(aHref); - if (itemRefPath.startsWith(tFlash + "/") && itemRefPath.endsWith(".swf")) { - if (parseSvgFlash(element)) return true; - else return false; - } - qreal x = element.attribute(aX).toDouble(); - qreal y = element.attribute(aY).toDouble(); - - QUrl concreteUrl; - if (!itemRefPath.isNull()) { - QString videoPath = pwdContent + "/" + itemRefPath; - if (!QFile::exists(videoPath)) { - qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; - return false; - } - concreteUrl = QUrl::fromLocalFile(videoPath); - } - - QString uuid = QUuid::createUuid().toString(); - mRefToUuidMap.insert(element.attribute(aId), uuid); - - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument( - mCurrentScene->document(), - concreteUrl.toLocalFile(), - UBPersistenceManager::videoDirectory, - QUuid(uuid), - destFile); - if (!b) - { - return false; - } - concreteUrl = QUrl::fromLocalFile(destFile); - - UBGraphicsMediaItem *videoItem = mCurrentScene->addVideo(concreteUrl, false); - - QTransform transform; - QString textTransform = element.attribute(aTransform); - - videoItem->resetTransform(); - if (!textTransform.isNull()) { - transform = transformFromString(textTransform, videoItem); - } - repositionSvgItem(videoItem, videoItem->boundingRect().width(), videoItem->boundingRect().height(), x + transform.m31(), y + transform.m32(), transform); - hashSceneItem(element, videoItem); - - if (mGSectionContainer) - { - addItemToGSection(videoItem); - } - - return true; -} - -void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgSectionAttr(const QDomElement &svgSection) -{ - getViewBoxDimenstions(svgSection.attribute(aViewbox)); - mSize = QSize(svgSection.attribute(aWidth).toInt(), - svgSection.attribute(aHeight).toInt()); -} - -void UBCFFSubsetAdaptor::UBCFFSubsetReader::addItemToGSection(QGraphicsItem *item) -{ - mGSectionContainer->addToGroup(item); -} - -void UBCFFSubsetAdaptor::UBCFFSubsetReader::hashSceneItem(const QDomElement &element, UBGraphicsItem *item) -{ -// adding element pointer to hash to refer if needed - QString key = element.attribute(aId); - if (!key.isNull()) { - persistedItems.insert(key, item); - } -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgElement(const QDomElement &parent) -{ - QString tagName = parent.tagName(); - if (parent.namespaceURI() != svgNS) { - qWarning() << "Incorrect namespace, error at content file, line number" << parent.lineNumber(); - //return false; - } - - if (tagName == tG && !parseGSection(parent)) return false; - else if (tagName == tSwitch && !parseSvgSwitchSection(parent)) return false; - else if (tagName == tRect && !parseSvgRect(parent)) return false; - else if (tagName == tEllipse && !parseSvgEllipse(parent)) return false; - else if (tagName == tPolygon && !parseSvgPolygon(parent)) return false; - else if (tagName == tPolyline && !parseSvgPolyline(parent)) return false; - else if (tagName == tText && !parseSvgText(parent)) return false; - else if (tagName == tTextarea && !parseSvgTextarea(parent)) return false; - else if (tagName == tImage && !parseSvgImage(parent)) return false; - else if (tagName == tFlash && !parseSvgFlash(parent)) return false; - else if (tagName == tAudio && !parseSvgAudio(parent)) return false; - else if (tagName == tVideo && !parseSvgVideo(parent)) return false; - - return true; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPage(const QDomElement &parent) -{ - createNewScene(); - QDomElement currentSvgElement = parent.firstChildElement(); - while (!currentSvgElement.isNull()) { - if (!parseSvgElement(currentSvgElement)) - return false; - - currentSvgElement = currentSvgElement.nextSiblingElement(); - } - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPageset(const QDomElement &parent) -{ - QDomElement currentPage = parent.firstChildElement(tPage); - while (!currentPage.isNull()) { - if (!parseSvgPage(currentPage)) - return false; - currentPage = currentPage.nextSiblingElement(tPage); - } - return true; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbMeta(const QDomElement &element) -{ - if (element.namespaceURI() != iwbNS) { - qWarning() << "incorrect meta namespace, incorrect document"; - //return false; - } - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvg(const QDomElement &svgSection) -{ - if (svgSection.namespaceURI() != svgNS) { - qWarning() << "incorrect svg namespace, incorrect document"; - // return false; - } - - parseSvgSectionAttr(svgSection); - QDomElement currentSvg = svgSection.firstChildElement(); - - if (currentSvg.tagName() != tPageset) { - parseSvgPage(svgSection); - } else if (currentSvg.tagName() == tPageset){ - parseSvgPageset(currentSvg); - } - - return true; -} - -UBGraphicsGroupContainerItem *UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbGroup(QDomElement &parent) -{ - //TODO. Create groups from elements parsed by parseIwbElement() function - if (parent.namespaceURI() != iwbNS) { - qWarning() << "incorrect iwb group namespace, incorrect document"; - // return false; - } - - UBGraphicsGroupContainerItem *group = new UBGraphicsGroupContainerItem(); - QMultiMap strokesGroupsContainer; - QList groupContainer; - QString currentStrokeIdentifier; - - QDomElement currentStrokeElement = parent.firstChildElement(); - while (!currentStrokeElement.isNull()) - { - if (tGroup == currentStrokeElement.tagName()) - group->addToGroup(parseIwbGroup(currentStrokeElement)); - else - { - - QString ref = currentStrokeElement.attribute(aRef); - QString uuid = mRefToUuidMap[ref]; - if (!uuid.isEmpty()) - { - if (ref.size() > QUuid().toString().length()) // create stroke group - { - currentStrokeIdentifier = ref.left(QUuid().toString().length()-1); - UBGraphicsPolygonItem *strokeByUuid = qgraphicsitem_cast(mCurrentScene->itemForUuid(QUuid(ref.right(QUuid().toString().length())))); - - if (strokeByUuid) - strokesGroupsContainer.insert(currentStrokeIdentifier, strokeByUuid); - } - else // single elements in group - groupContainer.append(mCurrentScene->itemForUuid(QUuid(uuid))); - } - } - currentStrokeElement = currentStrokeElement.nextSiblingElement(); - } - - - - foreach (QString key, strokesGroupsContainer.keys().toSet()) - { - UBGraphicsStrokesGroup* pStrokesGroup = new UBGraphicsStrokesGroup(); - UBGraphicsStroke *currentStroke = new UBGraphicsStroke(); - foreach(UBGraphicsPolygonItem* poly, strokesGroupsContainer.values(key)) - { - if (poly) - { - mCurrentScene->removeItem(poly); - mCurrentScene->removeItemFromDeletion(poly); - poly->setStrokesGroup(pStrokesGroup); - poly->setStroke(currentStroke); - pStrokesGroup->addToGroup(poly); - } - } - if (currentStroke->polygons().empty()) - delete currentStroke; - - if (pStrokesGroup->childItems().count()) - mCurrentScene->addItem(pStrokesGroup); - else - delete pStrokesGroup; - - if (pStrokesGroup) - { - QGraphicsItem *strokeGroup = qgraphicsitem_cast(pStrokesGroup); - groupContainer.append(strokeGroup); - } - } - - foreach(QGraphicsItem* item, groupContainer) - group->addToGroup(item); - - if (group->childItems().count()) - { - mCurrentScene->addItem(group); - - if (1 == group->childItems().count()) - { - group->destroy(false); - } - } - - return group; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::strToBool(QString str) -{ - return str == "true"; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbElement(QDomElement &element) -{ - if (element.namespaceURI() != iwbNS) { - qWarning() << "incorrect iwb element namespace, incorrect document"; - // return false; - } - - bool locked = false; - bool isEditableItem = false; - bool isEditable = false; //Text items to convert to UBGraphicsTextItem only - - QString IDRef = element.attribute(aRef); - if (!IDRef.isNull()) { - element.hasAttribute(aBackground) ? strToBool(element.attribute(aBackground)) : false; - locked = element.hasAttribute(aBackground) ? strToBool(element.attribute(aBackground)) : false; - isEditableItem = element.hasAttribute(aEditable); - if (isEditableItem) - isEditable = strToBool(element.attribute(aEditable)); - - UBGraphicsItem *referedItem(0); - QHash::iterator iReferedItem; - iReferedItem = persistedItems.find(IDRef); - if (iReferedItem != persistedItems.end()) { - referedItem = *iReferedItem; - referedItem->Delegate()->lock(locked); - } - if (isEditableItem) { - UBGraphicsTextItemDelegate *textDelegate = dynamic_cast(referedItem->Delegate()); - if (textDelegate) { - textDelegate->setEditable(isEditable); - } - } - } - - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseDoc() -{ - QDomElement currentTopElement = mDOMdoc.documentElement().firstChildElement(); - while (!currentTopElement.isNull()) { - QString tagName = currentTopElement.tagName(); - if (tagName == tMeta && !parseIwbMeta(currentTopElement)) return false; - else if (tagName == tSvg && !parseSvg(currentTopElement)) return false; - else if (tagName == tGroup && !parseIwbGroup(currentTopElement)) return false; - else if (tagName == tElement && !parseIwbElement(currentTopElement)) return false; - - currentTopElement = currentTopElement.nextSiblingElement(); - } - if (!persistScenes()) return false; - - return true; -} - -void UBCFFSubsetAdaptor::UBCFFSubsetReader::repositionSvgItem(QGraphicsItem *item, qreal width, qreal height, - qreal x, qreal y, - QTransform &transform) -{ - //First using viebox coordinates, then translate them to scene coordinates - - QRectF itemBounds = item->boundingRect(); - - qreal xScale = width / itemBounds.width(); - qreal yScale = height / itemBounds.height(); - - qreal fullScaleX = mVBTransFactor * xScale; - qreal fullScaleY = mVBTransFactor * yScale; - - QPointF oldVector((x - transform.dx()), (y - transform.dy())); - QTransform rTransform; - QPointF newVector = rTransform.map(oldVector); - - QTransform tr = item->sceneTransform(); - item->setTransform(rTransform.scale(fullScaleX, fullScaleY), true); - tr = item->sceneTransform(); - QPoint pos; - if (UBGraphicsTextItem::Type == item->type()) - pos = QPoint((int)((x + mShiftVector.x() + (newVector - oldVector).x())), (int)((y +mShiftVector.y() + (newVector - oldVector).y()) * mVBTransFactor)); - else - pos = QPoint((int)((x + mShiftVector.x() + (newVector - oldVector).x()) * mVBTransFactor), (int)((y +mShiftVector.y() + (newVector - oldVector).y()) * mVBTransFactor)); - - - item->setPos(pos); -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createNewScene() -{ - mCurrentScene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mProxy, mProxy->pageCount(), false); - mCurrentScene->setSceneRect(mViewBox); - if ((mCurrentScene->sceneRect().topLeft().x() >= 0) || (mCurrentScene->sceneRect().topLeft().y() >= 0)) { - mShiftVector = -mViewBox.center(); - } - mCurrentSceneRect = mViewBox; - mVBTransFactor = qMin(mCurrentScene->normalizedSceneRect().width() / mViewPort.width(), - mCurrentScene->normalizedSceneRect().height() / mViewPort.height()); - return true; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::persistCurrentScene() -{ - if (mCurrentScene != 0 && mCurrentScene->isModified()) - { - UBThumbnailAdaptor::persistScene(mProxy, mCurrentScene, mProxy->pageCount() - 1); - UBSvgSubsetAdaptor::persistScene(mProxy, mCurrentScene, mProxy->pageCount() - 1); - - mCurrentScene->setModified(false); - mCurrentScene = 0; - } - return true; -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::persistScenes() -{ - if (!mProxy->pageCount()) { - qDebug() << "No pages created"; - return false; - } - for (int i = 0; i < mProxy->pageCount(); i++) { - mCurrentScene = UBPersistenceManager::persistenceManager()->getDocumentScene(mProxy, i); - if (!mCurrentScene) { - qDebug() << "can't allocate scene, loading failed"; - return false; - } - - UBSvgSubsetAdaptor::persistScene(mProxy, mCurrentScene, i); - UBGraphicsScene *tmpScene = UBSvgSubsetAdaptor::loadScene(mProxy, i); - tmpScene->setModified(true); - UBThumbnailAdaptor::persistScene(mProxy, tmpScene, i); - mCurrentScene->setModified(false); - } - - return true; -} - -QColor UBCFFSubsetAdaptor::UBCFFSubsetReader::colorFromString(const QString& clrString) -{ - //init regexp with pattern - //pattern corresponds to strings like 'rgb(1,2,3) or rgb(10%,20%,30%)' - QRegExp regexp("rgb\\(([0-9]+%{0,1}),([0-9]+%{0,1}),([0-9]+%{0,1})\\)"); - if (regexp.exactMatch(clrString)) - { - if (regexp.capturedTexts().count() == 4 && regexp.capturedTexts().at(0).length() == clrString.length()) - { - int r = regexp.capturedTexts().at(1).toInt(); - if (regexp.capturedTexts().at(1).indexOf("%") != -1) - r = r * 255 / 100; - int g = regexp.capturedTexts().at(2).toInt(); - if (regexp.capturedTexts().at(2).indexOf("%") != -1) - g = g * 255 / 100; - int b = regexp.capturedTexts().at(3).toInt(); - if (regexp.capturedTexts().at(3).indexOf("%") != -1) - b = b * 255 / 100; - return QColor(r, g, b); - } - else - return QColor(); - } - else - return QColor(clrString); -} - -QTransform UBCFFSubsetAdaptor::UBCFFSubsetReader::transformFromString(const QString trString, QGraphicsItem *item) -{ - qreal dxr = 0.0; - qreal dyr = 0.0; - qreal dx = 0.0; - qreal dy = 0.0; - qreal angle = 0.0; - QTransform tr; - - foreach(QString trStr, trString.split(" ", QString::SkipEmptyParts)) - { - //check pattern for strings like 'rotate(10)' - QRegExp regexp("rotate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *\\)"); - if (regexp.exactMatch(trStr)) { - angle = regexp.capturedTexts().at(1).toDouble(); - if (item) - { - item->setTransformOriginPoint(QPointF(0, 0)); - item->rotate(angle); - } - continue; - }; - - //check pattern for strings like 'rotate(10,20,20)' or 'rotate(10.1,10.2,34.2)' - regexp.setPattern("rotate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *, *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *, *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *\\)"); - if (regexp.exactMatch(trStr)) { - angle = regexp.capturedTexts().at(1).toDouble(); - dxr = regexp.capturedTexts().at(2).toDouble(); - dyr = regexp.capturedTexts().at(3).toDouble(); - if (item) - { - item->setTransformOriginPoint(QPointF(dxr, dyr)-item->pos()); - item->rotate(angle); - } - continue; - } - - //check pattern for strings like 'translate(11.0, 12.34)' - regexp.setPattern("translate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *,*([-+]{0,1}[0-9]*\\.{0,1}[0-9]*)*\\)"); - if (regexp.exactMatch(trStr)) { - dx = regexp.capturedTexts().at(1).toDouble(); - dy = regexp.capturedTexts().at(2).toDouble(); - tr.translate(dx,dy); - continue; - } - } - return tr; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getViewBoxDimenstions(const QString& viewBox) -{ - QStringList capturedTexts = viewBox.split(" ", QString::SkipEmptyParts); - if (capturedTexts.count()) - { - if (4 == capturedTexts.count()) - { - mViewBox = QRectF(capturedTexts.at(0).toDouble(), capturedTexts.at(1).toDouble(), capturedTexts.at(2).toDouble(), capturedTexts.at(3).toDouble()); - mViewPort = mViewBox; - mViewPort.translate(- mViewPort.center()); - mViewBoxCenter.setX(mViewBox.width() / 2); - mViewBoxCenter.setY(mViewBox.height() / 2); - - return true; - } - } - - mViewBox = QRectF(0, 0, 1000, 1000); - mViewBoxCenter = QPointF(500, 500); - return false; -} - -QSvgGenerator* UBCFFSubsetAdaptor::UBCFFSubsetReader::createSvgGenerator(qreal width, qreal height) -{ - QSvgGenerator* generator = new QSvgGenerator(); -// qWarning() << QString("Making generator with file %1, size (%2, %3) and viewbox (%4 %5 %6 %7)").arg(mTempFilePath) -// .arg(width).arg(height).arg(0.0).arg(0.0).arg(width).arg(width); - generator->setResolution(QApplication::desktop()->physicalDpiY()); - generator->setFileName(mTempFilePath); - generator->setSize(QSize(width, height)); - generator->setViewBox(QRectF(0, 0, width, height)); - - return generator; -} - -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getTempFileName() -{ - int tmpNumber = 0; - QDir rootDir; - while (true) - { - mTempFilePath = QString("%1/sanksvg%2.%3") - .arg(rootDir.tempPath()) - .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm")) - .arg(tmpNumber); - if (!QFile::exists(mTempFilePath)) - return true; - tmpNumber++; - if (tmpNumber == 100000) - { - qWarning() << "Import failed. Failed to create temporary file for svg objects"; - return false; - } - } -} -bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createTempFlashPath() -{ - int tmpNumber = 0; - QDir systemTmp = QDir::temp(); - - while (true) { - QString dirName = QString("SankTmpFlash%1.%2") - .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm")) - .arg(tmpNumber++); - if (!systemTmp.exists(dirName)) { - if (systemTmp.mkdir(dirName)) { - mTmpFlashDir = QDir(systemTmp.absolutePath() + "/" + dirName); - return true; - } else { - qDebug() << "Can't create temporary dir maybe due to permissions"; - return false; - } - } else if (tmpNumber == 1000) { - qWarning() << "Import failed. Failed to create temporary file for svg objects"; - return false; - } - } - - return true; -} -UBCFFSubsetAdaptor::UBCFFSubsetReader::~UBCFFSubsetReader() -{ -// QList pages; -// for (int i = 0; i < mProxy->pageCount(); i++) { -// pages << i; -// } -// UBPersistenceManager::persistenceManager()->deleteDocumentScenes(mProxy, pages); -} + + +#include +#include +#include +#include +#include + +#include "core/UBPersistenceManager.h" + +#include "document/UBDocumentProxy.h" + +#include "domain/UBItem.h" +#include "domain/UBGraphicsPolygonItem.h" +#include "domain/UBGraphicsStroke.h" +#include "domain/UBGraphicsTextItem.h" +#include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsPixmapItem.h" +#include "domain/UBGraphicsMediaItem.h" +#include "domain/UBGraphicsWidgetItem.h" +#include "domain/UBGraphicsTextItem.h" +#include "domain/UBGraphicsTextItemDelegate.h" +#include "domain/UBGraphicsWidgetItem.h" +#include "domain/UBGraphicsGroupContainerItem.h" + +#include "frameworks/UBFileSystemUtils.h" + +#include "UBCFFSubsetAdaptor.h" +#include "UBMetadataDcSubsetAdaptor.h" +#include "UBThumbnailAdaptor.h" +#include "UBSvgSubsetAdaptor.h" + +#include "core/UBApplication.h" +#include "QFile" + +#include "core/memcheck.h" +//#include "qtlogger.h" + +//tag names definition. Use them everiwhere! +static QString tElement = "element"; +static QString tGroup = "group"; +static QString tEllipse = "ellipse"; +static QString tIwb = "iwb"; +static QString tMeta = "meta"; +static QString tPage = "page"; +static QString tPageset = "pageset"; +static QString tG = "g"; +static QString tSwitch = "switch"; +static QString tPolygon = "polygon"; +static QString tPolyline = "polyline"; +static QString tRect = "rect"; +static QString tSvg = "svg"; +static QString tText = "text"; +static QString tTextarea = "textarea"; +static QString tTspan = "tspan"; +static QString tBreak = "tbreak"; +static QString tImage = "image"; +static QString tFlash = "flash"; +static QString tAudio = "a"; +static QString tVideo = "video"; + +//attribute names definition +static QString aFill = "fill"; +static QString aFillopacity = "fill-opacity"; +static QString aX = "x"; +static QString aY = "y"; +static QString aWidth = "width"; +static QString aHeight = "height"; +static QString aStroke = "stroke"; +static QString aStrokewidth = "stroke-width"; +static QString aCx = "cx"; +static QString aCy = "cy"; +static QString aRx = "rx"; +static QString aRy = "ry"; +static QString aTransform = "transform"; +static QString aViewbox = "viewbox"; +static QString aFontSize = "font-size"; +static QString aFontfamily = "font-family"; +static QString aFontstretch = "font-stretch"; +static QString aFontstyle = "font-style"; +static QString aFontweight = "font-weight"; +static QString aTextalign = "text-align"; +static QString aPoints = "points"; +static QString svgNS = "http://www.w3.org/2000/svg"; +static QString iwbNS = "http://www.imsglobal.org/xsd/iwb_v1p0"; +static QString aId = "id"; +static QString aRef = "ref"; +static QString aHref = "href"; +static QString aBackground = "background"; +static QString aLocked = "locked"; +static QString aEditable = "editable"; + +//attributes part names +static QString apRotate = "rotate"; +static QString apTranslate = "translate"; + + +UBCFFSubsetAdaptor::UBCFFSubsetAdaptor() +{} + +bool UBCFFSubsetAdaptor::ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentProxy* pDocument) +{ + //TODO + // fill document proxy metadata + // create persistance manager to save data using proxy + // create UBCFFSubsetReader and make it parse cffSourceFolder + QFile file(cffSourceFile); + + if (!file.open(QIODevice::ReadOnly)) + { + qWarning() << "Cannot open file " << cffSourceFile << " for reading ..."; + return false; + } + + UBCFFSubsetReader cffReader(pDocument, &file); + bool result = cffReader.parse(); + file.close(); + + return result; +} +UBCFFSubsetAdaptor::UBCFFSubsetReader::UBCFFSubsetReader(UBDocumentProxy *proxy, QFile *content) + : mProxy(proxy) + , mGSectionContainer(NULL) +{ + int errorLine, errorColumn; + QString errorStr; + if(!mDOMdoc.setContent(content, true, &errorStr, &errorLine, &errorColumn)){ + qWarning() << "Error:Parseerroratline" << errorLine << "," + << "column" << errorColumn << ":" << errorStr; + } else { + qDebug() << "well parsed to DOM"; + pwdContent = QFileInfo(content->fileName()).dir().absolutePath(); + } + qDebug() << "tmp path is" << pwdContent; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parse() +{ + UBMetadataDcSubsetAdaptor::persist(mProxy); + + mIndent = ""; + if (!getTempFileName() || !createTempFlashPath()) + return false; + + if (mDOMdoc.isNull()) + return false; + + bool result = parseDoc(); + if (result) + result = mProxy->pageCount() != 0; + + if (QFile::exists(mTempFilePath)) + QFile::remove(mTempFilePath); + +// if (mTmpFlashDir.exists()) +// UBFileSystemUtils::deleteDir(mTmpFlashDir.path()); + + return result; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseGSection(const QDomElement &element) +{ + mGSectionContainer = new UBGraphicsGroupContainerItem(); + + QDomElement currentSvgElement = element.firstChildElement(); + while (!currentSvgElement.isNull()) { + parseSvgElement(currentSvgElement); + currentSvgElement = currentSvgElement.nextSiblingElement(); + } + + if (mGSectionContainer->childItems().count()) + { + mCurrentScene->addGroup(mGSectionContainer); + } + else + { + delete mGSectionContainer; + } + mGSectionContainer = NULL; + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgSwitchSection(const QDomElement &element) +{ + + QDomElement currentSvgElement = element.firstChildElement(); + while (!currentSvgElement.isNull()) { + if (parseSvgElement(currentSvgElement)) + return true; + } + + return false; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgRect(const QDomElement &element) +{ + qreal x1 = element.attribute(aX).toDouble(); + qreal y1 = element.attribute(aY).toDouble(); + //rect dimensions + qreal width = element.attribute(aWidth).toDouble(); + qreal height = element.attribute(aHeight).toDouble(); + + QString textFillColor = element.attribute(aFill); + QString textStrokeColor = element.attribute(aStroke); + QString textStrokeWidth = element.attribute(aStrokewidth); + + QColor fillColor = !textFillColor.isNull() ? colorFromString(textFillColor) : QColor(); + QColor strokeColor = !textStrokeColor.isNull() ? colorFromString(textStrokeColor) : QColor(); + int strokeWidth = textStrokeWidth.toInt(); + + x1 -= strokeWidth/2; + y1 -= strokeWidth/2; + width += strokeWidth; + height += strokeWidth; + + //init svg generator with temp file + QSvgGenerator *generator = createSvgGenerator(width, height); + + //init painter to paint to svg + QPainter painter; + + painter.begin(generator); + + //fill rect + if (fillColor.isValid()) { + painter.setBrush(QBrush(fillColor)); + painter.fillRect(0, 0, width, height, fillColor); + } + QPen pen; + if (strokeColor.isValid()) { + pen.setColor(strokeColor); + } + if (strokeWidth) + pen.setWidth(strokeWidth); + painter.setPen(pen); + painter.drawRect(0, 0, width, height); + + painter.end(); + + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + + repositionSvgItem(svgItem, width, height, x1, y1, transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgEllipse(const QDomElement &element) +{ + //ellipse horisontal and vertical radius + qreal rx = element.attribute(aRx).toDouble(); + qreal ry = element.attribute(aRy).toDouble(); + QSvgGenerator *generator = createSvgGenerator(rx * 2, ry * 2); + + //fill and stroke color + QColor fillColor = colorFromString(element.attribute(aFill)); + QColor strokeColor = colorFromString(element.attribute(aStroke)); + int strokeWidth = element.attribute(aStrokewidth).toInt(); + + //ellipse center coordinates + qreal cx = element.attribute(aCx).toDouble(); + qreal cy = element.attribute(aCy).toDouble(); + + //init painter to paint to svg + QPainter painter; + painter.begin(generator); + + QPen pen(strokeColor); + pen.setWidth(strokeWidth); + painter.setPen(pen); + painter.setBrush(QBrush(fillColor)); + + painter.drawEllipse(0, 0, rx * 2, ry * 2); + + painter.end(); + + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + + + repositionSvgItem(svgItem, rx * 2, ry * 2, cx - 2*rx, cy+ry, transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolygon(const QDomElement &element) +{ + QString svgPoints = element.attribute(aPoints); + QPolygonF polygon; + + if (!svgPoints.isNull()) { + QStringList ts = svgPoints.split(QLatin1Char(' '), QString::SkipEmptyParts); + + foreach(const QString sPoint, ts) { + QStringList sCoord = sPoint.split(QLatin1Char(','), QString::SkipEmptyParts); + if (sCoord.size() == 2) { + QPointF point; + point.setX(sCoord.at(0).toFloat()); + point.setY(sCoord.at(1).toFloat()); + polygon << point; + } + else if (sCoord.size() == 4){ + //This is the case on system were the "," is used to seperate decimal + QPointF point; + QString x = sCoord.at(0) + "." + sCoord.at(1); + QString y = sCoord.at(2) + "." + sCoord.at(3); + point.setX(x.toFloat()); + point.setY(y.toFloat()); + polygon << point; + } + else { + qWarning() << "cannot make sense of a 'point' value" << sCoord; + } + } + } + + //bounding rect lef top corner coordinates + qreal x1 = polygon.boundingRect().topLeft().x(); + qreal y1 = polygon.boundingRect().topLeft().y(); + //bounding rect dimensions + qreal width = polygon.boundingRect().width(); + qreal height = polygon.boundingRect().height(); + + QString strokeColorText = element.attribute(aStroke); + QString fillColorText = element.attribute(aFill); + QString strokeWidthText = element.attribute(aStrokewidth); + + QColor strokeColor = !strokeColorText.isEmpty() ? colorFromString(strokeColorText) : QColor(); + QColor fillColor = !fillColorText.isEmpty() ? colorFromString(fillColorText) : QColor(); + int strokeWidth = strokeWidthText.toDouble(); + + QPen pen; + pen.setColor(strokeColor); + pen.setWidth(strokeWidth); + + QBrush brush; + brush.setColor(fillColor); + brush.setStyle(Qt::SolidPattern); + + + QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length())); + QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1)); + if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ + { + UBGraphicsPolygonItem *graphicsPolygon = mCurrentScene->polygonToPolygonItem(polygon); + + graphicsPolygon->setBrush(brush); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + graphicsPolygon->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, graphicsPolygon); + } + mCurrentScene->addItem(graphicsPolygon); + + graphicsPolygon->setUuid(itemUuid); + mRefToUuidMap.insert(element.attribute(aId), itemUuid); + + } + else // single CFF + { + QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); + QPainter painter; + + painter.begin(generator); //drawing to svg tmp file + + painter.translate(pen.widthF() / 2 - x1, pen.widthF() / 2 - y1); + painter.setBrush(brush); + painter.setPen(pen); + painter.drawPolygon(polygon); + + painter.end(); + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + QTransform transform; + QString textTransform = element.attribute(aTransform); + + QUuid uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(uuid); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; + } + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolyline(const QDomElement &element) +{ + QString svgPoints = element.attribute(aPoints); + QPolygonF polygon; + + if (!svgPoints.isNull()) { + QStringList ts = svgPoints.split(QLatin1Char(' '), + QString::SkipEmptyParts); + + foreach(const QString sPoint, ts) { + QStringList sCoord = sPoint.split(QLatin1Char(','), QString::SkipEmptyParts); + if (sCoord.size() == 2) { + QPointF point; + point.setX(sCoord.at(0).toFloat()); + point.setY(sCoord.at(1).toFloat()); + polygon << point; + } + else if (sCoord.size() == 4){ + //This is the case on system were the "," is used to seperate decimal + QPointF point; + QString x = sCoord.at(0) + "." + sCoord.at(1); + QString y = sCoord.at(2) + "." + sCoord.at(3); + point.setX(x.toFloat()); + point.setY(y.toFloat()); + polygon << point; + } + else { + qWarning() << "cannot make sense of a 'point' value" << sCoord; + } + } + } + + //bounding rect lef top corner coordinates + qreal x1 = polygon.boundingRect().topLeft().x(); + qreal y1 = polygon.boundingRect().topLeft().y(); + + //bounding rect dimensions + qreal width = polygon.boundingRect().width(); + qreal height = polygon.boundingRect().height(); + + QString strokeColorText = element.attribute(aStroke); + QString strokeWidthText = element.attribute(aStrokewidth); + + QColor strokeColor = !strokeColorText.isEmpty() ? colorFromString(strokeColorText) : QColor(); + int strokeWidth = strokeWidthText.toDouble(); + + width += strokeWidth; + height += strokeWidth; + + QPen pen; + pen.setColor(strokeColor); + pen.setWidth(strokeWidth); + + QBrush brush; + brush.setColor(strokeColor); + brush.setStyle(Qt::SolidPattern); + + QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length())); + QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1)); + if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ + { + UBGraphicsPolygonItem *graphicsPolygon = new UBGraphicsPolygonItem(polygon); + + UBGraphicsStroke *stroke = new UBGraphicsStroke(); + graphicsPolygon->setStroke(stroke); + + graphicsPolygon->setBrush(brush); + QTransform transform; + QString textTransform = element.attribute(aTransform); + + graphicsPolygon->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, graphicsPolygon); + } + mCurrentScene->addItem(graphicsPolygon); + + graphicsPolygon->setUuid(itemUuid); + mRefToUuidMap.insert(element.attribute(aId), itemUuid); + + } + else // simple CFF + { + QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); + QPainter painter; + + painter.begin(generator); //drawing to svg tmp file + + painter.translate(pen.widthF() / 2 - x1, pen.widthF() / 2 - y1); + painter.setBrush(brush); + painter.setPen(pen); + painter.drawPolygon(polygon); + + painter.end(); + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; + } + + + return true; +} +void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextAttributes(const QDomElement &element, + qreal &fontSize, QColor &fontColor, QString &fontFamily, + QString &fontStretch, bool &italic, int &fontWeight, + int &textAlign, QTransform &fontTransform) +{ + //consider inch has 72 liens + //since svg font size is given in pixels, divide it by pixels per line + QString fontSz = element.attribute(aFontSize); + if (!fontSz.isNull()) fontSize = fontSz.toDouble() * 72 / QApplication::desktop()->physicalDpiY(); + + QString fontColorText = element.attribute(aFill); + if (!fontColorText.isNull()) fontColor = colorFromString(fontColorText); + + QString fontFamilyText = element.attribute(aFontfamily); + if (!fontFamilyText.isNull()) fontFamily = fontFamilyText; + + QString fontStretchText = element.attribute(aFontstretch); + if (!fontStretchText.isNull()) fontStretch = fontStretchText; + + if (!element.attribute(aFontstyle).isNull()) + italic = (element.attribute(aFontstyle) == "italic"); + + QString weight = element.attribute(aFontweight); + if (!weight.isNull()) { + if (weight == "normal") fontWeight = QFont::Normal; + else if (weight == "light") fontWeight = QFont::Light; + else if (weight == "demibold") fontWeight = QFont::DemiBold; + else if (weight == "bold") fontWeight = QFont::Bold; + else if (weight == "black") fontWeight = QFont::Black; + } + QString align = element.attribute(aTextalign); + if (!align.isNull()) { + if (align == "middle" || align == "center") textAlign = Qt::AlignHCenter; + else if (align == "start") textAlign = Qt::AlignLeft; + else if (align == "end") textAlign = Qt::AlignRight; + } + + if (!element.attribute(aTransform).isNull()) + fontTransform = transformFromString(element.attribute(aTransform)); +} +void UBCFFSubsetAdaptor::UBCFFSubsetReader::readTextBlockAttr(const QDomElement &element, QTextBlockFormat &format) +{ + QString fontStretchText = element.attribute(aFontstretch); + if (!fontStretchText.isNull()) format.setAlignment(Qt::AlignJustify); + + QString align = element.attribute(aTextalign); + if (!align.isNull()) { + if (align == "middle" || align == "center") format.setAlignment(Qt::AlignHCenter); + else if (align == "start") format.setAlignment(Qt::AlignLeft); + else if (align == "end") format.setAlignment(Qt::AlignRight); + else if (align == "justify") format.setAlignment(Qt::AlignJustify); + } +} +void UBCFFSubsetAdaptor::UBCFFSubsetReader::readTextCharAttr(const QDomElement &element, QTextCharFormat &format) +{ + QString fontSz = element.attribute(aFontSize); + if (!fontSz.isNull()) { + qreal fontSize = fontSz.remove("pt").toDouble(); + format.setFontPointSize(fontSize); + } + QString fontColorText = element.attribute(aFill); + if (!fontColorText.isNull()) { + QColor fontColor = colorFromString(fontColorText); + if (fontColor.isValid()) format.setForeground(fontColor); + } + QString fontFamilyText = element.attribute(aFontfamily); + if (!fontFamilyText.isNull()) { + format.setFontFamily(fontFamilyText); + } + if (!element.attribute(aFontstyle).isNull()) { + bool italic = (element.attribute(aFontstyle) == "italic"); + format.setFontItalic(italic); + } + QString weight = element.attribute(aFontweight); + if (!weight.isNull()) { + if (weight == "normal") format.setFontWeight(QFont::Normal); + else if (weight == "light") format.setFontWeight(QFont::Light); + else if (weight == "demibold") format.setFontWeight(QFont::DemiBold); + else if (weight == "bold") format.setFontWeight(QFont::Bold); + else if (weight == "black") format.setFontWeight(QFont::Black); + } +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgText(const QDomElement &element) +{ + qreal x = element.attribute(aX).toDouble(); + qreal y = element.attribute(aY).toDouble(); + qreal width = element.attribute(aWidth).toDouble(); + qreal height = element.attribute(aHeight).toDouble(); + + + qreal fontSize = 12; + QColor fontColor(qApp->palette().foreground().color()); + QString fontFamily = "Arial"; + QString fontStretch = "normal"; + bool italic = false; + int fontWeight = QFont::Normal; + int textAlign = Qt::AlignLeft; + QTransform fontTransform; + parseTextAttributes(element, fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); + + QFont startFont(fontFamily, fontSize, fontWeight, italic); + height = QFontMetrics(startFont).height(); + width = QFontMetrics(startFont).width(element.text()) + 5; + + QSvgGenerator *generator = createSvgGenerator(width, height); + QPainter painter; + painter.begin(generator); + painter.setFont(startFont); + + qreal curY = 0.0; + qreal curX = 0.0; + qreal linespacing = QFontMetricsF(painter.font()).leading(); + +// remember if text area has transform +// QString transformString; + QTransform transform = fontTransform; + + QRectF lastDrawnTextBoundingRect; + //parse text area tags + + //recursive call any tspan in text svg element + parseTSpan(element, painter + , curX, curY, width, height, linespacing, lastDrawnTextBoundingRect + , fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); + + painter.end(); + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + + svgItem->resetTransform(); + repositionSvgItem(svgItem, width, height, x + transform.m31(), y + transform.m32(), transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; + return true; +} + +void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTSpan(const QDomElement &parent, QPainter &painter + , qreal &curX, qreal &curY, qreal &width, qreal &height, qreal &linespacing, QRectF &lastDrawnTextBoundingRect + , qreal &fontSize, QColor &fontColor, QString &fontFamily, QString &fontStretch, bool &italic + , int &fontWeight, int &textAlign, QTransform &fontTransform) +{ + QDomNode curNode = parent.firstChild(); + while (!curNode.isNull()) { + if (curNode.toElement().tagName() == tTspan) { + QDomElement curTSpan = curNode.toElement(); + parseTextAttributes(curTSpan, fontSize, fontColor, fontFamily, fontStretch, italic + , fontWeight, textAlign, fontTransform); + painter.setFont(QFont(fontFamily, fontSize, fontWeight, italic)); + painter.setPen(fontColor); + linespacing = QFontMetricsF(painter.font()).leading(); + parseTSpan(curTSpan, painter + , curX, curY, width, height, linespacing, lastDrawnTextBoundingRect + , fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); + } else if (curNode.nodeType() == QDomNode::CharacterDataNode + || curNode.nodeType() == QDomNode::CDATASectionNode + || curNode.nodeType() == QDomNode::TextNode) { + + QDomCharacterData textData = curNode.toCharacterData(); + QString text = textData.data().trimmed(); +// width = painter.fontMetrics().width(text); + //get bounding rect to obtain desired text height + lastDrawnTextBoundingRect = painter.boundingRect(QRectF(curX, curY, width, height - curY), textAlign|Qt::TextWordWrap, text); + painter.drawText(curX, curY, width, lastDrawnTextBoundingRect.height(), textAlign|Qt::TextWordWrap, text); + curX += lastDrawnTextBoundingRect.x() + lastDrawnTextBoundingRect.width(); + } else if (curNode.nodeType() == QDomNode::ElementNode + && curNode.toElement().tagName() == tBreak) { + + curY += lastDrawnTextBoundingRect.height() + linespacing; + curX = 0.0; + lastDrawnTextBoundingRect = QRectF(0,0,0,0); + } + curNode = curNode.nextSibling(); + } +} +void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTSpan(const QDomElement &element, QTextCursor &cursor + , QTextBlockFormat &blockFormat, QTextCharFormat &charFormat) +{ + QDomNode curNode = element.firstChild(); + while (!curNode.isNull()) { + if (curNode.toElement().tagName() == tTspan) { + QDomElement curTspan = curNode.toElement(); + readTextBlockAttr(curTspan, blockFormat); + readTextCharAttr(curTspan, charFormat); + cursor.setBlockFormat(blockFormat); + cursor.setCharFormat(charFormat); + parseTSpan(curTspan, cursor, blockFormat, charFormat); + + } else if (curNode.nodeType() == QDomNode::CharacterDataNode + || curNode.nodeType() == QDomNode::CDATASectionNode + || curNode.nodeType() == QDomNode::TextNode) { + + QDomCharacterData textData = curNode.toCharacterData(); + QString text = textData.data().trimmed(); + cursor.insertText(text, charFormat); + + } else if (curNode.nodeType() == QDomNode::ElementNode + && curNode.toElement().tagName() == tBreak) { + cursor.insertBlock(); + } + curNode = curNode.nextSibling(); + } +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgTextarea(const QDomElement &element) +{ + qreal x = element.attribute(aX).toDouble(); + qreal y = element.attribute(aY).toDouble(); + qreal width = element.attribute(aWidth).toDouble(); + qreal height = element.attribute(aHeight).toDouble(); + + QTextBlockFormat blockFormat; + blockFormat.setAlignment(Qt::AlignLeft); + + QTextCharFormat textFormat; + // default values + textFormat.setFontPointSize(12); + textFormat.setForeground(qApp->palette().foreground().color()); + textFormat.setFontFamily("Arial"); + textFormat.setFontItalic(false); + textFormat.setFontWeight(QFont::Normal); + + // readed values + readTextBlockAttr(element, blockFormat); + readTextCharAttr(element, textFormat); + + QTextDocument doc; + doc.setPlainText(""); + QTextCursor tCursor(&doc); + tCursor.setBlockFormat(blockFormat); + tCursor.setCharFormat(textFormat); + + parseTSpan(element, tCursor, blockFormat, textFormat); + + UBGraphicsTextItem *svgItem = mCurrentScene->addTextHtml(doc.toHtml()); + svgItem->resize(width, height); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + + //by default all the textAreas are not editable + UBGraphicsTextItemDelegate *curDelegate = dynamic_cast(svgItem->Delegate()); + if (curDelegate) { + curDelegate->setEditable(false); + } + + repositionSvgItem(svgItem, width, height, x + transform.m31(), y + transform.m32(), transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgImage(const QDomElement &element) +{ + qreal x = element.attribute(aX).toDouble(); + qreal y = element.attribute(aY).toDouble(); + qreal width = element.attribute(aWidth).toDouble(); + qreal height = element.attribute(aHeight).toDouble(); + + QString itemRefPath = element.attribute(aHref); + + QPixmap pix; + if (!itemRefPath.isNull()) { + QString imagePath = pwdContent + "/" + itemRefPath; + if (!QFile::exists(imagePath)) { + qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; + return false; + } else { +// qDebug() << "size of file" << itemRefPath << QFileInfo(itemRefPath).size(); + } + pix.load(imagePath); + if (pix.isNull()) { + qDebug() << "can't create pixmap for file" << pwdContent + "/" + itemRefPath << "maybe format does not supported"; + } + } + + UBGraphicsPixmapItem *pixItem = mCurrentScene->addPixmap(pix, NULL); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + pixItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + pixItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, pixItem); + } + repositionSvgItem(pixItem, width, height, x + transform.m31(), y + transform.m32(), transform); + hashSceneItem(element, pixItem); + + if (mGSectionContainer) + { + addItemToGSection(pixItem); + } + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgFlash(const QDomElement &element) +{ + QString itemRefPath = element.attribute(aHref); + + qreal x = element.attribute(aX).toDouble(); + qreal y = element.attribute(aY).toDouble(); + qreal width = element.attribute(aWidth).toDouble(); + qreal height = element.attribute(aHeight).toDouble(); + + QUrl urlPath; + QString flashPath; + if (!itemRefPath.isNull()) { + flashPath = pwdContent + "/" + itemRefPath; + if (!QFile::exists(flashPath)) { + qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; + return false; + } + urlPath = QUrl::fromLocalFile(flashPath); + } + QDir tmpFlashDir(mTmpFlashDir); + if (!tmpFlashDir.exists()) { + qDebug() << "Can't create temporary directory to put flash"; + return false; + } + + QString flashUrl = UBGraphicsW3CWidgetItem::createNPAPIWrapperInDir(flashPath, tmpFlashDir, "application/x-shockwave-flash" + ,QSize(mCurrentSceneRect.width(), mCurrentSceneRect.height())); + UBGraphicsWidgetItem *flashItem = mCurrentScene->addW3CWidget(QUrl::fromLocalFile(flashUrl)); + flashItem->setSourceUrl(urlPath); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + flashItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + flashItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, flashItem); + } + repositionSvgItem(flashItem, width, height, x + transform.m31(), y + transform.m32(), transform); + hashSceneItem(element, flashItem); + + if (mGSectionContainer) + { + addItemToGSection(flashItem); + } + + return true; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgAudio(const QDomElement &element) +{ + QDomElement parentOfAudio = element.firstChild().toElement(); + + qreal x = parentOfAudio.attribute(aX).toDouble(); + qreal y = parentOfAudio.attribute(aY).toDouble(); + + QString itemRefPath = element.attribute(aHref); + + QUrl concreteUrl; + if (!itemRefPath.isNull()) { + QString audioPath = pwdContent + "/" + itemRefPath; + if (!QFile::exists(audioPath)) { + qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; + return false; + } + concreteUrl = QUrl::fromLocalFile(audioPath); + } + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument( + mCurrentScene->document(), + concreteUrl.toLocalFile(), + UBPersistenceManager::audioDirectory, + QUuid(uuid), + destFile); + if (!b) + { + return false; + } + concreteUrl = QUrl::fromLocalFile(destFile); + + UBGraphicsMediaItem *audioItem = mCurrentScene->addAudio(concreteUrl, false); + + QTransform transform; + QString textTransform = parentOfAudio.attribute(aTransform); + + audioItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, audioItem); + } + repositionSvgItem(audioItem, audioItem->boundingRect().width(), audioItem->boundingRect().height(), x + transform.m31(), y + transform.m32(), transform); + hashSceneItem(element, audioItem); + + if (mGSectionContainer) + { + addItemToGSection(audioItem); + } + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgVideo(const QDomElement &element) +{ + QString itemRefPath = element.attribute(aHref); + if (itemRefPath.startsWith(tFlash + "/") && itemRefPath.endsWith(".swf")) { + if (parseSvgFlash(element)) return true; + else return false; + } + qreal x = element.attribute(aX).toDouble(); + qreal y = element.attribute(aY).toDouble(); + + QUrl concreteUrl; + if (!itemRefPath.isNull()) { + QString videoPath = pwdContent + "/" + itemRefPath; + if (!QFile::exists(videoPath)) { + qDebug() << "can't load file" << pwdContent + "/" + itemRefPath << "maybe file corrupted"; + return false; + } + concreteUrl = QUrl::fromLocalFile(videoPath); + } + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument( + mCurrentScene->document(), + concreteUrl.toLocalFile(), + UBPersistenceManager::videoDirectory, + QUuid(uuid), + destFile); + if (!b) + { + return false; + } + concreteUrl = QUrl::fromLocalFile(destFile); + + UBGraphicsMediaItem *videoItem = mCurrentScene->addVideo(concreteUrl, false); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + videoItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, videoItem); + } + repositionSvgItem(videoItem, videoItem->boundingRect().width(), videoItem->boundingRect().height(), x + transform.m31(), y + transform.m32(), transform); + hashSceneItem(element, videoItem); + + if (mGSectionContainer) + { + addItemToGSection(videoItem); + } + + return true; +} + +void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgSectionAttr(const QDomElement &svgSection) +{ + getViewBoxDimenstions(svgSection.attribute(aViewbox)); + mSize = QSize(svgSection.attribute(aWidth).toInt(), + svgSection.attribute(aHeight).toInt()); +} + +void UBCFFSubsetAdaptor::UBCFFSubsetReader::addItemToGSection(QGraphicsItem *item) +{ + mGSectionContainer->addToGroup(item); +} + +void UBCFFSubsetAdaptor::UBCFFSubsetReader::hashSceneItem(const QDomElement &element, UBGraphicsItem *item) +{ +// adding element pointer to hash to refer if needed + QString key = element.attribute(aId); + if (!key.isNull()) { + persistedItems.insert(key, item); + } +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgElement(const QDomElement &parent) +{ + QString tagName = parent.tagName(); + if (parent.namespaceURI() != svgNS) { + qWarning() << "Incorrect namespace, error at content file, line number" << parent.lineNumber(); + //return false; + } + + if (tagName == tG && !parseGSection(parent)) return false; + else if (tagName == tSwitch && !parseSvgSwitchSection(parent)) return false; + else if (tagName == tRect && !parseSvgRect(parent)) return false; + else if (tagName == tEllipse && !parseSvgEllipse(parent)) return false; + else if (tagName == tPolygon && !parseSvgPolygon(parent)) return false; + else if (tagName == tPolyline && !parseSvgPolyline(parent)) return false; + else if (tagName == tText && !parseSvgText(parent)) return false; + else if (tagName == tTextarea && !parseSvgTextarea(parent)) return false; + else if (tagName == tImage && !parseSvgImage(parent)) return false; + else if (tagName == tFlash && !parseSvgFlash(parent)) return false; + else if (tagName == tAudio && !parseSvgAudio(parent)) return false; + else if (tagName == tVideo && !parseSvgVideo(parent)) return false; + + return true; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPage(const QDomElement &parent) +{ + createNewScene(); + QDomElement currentSvgElement = parent.firstChildElement(); + while (!currentSvgElement.isNull()) { + if (!parseSvgElement(currentSvgElement)) + return false; + + currentSvgElement = currentSvgElement.nextSiblingElement(); + } + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPageset(const QDomElement &parent) +{ + QDomElement currentPage = parent.firstChildElement(tPage); + while (!currentPage.isNull()) { + if (!parseSvgPage(currentPage)) + return false; + currentPage = currentPage.nextSiblingElement(tPage); + } + return true; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbMeta(const QDomElement &element) +{ + if (element.namespaceURI() != iwbNS) { + qWarning() << "incorrect meta namespace, incorrect document"; + //return false; + } + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvg(const QDomElement &svgSection) +{ + if (svgSection.namespaceURI() != svgNS) { + qWarning() << "incorrect svg namespace, incorrect document"; + // return false; + } + + parseSvgSectionAttr(svgSection); + QDomElement currentSvg = svgSection.firstChildElement(); + + if (currentSvg.tagName() != tPageset) { + parseSvgPage(svgSection); + } else if (currentSvg.tagName() == tPageset){ + parseSvgPageset(currentSvg); + } + + return true; +} + +UBGraphicsGroupContainerItem *UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbGroup(QDomElement &parent) +{ + //TODO. Create groups from elements parsed by parseIwbElement() function + if (parent.namespaceURI() != iwbNS) { + qWarning() << "incorrect iwb group namespace, incorrect document"; + // return false; + } + + UBGraphicsGroupContainerItem *group = new UBGraphicsGroupContainerItem(); + QMultiMap strokesGroupsContainer; + QList groupContainer; + QString currentStrokeIdentifier; + + QDomElement currentStrokeElement = parent.firstChildElement(); + while (!currentStrokeElement.isNull()) + { + if (tGroup == currentStrokeElement.tagName()) + group->addToGroup(parseIwbGroup(currentStrokeElement)); + else + { + + QString ref = currentStrokeElement.attribute(aRef); + QString uuid = mRefToUuidMap[ref]; + if (!uuid.isEmpty()) + { + if (ref.size() > QUuid().toString().length()) // create stroke group + { + currentStrokeIdentifier = ref.left(QUuid().toString().length()-1); + UBGraphicsPolygonItem *strokeByUuid = qgraphicsitem_cast(mCurrentScene->itemForUuid(QUuid(ref.right(QUuid().toString().length())))); + + if (strokeByUuid) + strokesGroupsContainer.insert(currentStrokeIdentifier, strokeByUuid); + } + else // single elements in group + groupContainer.append(mCurrentScene->itemForUuid(QUuid(uuid))); + } + } + currentStrokeElement = currentStrokeElement.nextSiblingElement(); + } + + + + foreach (QString key, strokesGroupsContainer.keys().toSet()) + { + UBGraphicsStrokesGroup* pStrokesGroup = new UBGraphicsStrokesGroup(); + UBGraphicsStroke *currentStroke = new UBGraphicsStroke(); + foreach(UBGraphicsPolygonItem* poly, strokesGroupsContainer.values(key)) + { + if (poly) + { + mCurrentScene->removeItem(poly); + mCurrentScene->removeItemFromDeletion(poly); + poly->setStrokesGroup(pStrokesGroup); + poly->setStroke(currentStroke); + pStrokesGroup->addToGroup(poly); + } + } + if (currentStroke->polygons().empty()) + delete currentStroke; + + if (pStrokesGroup->childItems().count()) + mCurrentScene->addItem(pStrokesGroup); + else + delete pStrokesGroup; + + if (pStrokesGroup) + { + QGraphicsItem *strokeGroup = qgraphicsitem_cast(pStrokesGroup); + groupContainer.append(strokeGroup); + } + } + + foreach(QGraphicsItem* item, groupContainer) + group->addToGroup(item); + + if (group->childItems().count()) + { + mCurrentScene->addItem(group); + + if (1 == group->childItems().count()) + { + group->destroy(false); + } + } + + return group; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::strToBool(QString str) +{ + return str == "true"; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbElement(QDomElement &element) +{ + if (element.namespaceURI() != iwbNS) { + qWarning() << "incorrect iwb element namespace, incorrect document"; + // return false; + } + + bool locked = false; + bool isEditableItem = false; + bool isEditable = false; //Text items to convert to UBGraphicsTextItem only + + QString IDRef = element.attribute(aRef); + if (!IDRef.isNull()) { + element.hasAttribute(aBackground) ? strToBool(element.attribute(aBackground)) : false; + locked = element.hasAttribute(aBackground) ? strToBool(element.attribute(aBackground)) : false; + isEditableItem = element.hasAttribute(aEditable); + if (isEditableItem) + isEditable = strToBool(element.attribute(aEditable)); + + UBGraphicsItem *referedItem(0); + QHash::iterator iReferedItem; + iReferedItem = persistedItems.find(IDRef); + if (iReferedItem != persistedItems.end()) { + referedItem = *iReferedItem; + referedItem->Delegate()->lock(locked); + } + if (isEditableItem) { + UBGraphicsTextItemDelegate *textDelegate = dynamic_cast(referedItem->Delegate()); + if (textDelegate) { + textDelegate->setEditable(isEditable); + } + } + } + + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseDoc() +{ + QDomElement currentTopElement = mDOMdoc.documentElement().firstChildElement(); + while (!currentTopElement.isNull()) { + QString tagName = currentTopElement.tagName(); + if (tagName == tMeta && !parseIwbMeta(currentTopElement)) return false; + else if (tagName == tSvg && !parseSvg(currentTopElement)) return false; + else if (tagName == tGroup && !parseIwbGroup(currentTopElement)) return false; + else if (tagName == tElement && !parseIwbElement(currentTopElement)) return false; + + currentTopElement = currentTopElement.nextSiblingElement(); + } + if (!persistScenes()) return false; + + return true; +} + +void UBCFFSubsetAdaptor::UBCFFSubsetReader::repositionSvgItem(QGraphicsItem *item, qreal width, qreal height, + qreal x, qreal y, + QTransform &transform) +{ + //First using viebox coordinates, then translate them to scene coordinates + + QRectF itemBounds = item->boundingRect(); + + qreal xScale = width / itemBounds.width(); + qreal yScale = height / itemBounds.height(); + + qreal fullScaleX = mVBTransFactor * xScale; + qreal fullScaleY = mVBTransFactor * yScale; + + QPointF oldVector((x - transform.dx()), (y - transform.dy())); + QTransform rTransform; + QPointF newVector = rTransform.map(oldVector); + + QTransform tr = item->sceneTransform(); + item->setTransform(rTransform.scale(fullScaleX, fullScaleY), true); + tr = item->sceneTransform(); + QPoint pos; + if (UBGraphicsTextItem::Type == item->type()) + pos = QPoint((int)((x + mShiftVector.x() + (newVector - oldVector).x())), (int)((y +mShiftVector.y() + (newVector - oldVector).y()) * mVBTransFactor)); + else + pos = QPoint((int)((x + mShiftVector.x() + (newVector - oldVector).x()) * mVBTransFactor), (int)((y +mShiftVector.y() + (newVector - oldVector).y()) * mVBTransFactor)); + + + item->setPos(pos); +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createNewScene() +{ + mCurrentScene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mProxy, mProxy->pageCount(), false); + mCurrentScene->setSceneRect(mViewBox); + if ((mCurrentScene->sceneRect().topLeft().x() >= 0) || (mCurrentScene->sceneRect().topLeft().y() >= 0)) { + mShiftVector = -mViewBox.center(); + } + mCurrentSceneRect = mViewBox; + mVBTransFactor = qMin(mCurrentScene->normalizedSceneRect().width() / mViewPort.width(), + mCurrentScene->normalizedSceneRect().height() / mViewPort.height()); + return true; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::persistCurrentScene() +{ + if (mCurrentScene != 0 && mCurrentScene->isModified()) + { + UBThumbnailAdaptor::persistScene(mProxy, mCurrentScene, mProxy->pageCount() - 1); + UBSvgSubsetAdaptor::persistScene(mProxy, mCurrentScene, mProxy->pageCount() - 1); + + mCurrentScene->setModified(false); + mCurrentScene = 0; + } + return true; +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::persistScenes() +{ + if (!mProxy->pageCount()) { + qDebug() << "No pages created"; + return false; + } + for (int i = 0; i < mProxy->pageCount(); i++) { + mCurrentScene = UBPersistenceManager::persistenceManager()->getDocumentScene(mProxy, i); + if (!mCurrentScene) { + qDebug() << "can't allocate scene, loading failed"; + return false; + } + + UBSvgSubsetAdaptor::persistScene(mProxy, mCurrentScene, i); + UBGraphicsScene *tmpScene = UBSvgSubsetAdaptor::loadScene(mProxy, i); + tmpScene->setModified(true); + UBThumbnailAdaptor::persistScene(mProxy, tmpScene, i); + mCurrentScene->setModified(false); + } + + return true; +} + +QColor UBCFFSubsetAdaptor::UBCFFSubsetReader::colorFromString(const QString& clrString) +{ + //init regexp with pattern + //pattern corresponds to strings like 'rgb(1,2,3) or rgb(10%,20%,30%)' + QRegExp regexp("rgb\\(([0-9]+%{0,1}),([0-9]+%{0,1}),([0-9]+%{0,1})\\)"); + if (regexp.exactMatch(clrString)) + { + if (regexp.capturedTexts().count() == 4 && regexp.capturedTexts().at(0).length() == clrString.length()) + { + int r = regexp.capturedTexts().at(1).toInt(); + if (regexp.capturedTexts().at(1).indexOf("%") != -1) + r = r * 255 / 100; + int g = regexp.capturedTexts().at(2).toInt(); + if (regexp.capturedTexts().at(2).indexOf("%") != -1) + g = g * 255 / 100; + int b = regexp.capturedTexts().at(3).toInt(); + if (regexp.capturedTexts().at(3).indexOf("%") != -1) + b = b * 255 / 100; + return QColor(r, g, b); + } + else + return QColor(); + } + else + return QColor(clrString); +} + +QTransform UBCFFSubsetAdaptor::UBCFFSubsetReader::transformFromString(const QString trString, QGraphicsItem *item) +{ + qreal dxr = 0.0; + qreal dyr = 0.0; + qreal dx = 0.0; + qreal dy = 0.0; + qreal angle = 0.0; + QTransform tr; + + foreach(QString trStr, trString.split(" ", QString::SkipEmptyParts)) + { + //check pattern for strings like 'rotate(10)' + QRegExp regexp("rotate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *\\)"); + if (regexp.exactMatch(trStr)) { + angle = regexp.capturedTexts().at(1).toDouble(); + if (item) + { + item->setTransformOriginPoint(QPointF(0, 0)); + item->rotate(angle); + } + continue; + }; + + //check pattern for strings like 'rotate(10,20,20)' or 'rotate(10.1,10.2,34.2)' + regexp.setPattern("rotate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *, *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *, *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *\\)"); + if (regexp.exactMatch(trStr)) { + angle = regexp.capturedTexts().at(1).toDouble(); + dxr = regexp.capturedTexts().at(2).toDouble(); + dyr = regexp.capturedTexts().at(3).toDouble(); + if (item) + { + item->setTransformOriginPoint(QPointF(dxr, dyr)-item->pos()); + item->rotate(angle); + } + continue; + } + + //check pattern for strings like 'translate(11.0, 12.34)' + regexp.setPattern("translate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *,*([-+]{0,1}[0-9]*\\.{0,1}[0-9]*)*\\)"); + if (regexp.exactMatch(trStr)) { + dx = regexp.capturedTexts().at(1).toDouble(); + dy = regexp.capturedTexts().at(2).toDouble(); + tr.translate(dx,dy); + continue; + } + } + return tr; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getViewBoxDimenstions(const QString& viewBox) +{ + QStringList capturedTexts = viewBox.split(" ", QString::SkipEmptyParts); + if (capturedTexts.count()) + { + if (4 == capturedTexts.count()) + { + mViewBox = QRectF(capturedTexts.at(0).toDouble(), capturedTexts.at(1).toDouble(), capturedTexts.at(2).toDouble(), capturedTexts.at(3).toDouble()); + mViewPort = mViewBox; + mViewPort.translate(- mViewPort.center()); + mViewBoxCenter.setX(mViewBox.width() / 2); + mViewBoxCenter.setY(mViewBox.height() / 2); + + return true; + } + } + + mViewBox = QRectF(0, 0, 1000, 1000); + mViewBoxCenter = QPointF(500, 500); + return false; +} + +QSvgGenerator* UBCFFSubsetAdaptor::UBCFFSubsetReader::createSvgGenerator(qreal width, qreal height) +{ + QSvgGenerator* generator = new QSvgGenerator(); +// qWarning() << QString("Making generator with file %1, size (%2, %3) and viewbox (%4 %5 %6 %7)").arg(mTempFilePath) +// .arg(width).arg(height).arg(0.0).arg(0.0).arg(width).arg(width); + generator->setResolution(QApplication::desktop()->physicalDpiY()); + generator->setFileName(mTempFilePath); + generator->setSize(QSize(width, height)); + generator->setViewBox(QRectF(0, 0, width, height)); + + return generator; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getTempFileName() +{ + int tmpNumber = 0; + QDir rootDir; + while (true) + { + mTempFilePath = QString("%1/sanksvg%2.%3") + .arg(rootDir.tempPath()) + .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm")) + .arg(tmpNumber); + if (!QFile::exists(mTempFilePath)) + return true; + tmpNumber++; + if (tmpNumber == 100000) + { + qWarning() << "Import failed. Failed to create temporary file for svg objects"; + return false; + } + } +} +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createTempFlashPath() +{ + int tmpNumber = 0; + QDir systemTmp = QDir::temp(); + + while (true) { + QString dirName = QString("SankTmpFlash%1.%2") + .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm")) + .arg(tmpNumber++); + if (!systemTmp.exists(dirName)) { + if (systemTmp.mkdir(dirName)) { + mTmpFlashDir = QDir(systemTmp.absolutePath() + "/" + dirName); + return true; + } else { + qDebug() << "Can't create temporary dir maybe due to permissions"; + return false; + } + } else if (tmpNumber == 1000) { + qWarning() << "Import failed. Failed to create temporary file for svg objects"; + return false; + } + } + + return true; +} +UBCFFSubsetAdaptor::UBCFFSubsetReader::~UBCFFSubsetReader() +{ +// QList pages; +// for (int i = 0; i < mProxy->pageCount(); i++) { +// pages << i; +// } +// UBPersistenceManager::persistenceManager()->deleteDocumentScenes(mProxy, pages); +} diff --git a/src/adaptors/UBCFFSubsetAdaptor.h b/src/adaptors/UBCFFSubsetAdaptor.h index 56e7afdd..5e6e7df3 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.h +++ b/src/adaptors/UBCFFSubsetAdaptor.h @@ -19,135 +19,135 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBCFFSUBSETADAPTOR_H -#define UBCFFSUBSETADAPTOR_H - -#include -#include -#include -#include -#include - -class UBDocumentProxy; -class UBGraphicsScene; -class QSvgGenerator; -class UBGraphicsSvgItem; -class UBGraphicsPixmapItem; -class UBGraphicsItemDelegate; -class QTransform; -class QPainter; -class UBGraphicsItem; -class QGraphicsItem; -class QTextBlockFormat; -class QTextCharFormat; -class QTextCursor; -class UBGraphicsStrokesGroup; - - -class UBCFFSubsetAdaptor -{ -public: - UBCFFSubsetAdaptor(); - static bool ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentProxy* pDocument); - -private: - class UBCFFSubsetReader - { - public: - UBCFFSubsetReader(UBDocumentProxy *proxy, QFile *content); - ~UBCFFSubsetReader(); - - UBDocumentProxy *mProxy; - QString pwdContent; - - bool parse(); - - private: - QString mTempFilePath; - UBGraphicsScene *mCurrentScene; - QRectF mCurrentSceneRect; - QString mIndent; - QRectF mViewBox; - QRectF mViewPort; - qreal mVBTransFactor; - QPointF mViewBoxCenter; - QSize mSize; - QPointF mShiftVector; - bool mSvgGSectionIsOpened; - UBGraphicsGroupContainerItem *mGSectionContainer; - - private: - QDomDocument mDOMdoc; - QDomNode mCurrentDOMElement; - QHash persistedItems; - QMap mRefToUuidMap; - QDir mTmpFlashDir; - - void addItemToGSection(QGraphicsItem *item); - bool hashElements(); - void addExtentionsToHash(QDomElement *parent, QDomElement *topGroup); - - void hashSvg(QDomNode *parent, QString prefix = ""); - void hashSiblingIwbElements(QDomElement *parent, QDomElement *topGroup = 0); - - inline void parseSvgSectionAttr(const QDomElement &); - bool parseSvgPage(const QDomElement &parent); - bool parseSvgPageset(const QDomElement &parent); - bool parseSvgElement(const QDomElement &parent); - bool parseIwbMeta(const QDomElement &element); - bool parseSvg(const QDomElement &svgSection); - - inline bool parseGSection(const QDomElement &element); - inline bool parseSvgSwitchSection(const QDomElement &element); - inline bool parseSvgRect(const QDomElement &element); - inline bool parseSvgEllipse(const QDomElement &element); - inline bool parseSvgPolygon(const QDomElement &element); - inline bool parseSvgPolyline(const QDomElement &element); - inline bool parseSvgText(const QDomElement &element); - inline bool parseSvgTextarea(const QDomElement &element); - inline bool parseSvgImage(const QDomElement &element); - inline bool parseSvgFlash(const QDomElement &element); - inline bool parseSvgAudio(const QDomElement &element); - inline bool parseSvgVideo(const QDomElement &element); - inline UBGraphicsGroupContainerItem *parseIwbGroup(QDomElement &parent); - inline bool parseIwbElement(QDomElement &element); - inline void parseTSpan(const QDomElement &parent, QPainter &painter - , qreal &curX, qreal &curY, qreal &width, qreal &height, qreal &linespacing, QRectF &lastDrawnTextBoundingRect - , qreal &fontSize, QColor &fontColor, QString &fontFamily, QString &fontStretch, bool &italic - , int &fontWeight, int &textAlign, QTransform &fontTransform); - inline void parseTSpan(const QDomElement &element, QTextCursor &cursor - , QTextBlockFormat &blockFormat, QTextCharFormat &charFormat); - inline void hashSceneItem(const QDomElement &element, UBGraphicsItem *item); - - // to kill - inline void parseTextAttributes(const QDomElement &element, qreal &fontSize, QColor &fontColor, - QString &fontFamily, QString &fontStretch, bool &italic, - int &fontWeight, int &textAlign, QTransform &fontTransform); - inline void parseTextAttributes(const QDomElement &element, QFont &font, QColor); - inline void readTextBlockAttr(const QDomElement &element, QTextBlockFormat &format); - inline void readTextCharAttr(const QDomElement &element, QTextCharFormat &format); - - //elements parsing methods - bool parseDoc(); - - bool createNewScene(); - bool persistCurrentScene(); - bool persistScenes(); - -// helper methods - void repositionSvgItem(QGraphicsItem *item, qreal width, qreal height, - qreal x, qreal y, - QTransform &transform); - QColor colorFromString(const QString& clrString); - QTransform transformFromString(const QString trString, QGraphicsItem *item = 0); - bool getViewBoxDimenstions(const QString& viewBox); - QSvgGenerator* createSvgGenerator(qreal width, qreal height); - bool getTempFileName(); - inline bool strToBool(QString); - bool createTempFlashPath(); - }; -}; - -#endif // UBCFFSUBSETADAPTOR_H + + +#ifndef UBCFFSUBSETADAPTOR_H +#define UBCFFSUBSETADAPTOR_H + +#include +#include +#include +#include +#include + +class UBDocumentProxy; +class UBGraphicsScene; +class QSvgGenerator; +class UBGraphicsSvgItem; +class UBGraphicsPixmapItem; +class UBGraphicsItemDelegate; +class QTransform; +class QPainter; +class UBGraphicsItem; +class QGraphicsItem; +class QTextBlockFormat; +class QTextCharFormat; +class QTextCursor; +class UBGraphicsStrokesGroup; + + +class UBCFFSubsetAdaptor +{ +public: + UBCFFSubsetAdaptor(); + static bool ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentProxy* pDocument); + +private: + class UBCFFSubsetReader + { + public: + UBCFFSubsetReader(UBDocumentProxy *proxy, QFile *content); + ~UBCFFSubsetReader(); + + UBDocumentProxy *mProxy; + QString pwdContent; + + bool parse(); + + private: + QString mTempFilePath; + UBGraphicsScene *mCurrentScene; + QRectF mCurrentSceneRect; + QString mIndent; + QRectF mViewBox; + QRectF mViewPort; + qreal mVBTransFactor; + QPointF mViewBoxCenter; + QSize mSize; + QPointF mShiftVector; + bool mSvgGSectionIsOpened; + UBGraphicsGroupContainerItem *mGSectionContainer; + + private: + QDomDocument mDOMdoc; + QDomNode mCurrentDOMElement; + QHash persistedItems; + QMap mRefToUuidMap; + QDir mTmpFlashDir; + + void addItemToGSection(QGraphicsItem *item); + bool hashElements(); + void addExtentionsToHash(QDomElement *parent, QDomElement *topGroup); + + void hashSvg(QDomNode *parent, QString prefix = ""); + void hashSiblingIwbElements(QDomElement *parent, QDomElement *topGroup = 0); + + inline void parseSvgSectionAttr(const QDomElement &); + bool parseSvgPage(const QDomElement &parent); + bool parseSvgPageset(const QDomElement &parent); + bool parseSvgElement(const QDomElement &parent); + bool parseIwbMeta(const QDomElement &element); + bool parseSvg(const QDomElement &svgSection); + + inline bool parseGSection(const QDomElement &element); + inline bool parseSvgSwitchSection(const QDomElement &element); + inline bool parseSvgRect(const QDomElement &element); + inline bool parseSvgEllipse(const QDomElement &element); + inline bool parseSvgPolygon(const QDomElement &element); + inline bool parseSvgPolyline(const QDomElement &element); + inline bool parseSvgText(const QDomElement &element); + inline bool parseSvgTextarea(const QDomElement &element); + inline bool parseSvgImage(const QDomElement &element); + inline bool parseSvgFlash(const QDomElement &element); + inline bool parseSvgAudio(const QDomElement &element); + inline bool parseSvgVideo(const QDomElement &element); + inline UBGraphicsGroupContainerItem *parseIwbGroup(QDomElement &parent); + inline bool parseIwbElement(QDomElement &element); + inline void parseTSpan(const QDomElement &parent, QPainter &painter + , qreal &curX, qreal &curY, qreal &width, qreal &height, qreal &linespacing, QRectF &lastDrawnTextBoundingRect + , qreal &fontSize, QColor &fontColor, QString &fontFamily, QString &fontStretch, bool &italic + , int &fontWeight, int &textAlign, QTransform &fontTransform); + inline void parseTSpan(const QDomElement &element, QTextCursor &cursor + , QTextBlockFormat &blockFormat, QTextCharFormat &charFormat); + inline void hashSceneItem(const QDomElement &element, UBGraphicsItem *item); + + // to kill + inline void parseTextAttributes(const QDomElement &element, qreal &fontSize, QColor &fontColor, + QString &fontFamily, QString &fontStretch, bool &italic, + int &fontWeight, int &textAlign, QTransform &fontTransform); + inline void parseTextAttributes(const QDomElement &element, QFont &font, QColor); + inline void readTextBlockAttr(const QDomElement &element, QTextBlockFormat &format); + inline void readTextCharAttr(const QDomElement &element, QTextCharFormat &format); + + //elements parsing methods + bool parseDoc(); + + bool createNewScene(); + bool persistCurrentScene(); + bool persistScenes(); + +// helper methods + void repositionSvgItem(QGraphicsItem *item, qreal width, qreal height, + qreal x, qreal y, + QTransform &transform); + QColor colorFromString(const QString& clrString); + QTransform transformFromString(const QString trString, QGraphicsItem *item = 0); + bool getViewBoxDimenstions(const QString& viewBox); + QSvgGenerator* createSvgGenerator(qreal width, qreal height); + bool getTempFileName(); + inline bool strToBool(QString); + bool createTempFlashPath(); + }; +}; + +#endif // UBCFFSUBSETADAPTOR_H diff --git a/src/adaptors/UBImportCFF.cpp b/src/adaptors/UBImportCFF.cpp index 8adf42a6..f8b2cca6 100644 --- a/src/adaptors/UBImportCFF.cpp +++ b/src/adaptors/UBImportCFF.cpp @@ -19,270 +19,270 @@ * along with Open-Sankoré. If not, see . */ - - -#include -#include - -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBDocumentManager.h" -#include "core/UBPersistenceManager.h" -#include "document/UBDocumentProxy.h" -#include "domain/UBGraphicsPDFItem.h" -#include "frameworks/UBFileSystemUtils.h" -#include "pdf/PDFRenderer.h" - -#include "UBCFFSubsetAdaptor.h" -#include "UBImportCFF.h" - -#include "globals/UBGlobals.h" - -THIRD_PARTY_WARNINGS_DISABLE -#include "quazip.h" -#include "quazipfile.h" -#include "quazipfileinfo.h" -THIRD_PARTY_WARNINGS_ENABLE - -#include "core/memcheck.h" - -UBImportCFF::UBImportCFF(QObject *parent) - : UBDocumentBasedImportAdaptor(parent) -{ - // NOOP -} - - -UBImportCFF::~UBImportCFF() -{ - // NOOP -} - - -QStringList UBImportCFF::supportedExtentions() -{ - return QStringList("iwb"); -} - - -QString UBImportCFF::importFileFilter() -{ - QString filter = tr("Common File Format ("); - QStringList formats = supportedExtentions(); - bool isFirst = true; - - foreach(QString format, formats) - { - if(isFirst) - isFirst = false; - else - filter.append(" "); - - filter.append("*."+format); - } - - filter.append(")"); - - return filter; -} - -bool UBImportCFF::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile) -{ - QFileInfo fi(pFile); - UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true); - - // first unzip the file to the correct place - //TODO create temporary path for iwb file content - QString path = QDir::tempPath(); - - QString documentRootFolder = expandFileToDir(pFile, path); - QString contentFile; - if (documentRootFolder.isEmpty()) //if file has failed to unzip it is probably just xml file - contentFile = pFile.fileName(); - else //get path to content xml (according to iwbcff specification) - contentFile = documentRootFolder.append("/content.xml"); - - if(!contentFile.length()){ - UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName())); - return false; - } - else{ - //TODO convert expanded CFF file content to the destination document - //create destination document proxy - //fill metadata and save - UBDocumentProxy* destDocument = new UBDocumentProxy(UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath()); - QDir dir; - dir.mkdir(destDocument->persistencePath()); - - //try to import cff to document - if (UBCFFSubsetAdaptor::ConvertCFFFileToUbz(contentFile, destDocument)) - { - UBPersistenceManager::persistenceManager()->addDirectoryContentToDocument(destDocument->persistencePath(), pDocument); - UBFileSystemUtils::deleteDir(destDocument->persistencePath()); - delete destDocument; - UBApplication::showMessage(tr("Import successful.")); - return true; - } - else - { - UBFileSystemUtils::deleteDir(destDocument->persistencePath()); - delete destDocument; - UBApplication::showMessage(tr("Import failed.")); - return false; - } - } -} - -QString UBImportCFF::expandFileToDir(const QFile& pZipFile, const QString& pDir) -{ - QuaZip zip(pZipFile.fileName()); - - if(!zip.open(QuaZip::mdUnzip)) { - qWarning() << "Import failed. Cause zip.open(): " << zip.getZipError(); - return ""; - } - - zip.setFileNameCodec("UTF-8"); - QuaZipFileInfo info; - QuaZipFile file(&zip); - - //create unique cff document root fodler - //use current date/time and temp number for folder name - QString documentRootFolder; - int tmpNumber = 0; - QDir rootDir; - while (true) { - QString tempPath = QString("%1/sank%2.%3") - .arg(pDir) - .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm")) - .arg(tmpNumber); - if (!rootDir.exists(tempPath)) { - documentRootFolder = tempPath; - break; - } - tmpNumber++; - if (tmpNumber == 100000) { - qWarning() << "Import failed. Failed to create temporary directory for iwb file"; - return ""; - } - } - if (!rootDir.mkdir(documentRootFolder)) { - qWarning() << "Import failed. Couse: failed to create temp folder for cff package"; - } - - QFile out; - char c; - for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { - if(!zip.getCurrentFileInfo(&info)) { - //TOD UB 4.3 O display error to user or use crash reporter - qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError(); - return ""; - } -// if(!file.open(QIODevice::ReadOnly)) { -// qWarning() << "Import failed. Cause: file.open(): " << zip.getZipError(); -// return ""; -// } - file.open(QIODevice::ReadOnly); - if(file.getZipError()!= UNZ_OK) { - qWarning() << "Import failed. Cause: file.getFileName(): " << zip.getZipError(); - return ""; - } - - QString newFileName = documentRootFolder + "/" + file.getActualFileName(); - - QFileInfo newFileInfo(newFileName); - rootDir.mkpath(newFileInfo.absolutePath()); - - out.setFileName(newFileName); - out.open(QIODevice::WriteOnly); - - while(file.getChar(&c)) - out.putChar(c); - - out.close(); - - if(file.getZipError()!=UNZ_OK) { - qWarning() << "Import failed. Cause: " << zip.getZipError(); - return ""; - } - if(!file.atEnd()) { - qWarning() << "Import failed. Cause: read all but not EOF"; - return ""; - } - - file.close(); - - if(file.getZipError()!=UNZ_OK) { - qWarning() << "Import failed. Cause: file.close(): " << file.getZipError(); - return ""; - } - } - - zip.close(); - - if(zip.getZipError()!=UNZ_OK) { - qWarning() << "Import failed. Cause: zip.close(): " << zip.getZipError(); - return ""; - } - - return documentRootFolder; -} - - -UBDocumentProxy* UBImportCFF::importFile(const QFile& pFile, const QString& pGroup) -{ - Q_UNUSED(pGroup); // group is defined in the imported file - - QFileInfo fi(pFile); - UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true); - - // first unzip the file to the correct place - //TODO create temporary path for iwb file content - QString path = QDir::tempPath(); - - QString documentRootFolder = expandFileToDir(pFile, path); - QString contentFile; - if (documentRootFolder.isEmpty()) - //if file has failed to umzip it is probably just xml file - contentFile = pFile.fileName(); - else - //get path to content xml - contentFile = QString("%1/content.xml").arg(documentRootFolder); - - if(!contentFile.length()){ - UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName())); - return 0; - } - else{ - //create destination document proxy - //fill metadata and save - UBDocumentProxy* destDocument = new UBDocumentProxy(UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath()); - QDir dir; - dir.mkdir(destDocument->persistencePath()); - if (pGroup.length() > 0) - destDocument->setMetaData(UBSettings::documentGroupName, pGroup); - if (fi.baseName() > 0) - destDocument->setMetaData(UBSettings::documentName, fi.baseName()); - - destDocument->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion); - destDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - UBDocumentProxy* newDocument = NULL; - //try to import cff to document - if (UBCFFSubsetAdaptor::ConvertCFFFileToUbz(contentFile, destDocument)) - { - newDocument = UBPersistenceManager::persistenceManager()->createDocumentFromDir(destDocument->persistencePath()); - UBApplication::showMessage(tr("Import successful.")); - } - else - { - UBFileSystemUtils::deleteDir(destDocument->persistencePath()); - UBApplication::showMessage(tr("Import failed.")); - } - delete destDocument; - - if (documentRootFolder.length() != 0) - UBFileSystemUtils::deleteDir(documentRootFolder); - return newDocument; - } -} + + +#include +#include + +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBDocumentManager.h" +#include "core/UBPersistenceManager.h" +#include "document/UBDocumentProxy.h" +#include "domain/UBGraphicsPDFItem.h" +#include "frameworks/UBFileSystemUtils.h" +#include "pdf/PDFRenderer.h" + +#include "UBCFFSubsetAdaptor.h" +#include "UBImportCFF.h" + +#include "globals/UBGlobals.h" + +THIRD_PARTY_WARNINGS_DISABLE +#include "quazip.h" +#include "quazipfile.h" +#include "quazipfileinfo.h" +THIRD_PARTY_WARNINGS_ENABLE + +#include "core/memcheck.h" + +UBImportCFF::UBImportCFF(QObject *parent) + : UBDocumentBasedImportAdaptor(parent) +{ + // NOOP +} + + +UBImportCFF::~UBImportCFF() +{ + // NOOP +} + + +QStringList UBImportCFF::supportedExtentions() +{ + return QStringList("iwb"); +} + + +QString UBImportCFF::importFileFilter() +{ + QString filter = tr("Common File Format ("); + QStringList formats = supportedExtentions(); + bool isFirst = true; + + foreach(QString format, formats) + { + if(isFirst) + isFirst = false; + else + filter.append(" "); + + filter.append("*."+format); + } + + filter.append(")"); + + return filter; +} + +bool UBImportCFF::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile) +{ + QFileInfo fi(pFile); + UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true); + + // first unzip the file to the correct place + //TODO create temporary path for iwb file content + QString path = QDir::tempPath(); + + QString documentRootFolder = expandFileToDir(pFile, path); + QString contentFile; + if (documentRootFolder.isEmpty()) //if file has failed to unzip it is probably just xml file + contentFile = pFile.fileName(); + else //get path to content xml (according to iwbcff specification) + contentFile = documentRootFolder.append("/content.xml"); + + if(!contentFile.length()){ + UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName())); + return false; + } + else{ + //TODO convert expanded CFF file content to the destination document + //create destination document proxy + //fill metadata and save + UBDocumentProxy* destDocument = new UBDocumentProxy(UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath()); + QDir dir; + dir.mkdir(destDocument->persistencePath()); + + //try to import cff to document + if (UBCFFSubsetAdaptor::ConvertCFFFileToUbz(contentFile, destDocument)) + { + UBPersistenceManager::persistenceManager()->addDirectoryContentToDocument(destDocument->persistencePath(), pDocument); + UBFileSystemUtils::deleteDir(destDocument->persistencePath()); + delete destDocument; + UBApplication::showMessage(tr("Import successful.")); + return true; + } + else + { + UBFileSystemUtils::deleteDir(destDocument->persistencePath()); + delete destDocument; + UBApplication::showMessage(tr("Import failed.")); + return false; + } + } +} + +QString UBImportCFF::expandFileToDir(const QFile& pZipFile, const QString& pDir) +{ + QuaZip zip(pZipFile.fileName()); + + if(!zip.open(QuaZip::mdUnzip)) { + qWarning() << "Import failed. Cause zip.open(): " << zip.getZipError(); + return ""; + } + + zip.setFileNameCodec("UTF-8"); + QuaZipFileInfo info; + QuaZipFile file(&zip); + + //create unique cff document root fodler + //use current date/time and temp number for folder name + QString documentRootFolder; + int tmpNumber = 0; + QDir rootDir; + while (true) { + QString tempPath = QString("%1/sank%2.%3") + .arg(pDir) + .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm")) + .arg(tmpNumber); + if (!rootDir.exists(tempPath)) { + documentRootFolder = tempPath; + break; + } + tmpNumber++; + if (tmpNumber == 100000) { + qWarning() << "Import failed. Failed to create temporary directory for iwb file"; + return ""; + } + } + if (!rootDir.mkdir(documentRootFolder)) { + qWarning() << "Import failed. Couse: failed to create temp folder for cff package"; + } + + QFile out; + char c; + for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { + if(!zip.getCurrentFileInfo(&info)) { + //TOD UB 4.3 O display error to user or use crash reporter + qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError(); + return ""; + } +// if(!file.open(QIODevice::ReadOnly)) { +// qWarning() << "Import failed. Cause: file.open(): " << zip.getZipError(); +// return ""; +// } + file.open(QIODevice::ReadOnly); + if(file.getZipError()!= UNZ_OK) { + qWarning() << "Import failed. Cause: file.getFileName(): " << zip.getZipError(); + return ""; + } + + QString newFileName = documentRootFolder + "/" + file.getActualFileName(); + + QFileInfo newFileInfo(newFileName); + rootDir.mkpath(newFileInfo.absolutePath()); + + out.setFileName(newFileName); + out.open(QIODevice::WriteOnly); + + while(file.getChar(&c)) + out.putChar(c); + + out.close(); + + if(file.getZipError()!=UNZ_OK) { + qWarning() << "Import failed. Cause: " << zip.getZipError(); + return ""; + } + if(!file.atEnd()) { + qWarning() << "Import failed. Cause: read all but not EOF"; + return ""; + } + + file.close(); + + if(file.getZipError()!=UNZ_OK) { + qWarning() << "Import failed. Cause: file.close(): " << file.getZipError(); + return ""; + } + } + + zip.close(); + + if(zip.getZipError()!=UNZ_OK) { + qWarning() << "Import failed. Cause: zip.close(): " << zip.getZipError(); + return ""; + } + + return documentRootFolder; +} + + +UBDocumentProxy* UBImportCFF::importFile(const QFile& pFile, const QString& pGroup) +{ + Q_UNUSED(pGroup); // group is defined in the imported file + + QFileInfo fi(pFile); + UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true); + + // first unzip the file to the correct place + //TODO create temporary path for iwb file content + QString path = QDir::tempPath(); + + QString documentRootFolder = expandFileToDir(pFile, path); + QString contentFile; + if (documentRootFolder.isEmpty()) + //if file has failed to umzip it is probably just xml file + contentFile = pFile.fileName(); + else + //get path to content xml + contentFile = QString("%1/content.xml").arg(documentRootFolder); + + if(!contentFile.length()){ + UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName())); + return 0; + } + else{ + //create destination document proxy + //fill metadata and save + UBDocumentProxy* destDocument = new UBDocumentProxy(UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath()); + QDir dir; + dir.mkdir(destDocument->persistencePath()); + if (pGroup.length() > 0) + destDocument->setMetaData(UBSettings::documentGroupName, pGroup); + if (fi.baseName() > 0) + destDocument->setMetaData(UBSettings::documentName, fi.baseName()); + + destDocument->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion); + destDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + UBDocumentProxy* newDocument = NULL; + //try to import cff to document + if (UBCFFSubsetAdaptor::ConvertCFFFileToUbz(contentFile, destDocument)) + { + newDocument = UBPersistenceManager::persistenceManager()->createDocumentFromDir(destDocument->persistencePath()); + UBApplication::showMessage(tr("Import successful.")); + } + else + { + UBFileSystemUtils::deleteDir(destDocument->persistencePath()); + UBApplication::showMessage(tr("Import failed.")); + } + delete destDocument; + + if (documentRootFolder.length() != 0) + UBFileSystemUtils::deleteDir(documentRootFolder); + return newDocument; + } +} diff --git a/src/adaptors/UBImportCFF.h b/src/adaptors/UBImportCFF.h index ab36b514..7748f5f3 100644 --- a/src/adaptors/UBImportCFF.h +++ b/src/adaptors/UBImportCFF.h @@ -19,32 +19,32 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBIMPORTCFF_H -#define UBIMPORTCFF_H - -#include -#include "UBImportAdaptor.h" - -class UBDocumentProxy; - -class UBImportCFF : public UBDocumentBasedImportAdaptor -{ - Q_OBJECT; - - public: - UBImportCFF(QObject *parent = 0); - virtual ~UBImportCFF(); - - virtual QStringList supportedExtentions(); - virtual QString importFileFilter(); - - virtual bool addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile); - virtual UBDocumentProxy* importFile(const QFile& pFile, const QString& pGroup); - - private: - QString expandFileToDir(const QFile& pZipFile, const QString& pDir); -}; - -#endif // UBIMPORTCFF_H + + +#ifndef UBIMPORTCFF_H +#define UBIMPORTCFF_H + +#include +#include "UBImportAdaptor.h" + +class UBDocumentProxy; + +class UBImportCFF : public UBDocumentBasedImportAdaptor +{ + Q_OBJECT; + + public: + UBImportCFF(QObject *parent = 0); + virtual ~UBImportCFF(); + + virtual QStringList supportedExtentions(); + virtual QString importFileFilter(); + + virtual bool addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile); + virtual UBDocumentProxy* importFile(const QFile& pFile, const QString& pGroup); + + private: + QString expandFileToDir(const QFile& pZipFile, const QString& pDir); +}; + +#endif // UBIMPORTCFF_H diff --git a/src/adaptors/UBSvgSubsetAdaptor.h b/src/adaptors/UBSvgSubsetAdaptor.h index 013a23ce..0d7d2c38 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.h +++ b/src/adaptors/UBSvgSubsetAdaptor.h @@ -19,249 +19,249 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBSVGSUBSETADAPTOR_H_ -#define UBSVGSUBSETADAPTOR_H_ - -#include -#include - -#include "frameworks/UBGeometryUtils.h" - -class UBGraphicsSvgItem; -class UBGraphicsPolygonItem; -class UBGraphicsPixmapItem; -class UBGraphicsPDFItem; -class UBGraphicsWidgetItem; -class UBGraphicsMediaItem; -class UBGraphicsAppleWidgetItem; -class UBGraphicsW3CWidgetItem; -class UBGraphicsTextItem; -class UBGraphicsCurtainItem; -class UBGraphicsRuler; -class UBGraphicsCompass; -class UBGraphicsProtractor; -class UBGraphicsScene; -class UBDocumentProxy; -class UBGraphicsStroke; -class UBPersistenceManager; -class UBGraphicsTriangle; -class UBGraphicsCache; -class IDataStorage; -class UBGraphicsGroupContainerItem; -class UBGraphicsStrokesGroup; - -class UBSvgSubsetAdaptor -{ - private: - - UBSvgSubsetAdaptor() {;} - virtual ~UBSvgSubsetAdaptor() {;} - - public: - - static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const int pageIndex); - static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); - static void upgradeScene(UBDocumentProxy* proxy, const int pageIndex); - - static QUuid sceneUuid(UBDocumentProxy* proxy, const int pageIndex); - static void setSceneUuid(UBDocumentProxy* proxy, const int pageIndex, QUuid pUuid); - - static bool addElementToBeStored(QString domName,IDataStorage* dataStorageClass); - - static void convertPDFObjectsToImages(UBDocumentProxy* proxy); - static void convertSvgImagesToImages(UBDocumentProxy* proxy); - - static QMap getAdditionalElementToStore() { return additionalElementToStore;} - - static const QString nsSvg; - static const QString nsXLink; - static const QString nsXHtml; - static const QString nsUb; - static const QString xmlTrue; - static const QString xmlFalse; - - static const QString sFontSizePrefix; - static const QString sPixelUnit; - static const QString sFontWeightPrefix; - static const QString sFontStylePrefix; - - static QString readTeacherGuideNode(int sceneIndex); - private: - - static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const QByteArray& pArray); - - static QDomDocument loadSceneDocument(UBDocumentProxy* proxy, const int pPageIndex); - - static QString uniboardDocumentNamespaceUriFromVersion(int fileVersion); - - static const QString sFormerUniboardDocumentNamespaceUri; - - static QString toSvgTransform(const QMatrix& matrix); - static QMatrix fromSvgTransform(const QString& transform); - - static QMap additionalElementToStore; - - - - - class UBSvgSubsetReader - { - public: - - UBSvgSubsetReader(UBDocumentProxy* proxy, const QByteArray& pXmlData); - - virtual ~UBSvgSubsetReader(){} - - UBGraphicsScene* loadScene(); - - private: - - UBGraphicsPolygonItem* polygonItemFromLineSvg(const QColor& pDefaultBrushColor); - - UBGraphicsPolygonItem* polygonItemFromPolygonSvg(const QColor& pDefaultBrushColor); - - QList polygonItemsFromPolylineSvg(const QColor& pDefaultColor); - - UBGraphicsPixmapItem* pixmapItemFromSvg(); - - UBGraphicsSvgItem* svgItemFromSvg(); - - UBGraphicsPDFItem* pdfItemFromPDF(); - - UBGraphicsMediaItem* videoItemFromSvg(); - - UBGraphicsMediaItem* audioItemFromSvg(); - - UBGraphicsAppleWidgetItem* graphicsAppleWidgetFromSvg(); - - UBGraphicsW3CWidgetItem* graphicsW3CWidgetFromSvg(); - - UBGraphicsTextItem* textItemFromSvg(); - - UBGraphicsCurtainItem* curtainItemFromSvg(); - - UBGraphicsRuler* rulerFromSvg(); - - UBGraphicsCompass* compassFromSvg(); - - UBGraphicsProtractor* protractorFromSvg(); - - UBGraphicsTriangle* triangleFromSvg(); - - UBGraphicsCache* cacheFromSvg(); - - void readGroupRoot(); - QGraphicsItem *readElementFromGroup(); - UBGraphicsGroupContainerItem* readGroup(); - - void graphicsItemFromSvg(QGraphicsItem* gItem); - - qreal getZValueFromSvg(); - QUuid getUuidFromSvg(); - - QXmlStreamReader mXmlReader; - int mFileVersion; - UBDocumentProxy *mProxy; - QString mDocumentPath; - - QColor mGroupDarkBackgroundColor; - QColor mGroupLightBackgroundColor; - qreal mGroupZIndex; - bool mGroupHasInfo; - - QString mNamespaceUri; - UBGraphicsScene *mScene; - - QMap mStrokesList; - }; - - class UBSvgSubsetWriter - { - public: - - UBSvgSubsetWriter(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); - - bool persistScene(int pageIndex); - - virtual ~UBSvgSubsetWriter(){} - - private: - - void persistGroupToDom(QGraphicsItem *groupItem, QDomElement *curParent, QDomDocument *curDomDocument); - void persistStrokeToDom(QGraphicsItem *strokeItem, QDomElement *curParent, QDomDocument *curDomDocument); - void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); - void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); - void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo); - void strokeToSvgPolygon(UBGraphicsStroke* stroke, bool groupHoldsInfo); - - inline QString pointsToSvgPointsAttribute(QVector points) - { - UBGeometryUtils::crashPointList(points); - - int pointsCount = points.size(); - QString svgPoints; - - int length = 0; - QString sBuf; - - for(int j = 0; j < pointsCount; j++) - { - sBuf = "%1,%2 "; - const QPointF & point = points.at(j); - - QString temp1 = "%1", temp2 = "%2"; - - temp1 = temp1.arg(point.x()); - temp2 = temp2.arg(point.y()); - - QLocale loc(QLocale::C); - sBuf = sBuf.arg(loc.toFloat(temp1)).arg(loc.toFloat(temp2)); - - svgPoints.insert(length, sBuf); - length += sBuf.length(); - } - return svgPoints; - } - - inline qreal trickAlpha(qreal alpha) - { - qreal trickAlpha = alpha; - if(trickAlpha >= 0.2 && trickAlpha < 0.6){ - trickAlpha /= 5; - }else if (trickAlpha < 0.8) - trickAlpha /= 3; - - return trickAlpha; - } - - void pixmapItemToLinkedImage(UBGraphicsPixmapItem *pixmapItem); - void svgItemToLinkedSvg(UBGraphicsSvgItem *svgItem); - void pdfItemToLinkedPDF(UBGraphicsPDFItem *pdfItem); - void videoItemToLinkedVideo(UBGraphicsMediaItem *videoItem); - void audioItemToLinkedAudio(UBGraphicsMediaItem *audioItem); - void graphicsItemToSvg(QGraphicsItem *item); - void graphicsAppleWidgetToSvg(UBGraphicsAppleWidgetItem *item); - void graphicsW3CWidgetToSvg(UBGraphicsW3CWidgetItem *item); - void graphicsWidgetToSvg(UBGraphicsWidgetItem *item); - void textItemToSvg(UBGraphicsTextItem *item); - void curtainItemToSvg(UBGraphicsCurtainItem *item); - void rulerToSvg(UBGraphicsRuler *item); - void compassToSvg(UBGraphicsCompass *item); - void protractorToSvg(UBGraphicsProtractor *item); - void cacheToSvg(UBGraphicsCache* item); - void triangleToSvg(UBGraphicsTriangle *item); - void writeSvgElement(); - - private: - - UBGraphicsScene* mScene; - QXmlStreamWriter mXmlWriter; - QString mDocumentPath; - int mPageIndex; - - }; -}; - -#endif /* UBSVGSUBSETADAPTOR_H_ */ + + +#ifndef UBSVGSUBSETADAPTOR_H_ +#define UBSVGSUBSETADAPTOR_H_ + +#include +#include + +#include "frameworks/UBGeometryUtils.h" + +class UBGraphicsSvgItem; +class UBGraphicsPolygonItem; +class UBGraphicsPixmapItem; +class UBGraphicsPDFItem; +class UBGraphicsWidgetItem; +class UBGraphicsMediaItem; +class UBGraphicsAppleWidgetItem; +class UBGraphicsW3CWidgetItem; +class UBGraphicsTextItem; +class UBGraphicsCurtainItem; +class UBGraphicsRuler; +class UBGraphicsCompass; +class UBGraphicsProtractor; +class UBGraphicsScene; +class UBDocumentProxy; +class UBGraphicsStroke; +class UBPersistenceManager; +class UBGraphicsTriangle; +class UBGraphicsCache; +class IDataStorage; +class UBGraphicsGroupContainerItem; +class UBGraphicsStrokesGroup; + +class UBSvgSubsetAdaptor +{ + private: + + UBSvgSubsetAdaptor() {;} + virtual ~UBSvgSubsetAdaptor() {;} + + public: + + static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const int pageIndex); + static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); + static void upgradeScene(UBDocumentProxy* proxy, const int pageIndex); + + static QUuid sceneUuid(UBDocumentProxy* proxy, const int pageIndex); + static void setSceneUuid(UBDocumentProxy* proxy, const int pageIndex, QUuid pUuid); + + static bool addElementToBeStored(QString domName,IDataStorage* dataStorageClass); + + static void convertPDFObjectsToImages(UBDocumentProxy* proxy); + static void convertSvgImagesToImages(UBDocumentProxy* proxy); + + static QMap getAdditionalElementToStore() { return additionalElementToStore;} + + static const QString nsSvg; + static const QString nsXLink; + static const QString nsXHtml; + static const QString nsUb; + static const QString xmlTrue; + static const QString xmlFalse; + + static const QString sFontSizePrefix; + static const QString sPixelUnit; + static const QString sFontWeightPrefix; + static const QString sFontStylePrefix; + + static QString readTeacherGuideNode(int sceneIndex); + private: + + static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const QByteArray& pArray); + + static QDomDocument loadSceneDocument(UBDocumentProxy* proxy, const int pPageIndex); + + static QString uniboardDocumentNamespaceUriFromVersion(int fileVersion); + + static const QString sFormerUniboardDocumentNamespaceUri; + + static QString toSvgTransform(const QMatrix& matrix); + static QMatrix fromSvgTransform(const QString& transform); + + static QMap additionalElementToStore; + + + + + class UBSvgSubsetReader + { + public: + + UBSvgSubsetReader(UBDocumentProxy* proxy, const QByteArray& pXmlData); + + virtual ~UBSvgSubsetReader(){} + + UBGraphicsScene* loadScene(); + + private: + + UBGraphicsPolygonItem* polygonItemFromLineSvg(const QColor& pDefaultBrushColor); + + UBGraphicsPolygonItem* polygonItemFromPolygonSvg(const QColor& pDefaultBrushColor); + + QList polygonItemsFromPolylineSvg(const QColor& pDefaultColor); + + UBGraphicsPixmapItem* pixmapItemFromSvg(); + + UBGraphicsSvgItem* svgItemFromSvg(); + + UBGraphicsPDFItem* pdfItemFromPDF(); + + UBGraphicsMediaItem* videoItemFromSvg(); + + UBGraphicsMediaItem* audioItemFromSvg(); + + UBGraphicsAppleWidgetItem* graphicsAppleWidgetFromSvg(); + + UBGraphicsW3CWidgetItem* graphicsW3CWidgetFromSvg(); + + UBGraphicsTextItem* textItemFromSvg(); + + UBGraphicsCurtainItem* curtainItemFromSvg(); + + UBGraphicsRuler* rulerFromSvg(); + + UBGraphicsCompass* compassFromSvg(); + + UBGraphicsProtractor* protractorFromSvg(); + + UBGraphicsTriangle* triangleFromSvg(); + + UBGraphicsCache* cacheFromSvg(); + + void readGroupRoot(); + QGraphicsItem *readElementFromGroup(); + UBGraphicsGroupContainerItem* readGroup(); + + void graphicsItemFromSvg(QGraphicsItem* gItem); + + qreal getZValueFromSvg(); + QUuid getUuidFromSvg(); + + QXmlStreamReader mXmlReader; + int mFileVersion; + UBDocumentProxy *mProxy; + QString mDocumentPath; + + QColor mGroupDarkBackgroundColor; + QColor mGroupLightBackgroundColor; + qreal mGroupZIndex; + bool mGroupHasInfo; + + QString mNamespaceUri; + UBGraphicsScene *mScene; + + QMap mStrokesList; + }; + + class UBSvgSubsetWriter + { + public: + + UBSvgSubsetWriter(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); + + bool persistScene(int pageIndex); + + virtual ~UBSvgSubsetWriter(){} + + private: + + void persistGroupToDom(QGraphicsItem *groupItem, QDomElement *curParent, QDomDocument *curDomDocument); + void persistStrokeToDom(QGraphicsItem *strokeItem, QDomElement *curParent, QDomDocument *curDomDocument); + void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); + void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); + void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo); + void strokeToSvgPolygon(UBGraphicsStroke* stroke, bool groupHoldsInfo); + + inline QString pointsToSvgPointsAttribute(QVector points) + { + UBGeometryUtils::crashPointList(points); + + int pointsCount = points.size(); + QString svgPoints; + + int length = 0; + QString sBuf; + + for(int j = 0; j < pointsCount; j++) + { + sBuf = "%1,%2 "; + const QPointF & point = points.at(j); + + QString temp1 = "%1", temp2 = "%2"; + + temp1 = temp1.arg(point.x()); + temp2 = temp2.arg(point.y()); + + QLocale loc(QLocale::C); + sBuf = sBuf.arg(loc.toFloat(temp1)).arg(loc.toFloat(temp2)); + + svgPoints.insert(length, sBuf); + length += sBuf.length(); + } + return svgPoints; + } + + inline qreal trickAlpha(qreal alpha) + { + qreal trickAlpha = alpha; + if(trickAlpha >= 0.2 && trickAlpha < 0.6){ + trickAlpha /= 5; + }else if (trickAlpha < 0.8) + trickAlpha /= 3; + + return trickAlpha; + } + + void pixmapItemToLinkedImage(UBGraphicsPixmapItem *pixmapItem); + void svgItemToLinkedSvg(UBGraphicsSvgItem *svgItem); + void pdfItemToLinkedPDF(UBGraphicsPDFItem *pdfItem); + void videoItemToLinkedVideo(UBGraphicsMediaItem *videoItem); + void audioItemToLinkedAudio(UBGraphicsMediaItem *audioItem); + void graphicsItemToSvg(QGraphicsItem *item); + void graphicsAppleWidgetToSvg(UBGraphicsAppleWidgetItem *item); + void graphicsW3CWidgetToSvg(UBGraphicsW3CWidgetItem *item); + void graphicsWidgetToSvg(UBGraphicsWidgetItem *item); + void textItemToSvg(UBGraphicsTextItem *item); + void curtainItemToSvg(UBGraphicsCurtainItem *item); + void rulerToSvg(UBGraphicsRuler *item); + void compassToSvg(UBGraphicsCompass *item); + void protractorToSvg(UBGraphicsProtractor *item); + void cacheToSvg(UBGraphicsCache* item); + void triangleToSvg(UBGraphicsTriangle *item); + void writeSvgElement(); + + private: + + UBGraphicsScene* mScene; + QXmlStreamWriter mXmlWriter; + QString mDocumentPath; + int mPageIndex; + + }; +}; + +#endif /* UBSVGSUBSETADAPTOR_H_ */ diff --git a/src/adaptors/UBThumbnailAdaptor.cpp b/src/adaptors/UBThumbnailAdaptor.cpp index 68441c58..bd1a6acc 100644 --- a/src/adaptors/UBThumbnailAdaptor.cpp +++ b/src/adaptors/UBThumbnailAdaptor.cpp @@ -19,169 +19,169 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBThumbnailAdaptor.h" - -#include - -#include "frameworks/UBFileSystemUtils.h" - -#include "core/UBPersistenceManager.h" -#include "core/UBApplication.h" -#include "core/UBSettings.h" - - -#include "gui/UBDockTeacherGuideWidget.h" -#include "gui/UBTeacherGuideWidget.h" - -#include "board/UBBoardController.h" -#include "board/UBBoardPaletteManager.h" - -#include "document/UBDocumentProxy.h" - -#include "domain/UBGraphicsScene.h" - -#include "UBSvgSubsetAdaptor.h" - -#include "core/memcheck.h" - -void UBThumbnailAdaptor::generateMissingThumbnails(UBDocumentProxy* proxy) -{ - int existingPageCount = proxy->pageCount(); - - for (int iPageNo = 0; iPageNo < existingPageCount; ++iPageNo) - { - QString thumbFileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", iPageNo); - - QFile thumbFile(thumbFileName); - - if (!thumbFile.exists()) - { - bool displayMessage = (existingPageCount > 5); - - int thumbCount = 0; - - UBGraphicsScene* scene = UBSvgSubsetAdaptor::loadScene(proxy, iPageNo); - - if (scene) - { - thumbCount++; - - if (displayMessage && thumbCount == 1) - UBApplication::showMessage(tr("Generating preview thumbnails ...")); - - persistScene(proxy, scene, iPageNo); - } - - if (displayMessage && thumbCount > 0) - UBApplication::showMessage(tr("%1 thumbnails generated ...").arg(thumbCount)); - - } - } -} - -const QPixmap* UBThumbnailAdaptor::get(UBDocumentProxy* proxy, int pageIndex) -{ - QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); - - QFile file(fileName); - if (!file.exists()) - { - generateMissingThumbnails(proxy); - } - - QPixmap* pix = new QPixmap(); - if (file.exists()) - { - //Warning. Works only with modified Qt -#ifdef Q_WS_X11 - pix->load(fileName, 0, Qt::AutoColor); -#else - pix->load(fileName, 0, Qt::AutoColor, false); -#endif - } - return pix; -} - -void UBThumbnailAdaptor::updateDocumentToHandleZeroPage(UBDocumentProxy* proxy) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()){ - QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", 0); - QFile file(fileName); - if(!file.exists()){ - UBPersistenceManager::persistenceManager()->persistDocumentScene(proxy,new UBGraphicsScene(proxy),0); - } - } -} - -void UBThumbnailAdaptor::load(UBDocumentProxy* proxy, QList& list) -{ - updateDocumentToHandleZeroPage(proxy); - generateMissingThumbnails(proxy); - - foreach(const QPixmap* pm, list) - delete pm; - list.clear(); - for(int i=0; ipageCount(); i++) - list.append(get(proxy, i)); -} - -void UBThumbnailAdaptor::persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, int pageIndex, bool overrideModified) -{ - QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); - - QFile thumbFile(fileName); - - if (pScene->isModified() || overrideModified || !thumbFile.exists() || UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified()) - { - qreal nominalWidth = pScene->nominalSize().width(); - qreal nominalHeight = pScene->nominalSize().height(); - qreal ratio = nominalWidth / nominalHeight; - QRectF sceneRect = pScene->normalizedSceneRect(ratio); - - qreal width = UBSettings::maxThumbnailWidth; - qreal height = width / ratio; - - QImage thumb(width, height, QImage::Format_ARGB32); - - QRectF imageRect(0, 0, width, height); - - QPainter painter(&thumb); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - - if (pScene->isDarkBackground()) - { - painter.fillRect(imageRect, Qt::black); - } - else - { - painter.fillRect(imageRect, Qt::white); - } - - pScene->setRenderingContext(UBGraphicsScene::NonScreen); - pScene->setRenderingQuality(UBItem::RenderingQualityHigh); - - pScene->render(&painter, imageRect, sceneRect, Qt::KeepAspectRatio); - - if(UBApplication::boardController->paletteManager()->teacherGuideDockWidget() && UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified()){ - QPixmap toque(":images/toque.svg"); - painter.setOpacity(0.6); - painter.drawPixmap(QPoint(width - toque.width(),0),toque); - } - - pScene->setRenderingContext(UBGraphicsScene::Screen); - pScene->setRenderingQuality(UBItem::RenderingQualityNormal); - - thumb.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(fileName, "JPG"); - } -} - - -QUrl UBThumbnailAdaptor::thumbnailUrl(UBDocumentProxy* proxy, int pageIndex) -{ - QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); - - return QUrl::fromLocalFile(fileName); -} + + +#include "UBThumbnailAdaptor.h" + +#include + +#include "frameworks/UBFileSystemUtils.h" + +#include "core/UBPersistenceManager.h" +#include "core/UBApplication.h" +#include "core/UBSettings.h" + + +#include "gui/UBDockTeacherGuideWidget.h" +#include "gui/UBTeacherGuideWidget.h" + +#include "board/UBBoardController.h" +#include "board/UBBoardPaletteManager.h" + +#include "document/UBDocumentProxy.h" + +#include "domain/UBGraphicsScene.h" + +#include "UBSvgSubsetAdaptor.h" + +#include "core/memcheck.h" + +void UBThumbnailAdaptor::generateMissingThumbnails(UBDocumentProxy* proxy) +{ + int existingPageCount = proxy->pageCount(); + + for (int iPageNo = 0; iPageNo < existingPageCount; ++iPageNo) + { + QString thumbFileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", iPageNo); + + QFile thumbFile(thumbFileName); + + if (!thumbFile.exists()) + { + bool displayMessage = (existingPageCount > 5); + + int thumbCount = 0; + + UBGraphicsScene* scene = UBSvgSubsetAdaptor::loadScene(proxy, iPageNo); + + if (scene) + { + thumbCount++; + + if (displayMessage && thumbCount == 1) + UBApplication::showMessage(tr("Generating preview thumbnails ...")); + + persistScene(proxy, scene, iPageNo); + } + + if (displayMessage && thumbCount > 0) + UBApplication::showMessage(tr("%1 thumbnails generated ...").arg(thumbCount)); + + } + } +} + +const QPixmap* UBThumbnailAdaptor::get(UBDocumentProxy* proxy, int pageIndex) +{ + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); + + QFile file(fileName); + if (!file.exists()) + { + generateMissingThumbnails(proxy); + } + + QPixmap* pix = new QPixmap(); + if (file.exists()) + { + //Warning. Works only with modified Qt +#ifdef Q_WS_X11 + pix->load(fileName, 0, Qt::AutoColor); +#else + pix->load(fileName, 0, Qt::AutoColor, false); +#endif + } + return pix; +} + +void UBThumbnailAdaptor::updateDocumentToHandleZeroPage(UBDocumentProxy* proxy) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()){ + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", 0); + QFile file(fileName); + if(!file.exists()){ + UBPersistenceManager::persistenceManager()->persistDocumentScene(proxy,new UBGraphicsScene(proxy),0); + } + } +} + +void UBThumbnailAdaptor::load(UBDocumentProxy* proxy, QList& list) +{ + updateDocumentToHandleZeroPage(proxy); + generateMissingThumbnails(proxy); + + foreach(const QPixmap* pm, list) + delete pm; + list.clear(); + for(int i=0; ipageCount(); i++) + list.append(get(proxy, i)); +} + +void UBThumbnailAdaptor::persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, int pageIndex, bool overrideModified) +{ + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); + + QFile thumbFile(fileName); + + if (pScene->isModified() || overrideModified || !thumbFile.exists() || UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified()) + { + qreal nominalWidth = pScene->nominalSize().width(); + qreal nominalHeight = pScene->nominalSize().height(); + qreal ratio = nominalWidth / nominalHeight; + QRectF sceneRect = pScene->normalizedSceneRect(ratio); + + qreal width = UBSettings::maxThumbnailWidth; + qreal height = width / ratio; + + QImage thumb(width, height, QImage::Format_ARGB32); + + QRectF imageRect(0, 0, width, height); + + QPainter painter(&thumb); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); + + if (pScene->isDarkBackground()) + { + painter.fillRect(imageRect, Qt::black); + } + else + { + painter.fillRect(imageRect, Qt::white); + } + + pScene->setRenderingContext(UBGraphicsScene::NonScreen); + pScene->setRenderingQuality(UBItem::RenderingQualityHigh); + + pScene->render(&painter, imageRect, sceneRect, Qt::KeepAspectRatio); + + if(UBApplication::boardController->paletteManager()->teacherGuideDockWidget() && UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified()){ + QPixmap toque(":images/toque.svg"); + painter.setOpacity(0.6); + painter.drawPixmap(QPoint(width - toque.width(),0),toque); + } + + pScene->setRenderingContext(UBGraphicsScene::Screen); + pScene->setRenderingQuality(UBItem::RenderingQualityNormal); + + thumb.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(fileName, "JPG"); + } +} + + +QUrl UBThumbnailAdaptor::thumbnailUrl(UBDocumentProxy* proxy, int pageIndex) +{ + QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", pageIndex); + + return QUrl::fromLocalFile(fileName); +} diff --git a/src/adaptors/UBThumbnailAdaptor.h b/src/adaptors/UBThumbnailAdaptor.h index bbdecb9f..52305dc1 100644 --- a/src/adaptors/UBThumbnailAdaptor.h +++ b/src/adaptors/UBThumbnailAdaptor.h @@ -19,34 +19,34 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBTHUMBNAILADAPTOR_H -#define UBTHUMBNAILADAPTOR_H - -#include - -class UBDocument; -class UBDocumentProxy; -class UBGraphicsScene; - -class UBThumbnailAdaptor //static class -{ - Q_DECLARE_TR_FUNCTIONS(UBThumbnailAdaptor) - -public: - static QUrl thumbnailUrl(UBDocumentProxy* proxy, int pageIndex); - - static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, int pageIndex, bool overrideModified = false); - - static const QPixmap* get(UBDocumentProxy* proxy, int index); - static void load(UBDocumentProxy* proxy, QList& list); - -private: - static void generateMissingThumbnails(UBDocumentProxy* proxy); - static void updateDocumentToHandleZeroPage(UBDocumentProxy* proxy); - - UBThumbnailAdaptor() {} -}; - -#endif // UBTHUMBNAILADAPTOR_H + + +#ifndef UBTHUMBNAILADAPTOR_H +#define UBTHUMBNAILADAPTOR_H + +#include + +class UBDocument; +class UBDocumentProxy; +class UBGraphicsScene; + +class UBThumbnailAdaptor //static class +{ + Q_DECLARE_TR_FUNCTIONS(UBThumbnailAdaptor) + +public: + static QUrl thumbnailUrl(UBDocumentProxy* proxy, int pageIndex); + + static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, int pageIndex, bool overrideModified = false); + + static const QPixmap* get(UBDocumentProxy* proxy, int index); + static void load(UBDocumentProxy* proxy, QList& list); + +private: + static void generateMissingThumbnails(UBDocumentProxy* proxy); + static void updateDocumentToHandleZeroPage(UBDocumentProxy* proxy); + + UBThumbnailAdaptor() {} +}; + +#endif // UBTHUMBNAILADAPTOR_H diff --git a/src/adaptors/publishing/UBDocumentPublisher.cpp b/src/adaptors/publishing/UBDocumentPublisher.cpp index 96b8d6bf..33e9b58e 100644 --- a/src/adaptors/publishing/UBDocumentPublisher.cpp +++ b/src/adaptors/publishing/UBDocumentPublisher.cpp @@ -19,813 +19,813 @@ * along with Open-Sankoré. If not, see . */ - - -#include - -#include "UBDocumentPublisher.h" - -#include "frameworks/UBPlatformUtils.h" -#include "frameworks/UBFileSystemUtils.h" -#include "frameworks/UBStringUtils.h" - -#include "network/UBNetworkAccessManager.h" -#include "network/UBServerXMLHttpRequest.h" - -#include "core/UBDocumentManager.h" -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBApplicationController.h" - -#include "board/UBBoardController.h" - -#include "gui/UBMainWindow.h" - -#include "document/UBDocumentProxy.h" -#include "document/UBDocumentContainer.h" - -#include "domain/UBGraphicsWidgetItem.h" - -#include "globals/UBGlobals.h" - -THIRD_PARTY_WARNINGS_DISABLE -#include "quazip.h" -#include "quazipfile.h" -THIRD_PARTY_WARNINGS_ENABLE - -#include "adaptors/UBExportFullPDF.h" -#include "adaptors/UBExportDocument.h" -#include "adaptors/UBSvgSubsetAdaptor.h" - -#include "UBSvgSubsetRasterizer.h" - -#include "../../core/UBApplication.h" - -#include "core/memcheck.h" - - -UBDocumentPublisher::UBDocumentPublisher(UBDocumentProxy* pDocument, QObject *parent) - : QObject(parent) - , mSourceDocument(pDocument) - , mUsername("") - , mPassword("") - , bLoginCookieSet(false) -{ - init(); -} - - -UBDocumentPublisher::~UBDocumentPublisher() -{ -} - - -void UBDocumentPublisher::publish() -{ - //check that the username and password are stored on preferences - UBSettings* settings = UBSettings::settings(); - - if(settings->communityUsername().isEmpty() || settings->communityPassword().isEmpty()){ - UBApplication::showMessage(tr("Credentials has to not been filled out yet.")); - qDebug() << "trying to connect to community without the required credentials"; - return; - } - - mUsername = settings->communityUsername(); - mPassword = settings->communityPassword(); - - UBPublicationDlg dlg; - if(QDialog::Accepted == dlg.exec()) - { - mDocInfos.title = dlg.title(); - mDocInfos.description = dlg.description(); - - buildUbwFile(); - - UBApplication::showMessage(tr("Uploading Sankore File on Web.")); - - sendUbw(mUsername, mPassword); - } -} - -void UBDocumentPublisher::buildUbwFile() -{ - QDir d; - d.mkpath(UBFileSystemUtils::defaultTempDirPath()); - - QString tmpDir = UBFileSystemUtils::createTempDir(); - - if (UBFileSystemUtils::copyDir(mSourceDocument->persistencePath(), tmpDir)) - { - QString documentName = mSourceDocument->name(); - - mPublishingPath = tmpDir; - mPublishingSize = mSourceDocument->pageCount(); - - rasterizeScenes(); - - upgradeDocumentForPublishing(); - - UBExportFullPDF pdfExporter; - pdfExporter.setVerbode(false); - pdfExporter.persistsDocument(mSourceDocument, mPublishingPath + "/" + documentName + ".pdf"); - - UBExportDocument ubzExporter; - ubzExporter.setVerbode(false); - ubzExporter.persistsDocument(mSourceDocument, mPublishingPath + "/" + documentName + ".ubz"); - - // remove all useless files - - for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) { - QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.svg",pageIndex); - - QFile::remove(filename); - } - - UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::imageDirectory); - UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::objectDirectory); - UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::videoDirectory); - UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::audioDirectory); - - mTmpZipFile = UBFileSystemUtils::defaultTempDirPath() + "/" + UBStringUtils::toCanonicalUuid(QUuid::createUuid()) + ".ubw~"; - - QuaZip zip(mTmpZipFile); - zip.setFileNameCodec("UTF-8"); - if (!zip.open(QuaZip::mdCreate)) - { - qWarning() << "Export failed. Cause: zip.open(): " << zip.getZipError() << "," << mTmpZipFile; - QApplication::restoreOverrideCursor(); - return; - } - - QuaZipFile outFile(&zip); - - if (!UBFileSystemUtils::compressDirInZip(mPublishingPath, "", &outFile, true)) - { - qWarning("Export failed. compressDirInZip failed ..."); - zip.close(); - UBApplication::showMessage(tr("Export failed.")); - QApplication::restoreOverrideCursor(); - return; - } - - if (zip.getZipError() != 0) - { - qWarning("Export failed. Cause: zip.close(): %d", zip.getZipError()); - zip.close(); - UBApplication::showMessage(tr("Export failed.")); - QApplication::restoreOverrideCursor(); - return; - } - - zip.close(); - - } - else - { - UBApplication::showMessage(tr("Export canceled ...")); - QApplication::restoreOverrideCursor(); - } -} - -void UBDocumentPublisher::rasterizeScenes() -{ - - for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) - { - UBApplication::showMessage(tr("Converting page %1/%2 ...").arg(UBDocumentContainer::pageFromSceneIndex(pageIndex)).arg(mPublishingSize), true); - - UBDocumentProxy publishingDocument(mPublishingPath); - UBSvgSubsetRasterizer rasterizer(&publishingDocument, pageIndex); - - QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.jpg",pageIndex); - - rasterizer.rasterizeToFile(filename); - - } -} - - -void UBDocumentPublisher::updateGoogleMapApiKey() -{ - QDir widgestDir(mPublishingPath + "/" + UBPersistenceManager::widgetDirectory); - - QString uniboardWebGoogleMapApiKey = UBSettings::settings()->uniboardWebGoogleMapApiKey->get().toString(); - - foreach(QFileInfo dirInfo, widgestDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) - { - QString config = UBFileSystemUtils::readTextFile(dirInfo.absoluteFilePath() + "/config.xml").toLower(); - - if (config.contains("google") && config.contains("map")) - { - QDir widgetDir(dirInfo.absoluteFilePath()); - - foreach(QFileInfo fileInfo, widgetDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)) - { - QFile file(fileInfo.absoluteFilePath()); - - if (file.open(QIODevice::ReadWrite)) - { - QTextStream stream(&file); - QString content = stream.readAll(); - - if (content.contains("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og")) - { - content.replace("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og", - uniboardWebGoogleMapApiKey); - - file.resize(0); - file.write(content.toUtf8()); - } - file.close(); - } - } - } - } -} - - -void UBDocumentPublisher::upgradeDocumentForPublishing() -{ - for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) - { - UBDocumentProxy publishingDocument(mPublishingPath); - UBGraphicsScene *scene = UBSvgSubsetAdaptor::loadScene(&publishingDocument, pageIndex); - - QList widgets; - - foreach(QGraphicsItem* item, scene->items()){ - UBGraphicsW3CWidgetItem *widgetItem = dynamic_cast(item); - - if(widgetItem){ - generateWidgetPropertyScript(widgetItem, UBDocumentContainer::pageFromSceneIndex(pageIndex)); - widgets << widgetItem; - } - } - - QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.json",pageIndex); - - QFile jsonFile(filename); - if (jsonFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { - jsonFile.write("{\n"); - jsonFile.write(QString(" \"scene\": {\n").toUtf8()); - jsonFile.write(QString(" \"x\": %1,\n").arg(scene->normalizedSceneRect().x()).toUtf8()); - jsonFile.write(QString(" \"y\": %1,\n").arg(scene->normalizedSceneRect().y()).toUtf8()); - jsonFile.write(QString(" \"width\": %1,\n").arg(scene->normalizedSceneRect().width()).toUtf8()); - jsonFile.write(QString(" \"height\": %1\n").arg(scene->normalizedSceneRect().height()).toUtf8()); - jsonFile.write(QString(" },\n").toUtf8()); - - jsonFile.write(QString(" \"widgets\": [\n").toUtf8()); - - bool first = true; - - foreach(UBGraphicsW3CWidgetItem* widget, widgets) - { - if (!first) - jsonFile.write(QString(" ,\n").toUtf8()); - - jsonFile.write(QString(" {\n").toUtf8()); - jsonFile.write(QString(" \"uuid\": \"%1\",\n").arg(UBStringUtils::toCanonicalUuid(widget->uuid())).toUtf8()); - jsonFile.write(QString(" \"id\": \"%1\",\n").arg(widget->metadatas().id).toUtf8()); - - jsonFile.write(QString(" \"name\": \"%1\",\n").arg(widget->metadatas().name).toUtf8()); - jsonFile.write(QString(" \"description\": \"%1\",\n").arg(widget->metadatas().description).toUtf8()); - jsonFile.write(QString(" \"author\": \"%1\",\n").arg(widget->metadatas().author).toUtf8()); - jsonFile.write(QString(" \"authorEmail\": \"%1\",\n").arg(widget->metadatas().authorEmail).toUtf8()); - jsonFile.write(QString(" \"authorHref\": \"%1\",\n").arg(widget->metadatas().authorHref).toUtf8()); - jsonFile.write(QString(" \"version\": \"%1\",\n").arg(widget->metadatas().authorHref).toUtf8()); - - jsonFile.write(QString(" \"x\": %1,\n").arg(widget->sceneBoundingRect().x()).toUtf8()); - jsonFile.write(QString(" \"y\": %1,\n").arg(widget->sceneBoundingRect().y()).toUtf8()); - jsonFile.write(QString(" \"width\": %1,\n").arg(widget->sceneBoundingRect().width()).toUtf8()); - jsonFile.write(QString(" \"height\": %1,\n").arg(widget->sceneBoundingRect().height()).toUtf8()); - - jsonFile.write(QString(" \"nominalWidth\": %1,\n").arg(widget->boundingRect().width()).toUtf8()); - jsonFile.write(QString(" \"nominalHeight\": %1,\n").arg(widget->boundingRect().height()).toUtf8()); - - QString url = UBPersistenceManager::widgetDirectory + "/" + widget->uuid().toString() + ".wgt"; - jsonFile.write(QString(" \"src\": \"%1\",\n").arg(url).toUtf8()); - QString startFile = widget->mainHtmlFileName(); - jsonFile.write(QString(" \"startFile\": \"%1\",\n").arg(startFile).toUtf8()); - - QMap preferences = widget->UBGraphicsWidgetItem::preferences(); - - jsonFile.write(QString(" \"preferences\": {\n").toUtf8()); - - foreach(QString key, preferences.keys()) - { - QString sep = ","; - if (key == preferences.keys().last()) - sep = ""; - - jsonFile.write(QString(" \"%1\": \"%2\"%3\n") - .arg(key) - .arg(preferences.value(key)) - .arg(sep) - .toUtf8()); - } - jsonFile.write(QString(" },\n").toUtf8()); - - jsonFile.write(QString(" \"datastore\": {\n").toUtf8()); - - QMap datastoreEntries = widget->datastoreEntries(); - - foreach(QString entry, datastoreEntries.keys()) - { - QString sep = ","; - if (entry == datastoreEntries.keys().last()) - sep = ""; - - jsonFile.write(QString(" \"%1\": \"%2\"%3\n") - .arg(entry) - .arg(datastoreEntries.value(entry)) - .arg(sep) - .toUtf8()); - } - jsonFile.write(QString(" }\n").toUtf8()); - - jsonFile.write(QString(" }\n").toUtf8()); - - first = false; - } - - jsonFile.write(" ]\n"); - jsonFile.write("}\n"); - } - else - { - qWarning() << "Cannot open file" << filename << "for saving page state"; - } - - delete scene; - } - - updateGoogleMapApiKey(); -} - - -void UBDocumentPublisher::generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber) -{ - - QMap preferences = widgetItem->UBGraphicsWidgetItem::preferences(); - QMap datastoreEntries = widgetItem->datastoreEntries(); - - QString startFileName = widgetItem->mainHtmlFileName(); - - if (!startFileName.startsWith("http://")) - { - QString startFilePath = mPublishingPath + "/" + UBPersistenceManager::widgetDirectory + "/" + widgetItem->uuid().toString() + ".wgt/" + startFileName; - - QFile startFile(startFilePath); - - if (startFile.exists()) - { - if (startFile.open(QIODevice::ReadWrite)) - { - QTextStream stream(&startFile); - QStringList lines; - - bool addedJs = false; - - QString line; - do - { - line = stream.readLine(); - if (!line.isNull()) - { - lines << line; - - if (!addedJs && line.contains("") ) // TODO UB 4.6, this is naive ... the HEAD tag may be on several lines - { - lines << ""; - lines << " "; - lines << ""; - - addedJs = true; - } - } - } - while (!line.isNull()); - - startFile.resize(0); - startFile.write(lines.join("\n").toUtf8()); // TODO UB 4.x detect real html encoding - - startFile.close(); - } - } - } - else{ - qWarning() << "Remote Widget start file, cannot inject widget preferences and datastore entries"; - } -} - -void UBDocumentPublisher::init() -{ - mCrlf=0x0d; - mCrlf+=0x0a; - mDocInfos.title = ""; - mDocInfos.description = ""; - - mpCookieJar = new QNetworkCookieJar(); - mpNetworkMgr = new QNetworkAccessManager(this); - - connect(mpNetworkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*))); -} - -void UBDocumentPublisher::onFinished(QNetworkReply *reply) -{ - QVariant cookieHeader = reply->rawHeader("Set-Cookie"); - // First we concatenate all the Set-Cookie values (the packet can contains many of them) - QStringList qslCookie = cookieHeader.toString().split("\n"); - QString qsCookieValue = qslCookie.at(0); - for (int i = 1; i < qslCookie.size(); i++) { - qsCookieValue += "; " +qslCookie.at(i); - } - - // Now we isolate every cookie value - QStringList qslCookieVals = qsCookieValue.split("; "); - - bool bTransferOk = false; - - for(int j = 0; j < qslCookieVals.size(); j++) - { - qDebug() << j; - if(qslCookieVals.at(j).startsWith("assetStatus")) - { - QStringList qslAsset = qslCookieVals.at(j).split("="); - if(qslAsset.at(1) == "UPLOADED") - { - bTransferOk = true; - break; - } - } - } - - if(bTransferOk) - { - UBApplication::showMessage(tr("Document uploaded correctly on the web.")); - } - else - { - UBApplication::showMessage(tr("Failed to upload document on the web.")); - } - - reply->deleteLater(); -} - -void UBDocumentPublisher::sendUbw(QString username, QString password) -{ - if (QFile::exists(mTmpZipFile)) - { - QFile f(mTmpZipFile); - if (f.open(QIODevice::ReadOnly)) - { - QFileInfo fi(f); - QByteArray ba = f.readAll(); - QString boundary,data, multipartHeader; - QByteArray datatoSend; - - boundary = "---WebKitFormBoundaryDKBTgA53MiyWrzLY"; - multipartHeader = "multipart/form-data; boundary="+boundary; - - data="--"+boundary+mCrlf; - data+="Content-Disposition: form-data; name=\"title\"" + mCrlf + mCrlf + mDocInfos.title + mCrlf; - data+="--"+boundary+mCrlf; - data+="Content-Disposition: form-data; name=\"description\"" + mCrlf + mCrlf + mDocInfos.description.remove("\n") + mCrlf; - data+="--"+boundary+mCrlf; - data+="Content-Disposition: form-data; name=\"file\"; filename=\""+ fi.fileName() +"\""+mCrlf; - data+="Content-Type: application/octet-stream"+mCrlf+mCrlf; - datatoSend=data.toAscii(); // convert data string to byte array for request - datatoSend += ba; - datatoSend += mCrlf; - datatoSend += QString("--%0--%1").arg(boundary).arg(mCrlf); - - QNetworkRequest request(QUrl(QString(DOCPUBLICATION_URL).toAscii().constData())); - - request.setHeader(QNetworkRequest::ContentTypeHeader, multipartHeader); - request.setHeader(QNetworkRequest::ContentLengthHeader,datatoSend.size()); - QString b64Auth = getBase64Of(QString("%0:%1").arg(username).arg(password)); - request.setRawHeader("Authorization", QString("Basic %0").arg(b64Auth).toAscii().constData()); - request.setRawHeader("Host", "planete.sankore.org"); - request.setRawHeader("Accept", "*/*"); - request.setRawHeader("Accept-Language", "en-US,*"); - - mpCookieJar->setCookiesFromUrl(mCookies, QUrl(DOCPUBLICATION_URL)); - mpNetworkMgr->setCookieJar(mpCookieJar); - - // Send the file - mpNetworkMgr->post(request,datatoSend); - } - } -} - -QString UBDocumentPublisher::getBase64Of(QString stringToEncode) -{ - return stringToEncode.toAscii().toBase64(); -} - -// --------------------------------------------------------- -UBProxyLoginDlg::UBProxyLoginDlg(QWidget *parent, const char *name):QDialog(parent) - , mpLayout(NULL) - , mpUserLayout(NULL) - , mpPasswordLayout(NULL) - , mpButtons(NULL) - , mpUserLabel(NULL) - , mpPasswordLabel(NULL) - , mpUsername(NULL) - , mpPassword(NULL) -{ - setObjectName(name); - setFixedSize(400, 150); - setWindowTitle(tr("Proxy Login")); - - mpLayout = new QVBoxLayout(); - setLayout(mpLayout); - mpUserLayout = new QHBoxLayout(); - mpLayout->addLayout(mpUserLayout); - mpPasswordLayout = new QHBoxLayout(); - mpLayout->addLayout(mpPasswordLayout); - - mpUserLabel = new QLabel(tr("Username:"), this); - mpUsername = new QLineEdit(this); - mpUserLayout->addWidget(mpUserLabel, 0); - mpUserLayout->addWidget(mpUsername, 1); - - mpPasswordLabel = new QLabel(tr("Password:"), this); - mpPassword = new QLineEdit(this); - mpPasswordLayout->addWidget(mpPasswordLabel, 0); - mpPasswordLayout->addWidget(mpPassword, 1); - - mpButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); - mpLayout->addWidget(mpButtons); - - connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); - connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); - -} - -UBProxyLoginDlg::~UBProxyLoginDlg() -{ - if(NULL != mpLayout) - { - delete mpLayout; - mpLayout = NULL; - } - if(NULL != mpButtons) - { - delete mpButtons; - mpButtons = NULL; - } - if(NULL != mpUserLabel) - { - delete mpUserLabel; - mpUserLabel = NULL; - } - if(NULL != mpPasswordLabel) - { - delete mpPasswordLabel; - mpPasswordLabel = NULL; - } - if(NULL != mpUsername) - { - delete mpUsername; - mpUsername = NULL; - } - if(NULL != mpPassword) - { - delete mpPassword; - mpPassword = NULL; - } -} - -// --------------------------------------------------------- -UBPublicationDlg::UBPublicationDlg(QWidget *parent, const char *name):QDialog(parent) - , mpLayout(NULL) - , mpTitleLayout(NULL) - , mpTitleLabel(NULL) - , mpTitle(NULL) - , mpDescLabel(NULL) - , mpDescription(NULL) - , mpButtons(NULL) -{ - setObjectName(name); - setWindowTitle(tr("Publish document on the web")); - - resize(500, 300); - - mpLayout = new QVBoxLayout(); - setLayout(mpLayout); - - mpTitleLabel = new QLabel(tr("Title:"), this); - mpTitle = new QLineEdit(this); - mpTitleLayout = new QHBoxLayout(); - mpTitleLayout->addWidget(mpTitleLabel, 0); - mpTitleLayout->addWidget(mpTitle, 1); - mpLayout->addLayout(mpTitleLayout, 0); - - mpDescLabel = new QLabel(tr("Description:"), this); - mpLayout->addWidget(mpDescLabel, 0); - - mpDescription = new QTextEdit(this); - mpLayout->addWidget(mpDescription, 1); - - mpButtons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); - mpButtons->button(QDialogButtonBox::Ok)->setText(tr("Publish")); - mpLayout->addWidget(mpButtons); - - mpButtons->button(QDialogButtonBox::Ok)->setEnabled(false); - - connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); - connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); - connect(mpTitle, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged())); - connect(mpDescription, SIGNAL(textChanged()), this, SLOT(onTextChanged())); -} - -UBPublicationDlg::~UBPublicationDlg() -{ - if(NULL != mpTitleLabel) - { - delete mpTitleLabel; - mpTitleLabel = NULL; - } - if(NULL != mpTitle) - { - delete mpTitle; - mpTitle = NULL; - } - if(NULL != mpDescLabel) - { - delete mpDescLabel; - mpDescLabel = NULL; - } - if(NULL != mpDescription) - { - delete mpDescription; - mpDescription = NULL; - } - if(NULL != mpButtons) - { - delete mpButtons; - mpButtons = NULL; - } - if(NULL != mpTitleLayout) - { - delete mpTitleLayout; - mpTitleLayout = NULL; - } - if(NULL != mpLayout) - { - delete mpLayout; - mpLayout = NULL; - } -} - -void UBPublicationDlg::onTextChanged() -{ - bool bPublishButtonState = false; - if(mpTitle->text() != "" && mpDescription->document()->toPlainText() != "") - { - bPublishButtonState = true; - } - else - { - bPublishButtonState = false; - } - - mpButtons->button(QDialogButtonBox::Ok)->setEnabled(bPublishButtonState); -} + + +#include + +#include "UBDocumentPublisher.h" + +#include "frameworks/UBPlatformUtils.h" +#include "frameworks/UBFileSystemUtils.h" +#include "frameworks/UBStringUtils.h" + +#include "network/UBNetworkAccessManager.h" +#include "network/UBServerXMLHttpRequest.h" + +#include "core/UBDocumentManager.h" +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBApplicationController.h" + +#include "board/UBBoardController.h" + +#include "gui/UBMainWindow.h" + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentContainer.h" + +#include "domain/UBGraphicsWidgetItem.h" + +#include "globals/UBGlobals.h" + +THIRD_PARTY_WARNINGS_DISABLE +#include "quazip.h" +#include "quazipfile.h" +THIRD_PARTY_WARNINGS_ENABLE + +#include "adaptors/UBExportFullPDF.h" +#include "adaptors/UBExportDocument.h" +#include "adaptors/UBSvgSubsetAdaptor.h" + +#include "UBSvgSubsetRasterizer.h" + +#include "../../core/UBApplication.h" + +#include "core/memcheck.h" + + +UBDocumentPublisher::UBDocumentPublisher(UBDocumentProxy* pDocument, QObject *parent) + : QObject(parent) + , mSourceDocument(pDocument) + , mUsername("") + , mPassword("") + , bLoginCookieSet(false) +{ + init(); +} + + +UBDocumentPublisher::~UBDocumentPublisher() +{ +} + + +void UBDocumentPublisher::publish() +{ + //check that the username and password are stored on preferences + UBSettings* settings = UBSettings::settings(); + + if(settings->communityUsername().isEmpty() || settings->communityPassword().isEmpty()){ + UBApplication::showMessage(tr("Credentials has to not been filled out yet.")); + qDebug() << "trying to connect to community without the required credentials"; + return; + } + + mUsername = settings->communityUsername(); + mPassword = settings->communityPassword(); + + UBPublicationDlg dlg; + if(QDialog::Accepted == dlg.exec()) + { + mDocInfos.title = dlg.title(); + mDocInfos.description = dlg.description(); + + buildUbwFile(); + + UBApplication::showMessage(tr("Uploading Sankore File on Web.")); + + sendUbw(mUsername, mPassword); + } +} + +void UBDocumentPublisher::buildUbwFile() +{ + QDir d; + d.mkpath(UBFileSystemUtils::defaultTempDirPath()); + + QString tmpDir = UBFileSystemUtils::createTempDir(); + + if (UBFileSystemUtils::copyDir(mSourceDocument->persistencePath(), tmpDir)) + { + QString documentName = mSourceDocument->name(); + + mPublishingPath = tmpDir; + mPublishingSize = mSourceDocument->pageCount(); + + rasterizeScenes(); + + upgradeDocumentForPublishing(); + + UBExportFullPDF pdfExporter; + pdfExporter.setVerbode(false); + pdfExporter.persistsDocument(mSourceDocument, mPublishingPath + "/" + documentName + ".pdf"); + + UBExportDocument ubzExporter; + ubzExporter.setVerbode(false); + ubzExporter.persistsDocument(mSourceDocument, mPublishingPath + "/" + documentName + ".ubz"); + + // remove all useless files + + for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) { + QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.svg",pageIndex); + + QFile::remove(filename); + } + + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::imageDirectory); + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::objectDirectory); + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::videoDirectory); + UBFileSystemUtils::deleteDir(mPublishingPath + "/" + UBPersistenceManager::audioDirectory); + + mTmpZipFile = UBFileSystemUtils::defaultTempDirPath() + "/" + UBStringUtils::toCanonicalUuid(QUuid::createUuid()) + ".ubw~"; + + QuaZip zip(mTmpZipFile); + zip.setFileNameCodec("UTF-8"); + if (!zip.open(QuaZip::mdCreate)) + { + qWarning() << "Export failed. Cause: zip.open(): " << zip.getZipError() << "," << mTmpZipFile; + QApplication::restoreOverrideCursor(); + return; + } + + QuaZipFile outFile(&zip); + + if (!UBFileSystemUtils::compressDirInZip(mPublishingPath, "", &outFile, true)) + { + qWarning("Export failed. compressDirInZip failed ..."); + zip.close(); + UBApplication::showMessage(tr("Export failed.")); + QApplication::restoreOverrideCursor(); + return; + } + + if (zip.getZipError() != 0) + { + qWarning("Export failed. Cause: zip.close(): %d", zip.getZipError()); + zip.close(); + UBApplication::showMessage(tr("Export failed.")); + QApplication::restoreOverrideCursor(); + return; + } + + zip.close(); + + } + else + { + UBApplication::showMessage(tr("Export canceled ...")); + QApplication::restoreOverrideCursor(); + } +} + +void UBDocumentPublisher::rasterizeScenes() +{ + + for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) + { + UBApplication::showMessage(tr("Converting page %1/%2 ...").arg(UBDocumentContainer::pageFromSceneIndex(pageIndex)).arg(mPublishingSize), true); + + UBDocumentProxy publishingDocument(mPublishingPath); + UBSvgSubsetRasterizer rasterizer(&publishingDocument, pageIndex); + + QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.jpg",pageIndex); + + rasterizer.rasterizeToFile(filename); + + } +} + + +void UBDocumentPublisher::updateGoogleMapApiKey() +{ + QDir widgestDir(mPublishingPath + "/" + UBPersistenceManager::widgetDirectory); + + QString uniboardWebGoogleMapApiKey = UBSettings::settings()->uniboardWebGoogleMapApiKey->get().toString(); + + foreach(QFileInfo dirInfo, widgestDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + QString config = UBFileSystemUtils::readTextFile(dirInfo.absoluteFilePath() + "/config.xml").toLower(); + + if (config.contains("google") && config.contains("map")) + { + QDir widgetDir(dirInfo.absoluteFilePath()); + + foreach(QFileInfo fileInfo, widgetDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)) + { + QFile file(fileInfo.absoluteFilePath()); + + if (file.open(QIODevice::ReadWrite)) + { + QTextStream stream(&file); + QString content = stream.readAll(); + + if (content.contains("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og")) + { + content.replace("ABQIAAAA6vtVqAUu8kZ_eTz7c8kwSBT9UCAhw_xm0LNFHsWmQxTJAdp5lxSY_5r-lZriY_7sACaMnl80JcX6Og", + uniboardWebGoogleMapApiKey); + + file.resize(0); + file.write(content.toUtf8()); + } + file.close(); + } + } + } + } +} + + +void UBDocumentPublisher::upgradeDocumentForPublishing() +{ + for (int pageIndex = 0; pageIndex < mPublishingSize; pageIndex++) + { + UBDocumentProxy publishingDocument(mPublishingPath); + UBGraphicsScene *scene = UBSvgSubsetAdaptor::loadScene(&publishingDocument, pageIndex); + + QList widgets; + + foreach(QGraphicsItem* item, scene->items()){ + UBGraphicsW3CWidgetItem *widgetItem = dynamic_cast(item); + + if(widgetItem){ + generateWidgetPropertyScript(widgetItem, UBDocumentContainer::pageFromSceneIndex(pageIndex)); + widgets << widgetItem; + } + } + + QString filename = mPublishingPath + UBFileSystemUtils::digitFileFormat("/page%1.json",pageIndex); + + QFile jsonFile(filename); + if (jsonFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + jsonFile.write("{\n"); + jsonFile.write(QString(" \"scene\": {\n").toUtf8()); + jsonFile.write(QString(" \"x\": %1,\n").arg(scene->normalizedSceneRect().x()).toUtf8()); + jsonFile.write(QString(" \"y\": %1,\n").arg(scene->normalizedSceneRect().y()).toUtf8()); + jsonFile.write(QString(" \"width\": %1,\n").arg(scene->normalizedSceneRect().width()).toUtf8()); + jsonFile.write(QString(" \"height\": %1\n").arg(scene->normalizedSceneRect().height()).toUtf8()); + jsonFile.write(QString(" },\n").toUtf8()); + + jsonFile.write(QString(" \"widgets\": [\n").toUtf8()); + + bool first = true; + + foreach(UBGraphicsW3CWidgetItem* widget, widgets) + { + if (!first) + jsonFile.write(QString(" ,\n").toUtf8()); + + jsonFile.write(QString(" {\n").toUtf8()); + jsonFile.write(QString(" \"uuid\": \"%1\",\n").arg(UBStringUtils::toCanonicalUuid(widget->uuid())).toUtf8()); + jsonFile.write(QString(" \"id\": \"%1\",\n").arg(widget->metadatas().id).toUtf8()); + + jsonFile.write(QString(" \"name\": \"%1\",\n").arg(widget->metadatas().name).toUtf8()); + jsonFile.write(QString(" \"description\": \"%1\",\n").arg(widget->metadatas().description).toUtf8()); + jsonFile.write(QString(" \"author\": \"%1\",\n").arg(widget->metadatas().author).toUtf8()); + jsonFile.write(QString(" \"authorEmail\": \"%1\",\n").arg(widget->metadatas().authorEmail).toUtf8()); + jsonFile.write(QString(" \"authorHref\": \"%1\",\n").arg(widget->metadatas().authorHref).toUtf8()); + jsonFile.write(QString(" \"version\": \"%1\",\n").arg(widget->metadatas().authorHref).toUtf8()); + + jsonFile.write(QString(" \"x\": %1,\n").arg(widget->sceneBoundingRect().x()).toUtf8()); + jsonFile.write(QString(" \"y\": %1,\n").arg(widget->sceneBoundingRect().y()).toUtf8()); + jsonFile.write(QString(" \"width\": %1,\n").arg(widget->sceneBoundingRect().width()).toUtf8()); + jsonFile.write(QString(" \"height\": %1,\n").arg(widget->sceneBoundingRect().height()).toUtf8()); + + jsonFile.write(QString(" \"nominalWidth\": %1,\n").arg(widget->boundingRect().width()).toUtf8()); + jsonFile.write(QString(" \"nominalHeight\": %1,\n").arg(widget->boundingRect().height()).toUtf8()); + + QString url = UBPersistenceManager::widgetDirectory + "/" + widget->uuid().toString() + ".wgt"; + jsonFile.write(QString(" \"src\": \"%1\",\n").arg(url).toUtf8()); + QString startFile = widget->mainHtmlFileName(); + jsonFile.write(QString(" \"startFile\": \"%1\",\n").arg(startFile).toUtf8()); + + QMap preferences = widget->UBGraphicsWidgetItem::preferences(); + + jsonFile.write(QString(" \"preferences\": {\n").toUtf8()); + + foreach(QString key, preferences.keys()) + { + QString sep = ","; + if (key == preferences.keys().last()) + sep = ""; + + jsonFile.write(QString(" \"%1\": \"%2\"%3\n") + .arg(key) + .arg(preferences.value(key)) + .arg(sep) + .toUtf8()); + } + jsonFile.write(QString(" },\n").toUtf8()); + + jsonFile.write(QString(" \"datastore\": {\n").toUtf8()); + + QMap datastoreEntries = widget->datastoreEntries(); + + foreach(QString entry, datastoreEntries.keys()) + { + QString sep = ","; + if (entry == datastoreEntries.keys().last()) + sep = ""; + + jsonFile.write(QString(" \"%1\": \"%2\"%3\n") + .arg(entry) + .arg(datastoreEntries.value(entry)) + .arg(sep) + .toUtf8()); + } + jsonFile.write(QString(" }\n").toUtf8()); + + jsonFile.write(QString(" }\n").toUtf8()); + + first = false; + } + + jsonFile.write(" ]\n"); + jsonFile.write("}\n"); + } + else + { + qWarning() << "Cannot open file" << filename << "for saving page state"; + } + + delete scene; + } + + updateGoogleMapApiKey(); +} + + +void UBDocumentPublisher::generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber) +{ + + QMap preferences = widgetItem->UBGraphicsWidgetItem::preferences(); + QMap datastoreEntries = widgetItem->datastoreEntries(); + + QString startFileName = widgetItem->mainHtmlFileName(); + + if (!startFileName.startsWith("http://")) + { + QString startFilePath = mPublishingPath + "/" + UBPersistenceManager::widgetDirectory + "/" + widgetItem->uuid().toString() + ".wgt/" + startFileName; + + QFile startFile(startFilePath); + + if (startFile.exists()) + { + if (startFile.open(QIODevice::ReadWrite)) + { + QTextStream stream(&startFile); + QStringList lines; + + bool addedJs = false; + + QString line; + do + { + line = stream.readLine(); + if (!line.isNull()) + { + lines << line; + + if (!addedJs && line.contains("") ) // TODO UB 4.6, this is naive ... the HEAD tag may be on several lines + { + lines << ""; + lines << " "; + lines << ""; + + addedJs = true; + } + } + } + while (!line.isNull()); + + startFile.resize(0); + startFile.write(lines.join("\n").toUtf8()); // TODO UB 4.x detect real html encoding + + startFile.close(); + } + } + } + else{ + qWarning() << "Remote Widget start file, cannot inject widget preferences and datastore entries"; + } +} + +void UBDocumentPublisher::init() +{ + mCrlf=0x0d; + mCrlf+=0x0a; + mDocInfos.title = ""; + mDocInfos.description = ""; + + mpCookieJar = new QNetworkCookieJar(); + mpNetworkMgr = new QNetworkAccessManager(this); + + connect(mpNetworkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*))); +} + +void UBDocumentPublisher::onFinished(QNetworkReply *reply) +{ + QVariant cookieHeader = reply->rawHeader("Set-Cookie"); + // First we concatenate all the Set-Cookie values (the packet can contains many of them) + QStringList qslCookie = cookieHeader.toString().split("\n"); + QString qsCookieValue = qslCookie.at(0); + for (int i = 1; i < qslCookie.size(); i++) { + qsCookieValue += "; " +qslCookie.at(i); + } + + // Now we isolate every cookie value + QStringList qslCookieVals = qsCookieValue.split("; "); + + bool bTransferOk = false; + + for(int j = 0; j < qslCookieVals.size(); j++) + { + qDebug() << j; + if(qslCookieVals.at(j).startsWith("assetStatus")) + { + QStringList qslAsset = qslCookieVals.at(j).split("="); + if(qslAsset.at(1) == "UPLOADED") + { + bTransferOk = true; + break; + } + } + } + + if(bTransferOk) + { + UBApplication::showMessage(tr("Document uploaded correctly on the web.")); + } + else + { + UBApplication::showMessage(tr("Failed to upload document on the web.")); + } + + reply->deleteLater(); +} + +void UBDocumentPublisher::sendUbw(QString username, QString password) +{ + if (QFile::exists(mTmpZipFile)) + { + QFile f(mTmpZipFile); + if (f.open(QIODevice::ReadOnly)) + { + QFileInfo fi(f); + QByteArray ba = f.readAll(); + QString boundary,data, multipartHeader; + QByteArray datatoSend; + + boundary = "---WebKitFormBoundaryDKBTgA53MiyWrzLY"; + multipartHeader = "multipart/form-data; boundary="+boundary; + + data="--"+boundary+mCrlf; + data+="Content-Disposition: form-data; name=\"title\"" + mCrlf + mCrlf + mDocInfos.title + mCrlf; + data+="--"+boundary+mCrlf; + data+="Content-Disposition: form-data; name=\"description\"" + mCrlf + mCrlf + mDocInfos.description.remove("\n") + mCrlf; + data+="--"+boundary+mCrlf; + data+="Content-Disposition: form-data; name=\"file\"; filename=\""+ fi.fileName() +"\""+mCrlf; + data+="Content-Type: application/octet-stream"+mCrlf+mCrlf; + datatoSend=data.toAscii(); // convert data string to byte array for request + datatoSend += ba; + datatoSend += mCrlf; + datatoSend += QString("--%0--%1").arg(boundary).arg(mCrlf); + + QNetworkRequest request(QUrl(QString(DOCPUBLICATION_URL).toAscii().constData())); + + request.setHeader(QNetworkRequest::ContentTypeHeader, multipartHeader); + request.setHeader(QNetworkRequest::ContentLengthHeader,datatoSend.size()); + QString b64Auth = getBase64Of(QString("%0:%1").arg(username).arg(password)); + request.setRawHeader("Authorization", QString("Basic %0").arg(b64Auth).toAscii().constData()); + request.setRawHeader("Host", "planete.sankore.org"); + request.setRawHeader("Accept", "*/*"); + request.setRawHeader("Accept-Language", "en-US,*"); + + mpCookieJar->setCookiesFromUrl(mCookies, QUrl(DOCPUBLICATION_URL)); + mpNetworkMgr->setCookieJar(mpCookieJar); + + // Send the file + mpNetworkMgr->post(request,datatoSend); + } + } +} + +QString UBDocumentPublisher::getBase64Of(QString stringToEncode) +{ + return stringToEncode.toAscii().toBase64(); +} + +// --------------------------------------------------------- +UBProxyLoginDlg::UBProxyLoginDlg(QWidget *parent, const char *name):QDialog(parent) + , mpLayout(NULL) + , mpUserLayout(NULL) + , mpPasswordLayout(NULL) + , mpButtons(NULL) + , mpUserLabel(NULL) + , mpPasswordLabel(NULL) + , mpUsername(NULL) + , mpPassword(NULL) +{ + setObjectName(name); + setFixedSize(400, 150); + setWindowTitle(tr("Proxy Login")); + + mpLayout = new QVBoxLayout(); + setLayout(mpLayout); + mpUserLayout = new QHBoxLayout(); + mpLayout->addLayout(mpUserLayout); + mpPasswordLayout = new QHBoxLayout(); + mpLayout->addLayout(mpPasswordLayout); + + mpUserLabel = new QLabel(tr("Username:"), this); + mpUsername = new QLineEdit(this); + mpUserLayout->addWidget(mpUserLabel, 0); + mpUserLayout->addWidget(mpUsername, 1); + + mpPasswordLabel = new QLabel(tr("Password:"), this); + mpPassword = new QLineEdit(this); + mpPasswordLayout->addWidget(mpPasswordLabel, 0); + mpPasswordLayout->addWidget(mpPassword, 1); + + mpButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); + mpLayout->addWidget(mpButtons); + + connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); + connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); + +} + +UBProxyLoginDlg::~UBProxyLoginDlg() +{ + if(NULL != mpLayout) + { + delete mpLayout; + mpLayout = NULL; + } + if(NULL != mpButtons) + { + delete mpButtons; + mpButtons = NULL; + } + if(NULL != mpUserLabel) + { + delete mpUserLabel; + mpUserLabel = NULL; + } + if(NULL != mpPasswordLabel) + { + delete mpPasswordLabel; + mpPasswordLabel = NULL; + } + if(NULL != mpUsername) + { + delete mpUsername; + mpUsername = NULL; + } + if(NULL != mpPassword) + { + delete mpPassword; + mpPassword = NULL; + } +} + +// --------------------------------------------------------- +UBPublicationDlg::UBPublicationDlg(QWidget *parent, const char *name):QDialog(parent) + , mpLayout(NULL) + , mpTitleLayout(NULL) + , mpTitleLabel(NULL) + , mpTitle(NULL) + , mpDescLabel(NULL) + , mpDescription(NULL) + , mpButtons(NULL) +{ + setObjectName(name); + setWindowTitle(tr("Publish document on the web")); + + resize(500, 300); + + mpLayout = new QVBoxLayout(); + setLayout(mpLayout); + + mpTitleLabel = new QLabel(tr("Title:"), this); + mpTitle = new QLineEdit(this); + mpTitleLayout = new QHBoxLayout(); + mpTitleLayout->addWidget(mpTitleLabel, 0); + mpTitleLayout->addWidget(mpTitle, 1); + mpLayout->addLayout(mpTitleLayout, 0); + + mpDescLabel = new QLabel(tr("Description:"), this); + mpLayout->addWidget(mpDescLabel, 0); + + mpDescription = new QTextEdit(this); + mpLayout->addWidget(mpDescription, 1); + + mpButtons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); + mpButtons->button(QDialogButtonBox::Ok)->setText(tr("Publish")); + mpLayout->addWidget(mpButtons); + + mpButtons->button(QDialogButtonBox::Ok)->setEnabled(false); + + connect(mpButtons, SIGNAL(accepted()), this, SLOT(accept())); + connect(mpButtons, SIGNAL(rejected()), this, SLOT(reject())); + connect(mpTitle, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged())); + connect(mpDescription, SIGNAL(textChanged()), this, SLOT(onTextChanged())); +} + +UBPublicationDlg::~UBPublicationDlg() +{ + if(NULL != mpTitleLabel) + { + delete mpTitleLabel; + mpTitleLabel = NULL; + } + if(NULL != mpTitle) + { + delete mpTitle; + mpTitle = NULL; + } + if(NULL != mpDescLabel) + { + delete mpDescLabel; + mpDescLabel = NULL; + } + if(NULL != mpDescription) + { + delete mpDescription; + mpDescription = NULL; + } + if(NULL != mpButtons) + { + delete mpButtons; + mpButtons = NULL; + } + if(NULL != mpTitleLayout) + { + delete mpTitleLayout; + mpTitleLayout = NULL; + } + if(NULL != mpLayout) + { + delete mpLayout; + mpLayout = NULL; + } +} + +void UBPublicationDlg::onTextChanged() +{ + bool bPublishButtonState = false; + if(mpTitle->text() != "" && mpDescription->document()->toPlainText() != "") + { + bPublishButtonState = true; + } + else + { + bPublishButtonState = false; + } + + mpButtons->button(QDialogButtonBox::Ok)->setEnabled(bPublishButtonState); +} diff --git a/src/adaptors/publishing/UBDocumentPublisher.h b/src/adaptors/publishing/UBDocumentPublisher.h index 7f8b2bb5..6b4b5f27 100644 --- a/src/adaptors/publishing/UBDocumentPublisher.h +++ b/src/adaptors/publishing/UBDocumentPublisher.h @@ -19,124 +19,124 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBDOCUMENTPUBLISHER_H -#define UBDOCUMENTPUBLISHER_H - -#include -#include - -#include "ui_webPublishing.h" - -#define DOCPUBLICATION_URL "http://planete.sankore.org/xwiki/bin/view/CreateResources/UniboardUpload?xpage=plain&outputSyntax=plain" - -typedef struct -{ - QString title; - QString description; -} sDocumentInfos; - -class UBDocumentProxy; -class UBServerXMLHttpRequest; -class UBGraphicsW3CWidgetItem; -class QWebView; - -class UBProxyLoginDlg : public QDialog -{ - Q_OBJECT -public: - UBProxyLoginDlg(QWidget* parent=0, const char* name="ProxyLoginDlg"); - ~UBProxyLoginDlg(); - - QString username(){return mpUsername->text();} - QString password(){return mpPassword->text();} - -private: - QVBoxLayout* mpLayout; - QHBoxLayout* mpUserLayout; - QHBoxLayout* mpPasswordLayout; - QDialogButtonBox* mpButtons; - QLabel* mpUserLabel; - QLabel* mpPasswordLabel; - QLineEdit* mpUsername; - QLineEdit* mpPassword; -}; - -class UBPublicationDlg : public QDialog -{ - Q_OBJECT -public: - UBPublicationDlg(QWidget* parent=0, const char* name="UBPublicationDlg"); - ~UBPublicationDlg(); - - QString title(){return mpTitle->text();} - QString description(){return mpDescription->document()->toPlainText();} - -private slots: - void onTextChanged(); - -private: - QVBoxLayout* mpLayout; - QHBoxLayout* mpTitleLayout; - QLabel* mpTitleLabel; - QLineEdit* mpTitle; - QLabel* mpDescLabel; - QTextEdit* mpDescription; - QDialogButtonBox* mpButtons; -}; - - -class UBDocumentPublisher : public QObject -{ - Q_OBJECT; - -public: - explicit UBDocumentPublisher(UBDocumentProxy* sourceDocument, QObject *parent = 0); - virtual ~UBDocumentPublisher(); - - void publish(); - -signals: - - void loginDone(); - -protected: - - virtual void updateGoogleMapApiKey(); - virtual void rasterizeScenes(); - virtual void upgradeDocumentForPublishing(); - virtual void generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber); - -private slots: - - void onFinished(QNetworkReply* reply); - -private: - - UBDocumentProxy *mSourceDocument; - - //UBDocumentProxy *mPublishingDocument; - QString mPublishingPath; - int mPublishingSize; - - - void init(); - void sendUbw(QString username, QString password); - QString getBase64Of(QString stringToEncode); - - QHBoxLayout* mpLayout; - QNetworkAccessManager* mpNetworkMgr; - QNetworkCookieJar* mpCookieJar; - QString mUsername; - QString mPassword; - QString mCrlf; - bool bLoginCookieSet; - - void buildUbwFile(); - QString mTmpZipFile; - QList mCookies; - sDocumentInfos mDocInfos; - -}; -#endif // UBDOCUMENTPUBLISHER_H + + +#ifndef UBDOCUMENTPUBLISHER_H +#define UBDOCUMENTPUBLISHER_H + +#include +#include + +#include "ui_webPublishing.h" + +#define DOCPUBLICATION_URL "http://planete.sankore.org/xwiki/bin/view/CreateResources/UniboardUpload?xpage=plain&outputSyntax=plain" + +typedef struct +{ + QString title; + QString description; +} sDocumentInfos; + +class UBDocumentProxy; +class UBServerXMLHttpRequest; +class UBGraphicsW3CWidgetItem; +class QWebView; + +class UBProxyLoginDlg : public QDialog +{ + Q_OBJECT +public: + UBProxyLoginDlg(QWidget* parent=0, const char* name="ProxyLoginDlg"); + ~UBProxyLoginDlg(); + + QString username(){return mpUsername->text();} + QString password(){return mpPassword->text();} + +private: + QVBoxLayout* mpLayout; + QHBoxLayout* mpUserLayout; + QHBoxLayout* mpPasswordLayout; + QDialogButtonBox* mpButtons; + QLabel* mpUserLabel; + QLabel* mpPasswordLabel; + QLineEdit* mpUsername; + QLineEdit* mpPassword; +}; + +class UBPublicationDlg : public QDialog +{ + Q_OBJECT +public: + UBPublicationDlg(QWidget* parent=0, const char* name="UBPublicationDlg"); + ~UBPublicationDlg(); + + QString title(){return mpTitle->text();} + QString description(){return mpDescription->document()->toPlainText();} + +private slots: + void onTextChanged(); + +private: + QVBoxLayout* mpLayout; + QHBoxLayout* mpTitleLayout; + QLabel* mpTitleLabel; + QLineEdit* mpTitle; + QLabel* mpDescLabel; + QTextEdit* mpDescription; + QDialogButtonBox* mpButtons; +}; + + +class UBDocumentPublisher : public QObject +{ + Q_OBJECT; + +public: + explicit UBDocumentPublisher(UBDocumentProxy* sourceDocument, QObject *parent = 0); + virtual ~UBDocumentPublisher(); + + void publish(); + +signals: + + void loginDone(); + +protected: + + virtual void updateGoogleMapApiKey(); + virtual void rasterizeScenes(); + virtual void upgradeDocumentForPublishing(); + virtual void generateWidgetPropertyScript(UBGraphicsW3CWidgetItem *widgetItem, int pageNumber); + +private slots: + + void onFinished(QNetworkReply* reply); + +private: + + UBDocumentProxy *mSourceDocument; + + //UBDocumentProxy *mPublishingDocument; + QString mPublishingPath; + int mPublishingSize; + + + void init(); + void sendUbw(QString username, QString password); + QString getBase64Of(QString stringToEncode); + + QHBoxLayout* mpLayout; + QNetworkAccessManager* mpNetworkMgr; + QNetworkCookieJar* mpCookieJar; + QString mUsername; + QString mPassword; + QString mCrlf; + bool bLoginCookieSet; + + void buildUbwFile(); + QString mTmpZipFile; + QList mCookies; + sDocumentInfos mDocInfos; + +}; +#endif // UBDOCUMENTPUBLISHER_H diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index 73f70795..7d5a42e3 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -19,2499 +19,2499 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBBoardController.h" - -#include -#include - -#include "frameworks/UBFileSystemUtils.h" -#include "frameworks/UBPlatformUtils.h" - -#include "core/UBApplication.h" -#include "core/UBSettings.h" -#include "core/UBSetting.h" -#include "core/UBPersistenceManager.h" -#include "core/UBApplicationController.h" -#include "core/UBDocumentManager.h" -#include "core/UBMimeData.h" -#include "core/UBDownloadManager.h" - -#include "network/UBHttpGet.h" - -#include "gui/UBMessageWindow.h" -#include "gui/UBResources.h" -#include "gui/UBToolbarButtonGroup.h" -#include "gui/UBMainWindow.h" -#include "gui/UBToolWidget.h" -#include "gui/UBKeyboardPalette.h" -#include "gui/UBMagnifer.h" -#include "gui/UBDockPaletteWidget.h" -#include "gui/UBDockTeacherGuideWidget.h" -#include "gui/UBTeacherGuideWidget.h" - -#include "domain/UBGraphicsPixmapItem.h" -#include "domain/UBGraphicsItemUndoCommand.h" -#include "domain/UBGraphicsProxyWidget.h" -#include "domain/UBGraphicsSvgItem.h" -#include "domain/UBGraphicsWidgetItem.h" -#include "domain/UBGraphicsMediaItem.h" -#include "domain/UBGraphicsPDFItem.h" -#include "domain/UBGraphicsTextItem.h" -#include "domain/UBPageSizeUndoCommand.h" -#include "domain/UBGraphicsGroupContainerItem.h" -#include "domain/UBItem.h" -#include "board/UBFeaturesController.h" -#include "domain/UBGraphicsStrokesGroup.h" - -#include "gui/UBFeaturesWidget.h" - -#include "tools/UBToolsManager.h" - -#include "document/UBDocumentProxy.h" -#include "document/UBDocumentController.h" - -#include "board/UBDrawingController.h" -#include "board/UBBoardView.h" - -#include "podcast/UBPodcastController.h" - -#include "adaptors/UBMetadataDcSubsetAdaptor.h" -#include "adaptors/UBSvgSubsetAdaptor.h" - -#include "UBBoardPaletteManager.h" - -#include "core/UBSettings.h" - -#include "core/memcheck.h" - -UBBoardController::UBBoardController(UBMainWindow* mainWindow) - : UBDocumentContainer(mainWindow->centralWidget()) - , mMainWindow(mainWindow) - , mActiveScene(0) - , mActiveSceneIndex(-1) - , mPaletteManager(0) - , mSoftwareUpdateDialog(0) - , mMessageWindow(0) - , mControlView(0) - , mDisplayView(0) - , mControlContainer(0) - , mControlLayout(0) - , mZoomFactor(1.0) - , mIsClosing(false) - , mSystemScaleFactor(1.0) - , mCleanupDone(false) - , mCacheWidgetIsEnabled(false) - , mDeletingSceneIndex(-1) - , mMovingSceneIndex(-1) - , mActionGroupText(tr("Group")) - , mActionUngroupText(tr("Ungroup")) -{ - mZoomFactor = UBSettings::settings()->boardZoomFactor->get().toDouble(); - - int penColorIndex = UBSettings::settings()->penColorIndex(); - int markerColorIndex = UBSettings::settings()->markerColorIndex(); - - mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(penColorIndex); - mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(penColorIndex); - mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(markerColorIndex); - mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(markerColorIndex); - - QDesktopWidget* desktop = UBApplication::desktop(); - int dpiCommon = (desktop->physicalDpiX() + desktop->physicalDpiY()) / 2; - int sPixelsPerMillimeter = qRound(dpiCommon / UBGeometryUtils::inchSize); - UBSettings::settings()->crossSize = 10*sPixelsPerMillimeter; -} - - -void UBBoardController::init() -{ - setupViews(); - setupToolbar(); - - connect(UBApplication::undoStack, SIGNAL(canUndoChanged(bool)) - , this, SLOT(undoRedoStateChange(bool))); - - connect(UBApplication::undoStack, SIGNAL(canRedoChanged (bool)) - , this, SLOT(undoRedoStateChange(bool))); - - connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) - , this, SLOT(setToolCursor(int))); - - connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) - , this, SLOT(stylusToolChanged(int))); - - connect(UBApplication::app(), SIGNAL(lastWindowClosed()) - , this, SLOT(lastWindowClosed())); - - connect(UBDownloadManager::downloadManager(), SIGNAL(downloadModalFinished()), this, SLOT(onDownloadModalFinished())); - connect(UBDownloadManager::downloadManager(), SIGNAL(addDownloadedFileToBoard(bool,QUrl,QUrl,QString,QByteArray,QPointF,QSize,bool)), this, SLOT(downloadFinished(bool,QUrl,QUrl,QString,QByteArray,QPointF,QSize,bool))); - - UBDocumentProxy* doc = UBPersistenceManager::persistenceManager()->createDocument(); - - setActiveDocumentScene(doc); - - connect(UBApplication::mainWindow->actionGroupItems, SIGNAL(triggered()), this, SLOT(groupButtonClicked())); - - undoRedoStateChange(true); -} - - -UBBoardController::~UBBoardController() -{ - delete mDisplayView; -} - - -int UBBoardController::currentPage() -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return mActiveSceneIndex; - return mActiveSceneIndex + 1; -} - -void UBBoardController::setupViews() -{ - mControlContainer = new QWidget(mMainWindow->centralWidget()); - - mControlLayout = new QHBoxLayout(mControlContainer); - mControlLayout->setContentsMargins(0, 0, 0, 0); - - mControlView = new UBBoardView(this, mControlContainer, true, false); - mControlView->setInteractive(true); - mControlView->setMouseTracking(true); - - mControlView->grabGesture(Qt::SwipeGesture); - - mControlView->setTransformationAnchor(QGraphicsView::NoAnchor); - - mControlLayout->addWidget(mControlView); - mControlContainer->setObjectName("ubBoardControlContainer"); - mMainWindow->addBoardWidget(mControlContainer); - - connect(mControlView, SIGNAL(resized(QResizeEvent*)), this, SLOT(boardViewResized(QResizeEvent*))); - - // TODO UB 4.x Optimization do we have to create the display view even if their is - // only 1 screen - // - mDisplayView = new UBBoardView(this, UBItemLayerType::FixedBackground, UBItemLayerType::Tool, 0); - mDisplayView->setInteractive(false); - mDisplayView->setTransformationAnchor(QGraphicsView::NoAnchor); - - mMessageWindow = new UBMessageWindow(mControlView); - mMessageWindow->hide(); - - mPaletteManager = new UBBoardPaletteManager(mControlContainer, this); - connect(this, SIGNAL(activeSceneChanged()), mPaletteManager, SLOT(activeSceneChanged())); - -} - - -void UBBoardController::setupLayout() -{ - if(mPaletteManager) - mPaletteManager->setupLayout(); -} - - -void UBBoardController::setBoxing(QRect displayRect) -{ - if (displayRect.isNull()) - { - mControlLayout->setContentsMargins(0, 0, 0, 0); - return; - } - - qreal controlWidth = (qreal)mMainWindow->centralWidget()->width(); - qreal controlHeight = (qreal)mMainWindow->centralWidget()->height(); - qreal displayWidth = (qreal)displayRect.width(); - qreal displayHeight = (qreal)displayRect.height(); - - qreal displayRatio = displayWidth / displayHeight; - qreal controlRatio = controlWidth / controlHeight; - - if (displayRatio < controlRatio) - { - // Pillarboxing - int boxWidth = (controlWidth - (displayWidth * (controlHeight / displayHeight))) / 2; - mControlLayout->setContentsMargins(boxWidth, 0, boxWidth, 0); - } - else if (displayRatio > controlRatio) - { - // Letterboxing - int boxHeight = (controlHeight - (displayHeight * (controlWidth / displayWidth))) / 2; - mControlLayout->setContentsMargins(0, boxHeight, 0, boxHeight); - } - else - { - // No boxing - mControlLayout->setContentsMargins(0, 0, 0, 0); - } -} - - -QSize UBBoardController::displayViewport() -{ - return mDisplayView->geometry().size(); -} - - -QSize UBBoardController::controlViewport() -{ - return mControlView->geometry().size(); -} - - -QRectF UBBoardController::controlGeometry() -{ - return mControlView->geometry(); -} - - -void UBBoardController::setupToolbar() -{ - UBSettings *settings = UBSettings::settings(); - - // Setup color choice widget - QList colorActions; - colorActions.append(mMainWindow->actionColor0); - colorActions.append(mMainWindow->actionColor1); - colorActions.append(mMainWindow->actionColor2); - colorActions.append(mMainWindow->actionColor3); - - UBToolbarButtonGroup *colorChoice = - new UBToolbarButtonGroup(mMainWindow->boardToolBar, colorActions); - - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice); - - connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), colorChoice, SLOT(displayText(QVariant))); - connect(colorChoice, SIGNAL(activated(int)), this, SLOT(setColorIndex(int))); - connect(UBDrawingController::drawingController(), SIGNAL(colorIndexChanged(int)), colorChoice, SLOT(setCurrentIndex(int))); - connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), colorChoice, SLOT(colorPaletteChanged())); - connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), this, SLOT(colorPaletteChanged())); - - colorChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); - colorChoice->colorPaletteChanged(); - - // Setup line width choice widget - QList lineWidthActions; - lineWidthActions.append(mMainWindow->actionLineSmall); - lineWidthActions.append(mMainWindow->actionLineMedium); - lineWidthActions.append(mMainWindow->actionLineLarge); - - UBToolbarButtonGroup *lineWidthChoice = - new UBToolbarButtonGroup(mMainWindow->boardToolBar, lineWidthActions); - - connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), lineWidthChoice, SLOT(displayText(QVariant))); - - connect(lineWidthChoice, SIGNAL(activated(int)) - , UBDrawingController::drawingController(), SLOT(setLineWidthIndex(int))); - - connect(UBDrawingController::drawingController(), SIGNAL(lineWidthIndexChanged(int)) - , lineWidthChoice, SLOT(setCurrentIndex(int))); - - lineWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); - - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice); - - //-----------------------------------------------------------// - // Setup eraser width choice widget - - QList eraserWidthActions; - eraserWidthActions.append(mMainWindow->actionEraserSmall); - eraserWidthActions.append(mMainWindow->actionEraserMedium); - eraserWidthActions.append(mMainWindow->actionEraserLarge); - - UBToolbarButtonGroup *eraserWidthChoice = - new UBToolbarButtonGroup(mMainWindow->boardToolBar, eraserWidthActions); - - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice); - - connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), eraserWidthChoice, SLOT(displayText(QVariant))); - connect(eraserWidthChoice, SIGNAL(activated(int)), UBDrawingController::drawingController(), SLOT(setEraserWidthIndex(int))); - - eraserWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); - eraserWidthChoice->setCurrentIndex(settings->eraserWidthIndex()); - - mMainWindow->boardToolBar->insertSeparator(mMainWindow->actionBackgrounds); - - //-----------------------------------------------------------// - - UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard); - UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->tutorialToolBar, mMainWindow->actionBoard); - - UBApplication::app()->decorateActionMenu(mMainWindow->actionMenu); - - mMainWindow->actionBoard->setVisible(false); - - mMainWindow->webToolBar->hide(); - mMainWindow->documentToolBar->hide(); - mMainWindow->tutorialToolBar->hide(); - - connectToolbar(); - initToolbarTexts(); -} - - -void UBBoardController::setToolCursor(int tool) -{ - if (mActiveScene) - { - mActiveScene->setToolCursor(tool); - } - - mControlView->setToolCursor(tool); -} - - -void UBBoardController::connectToolbar() -{ - connect(mMainWindow->actionAdd, SIGNAL(triggered()), this, SLOT(addItem())); - connect(mMainWindow->actionNewPage, SIGNAL(triggered()), this, SLOT(addScene())); - connect(mMainWindow->actionDuplicatePage, SIGNAL(triggered()), this, SLOT(duplicateScene())); - - connect(mMainWindow->actionClearPage, SIGNAL(triggered()), this, SLOT(clearScene())); - connect(mMainWindow->actionEraseItems, SIGNAL(triggered()), this, SLOT(clearSceneItems())); - connect(mMainWindow->actionEraseAnnotations, SIGNAL(triggered()), this, SLOT(clearSceneAnnotation())); - connect(mMainWindow->actionEraseBackground,SIGNAL(triggered()),this,SLOT(clearSceneBackground())); - - connect(mMainWindow->actionUndo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(undo())); - connect(mMainWindow->actionRedo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(redo())); - connect(mMainWindow->actionRedo, SIGNAL(triggered()), this, SLOT(startScript())); - connect(mMainWindow->actionBack, SIGNAL( triggered()), this, SLOT(previousScene())); - connect(mMainWindow->actionForward, SIGNAL(triggered()), this, SLOT(nextScene())); - connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(stopScript())); - connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(blackout())); - connect(mMainWindow->actionVirtualKeyboard, SIGNAL(triggered(bool)), this, SLOT(showKeyboard(bool))); - connect(mMainWindow->actionImportPage, SIGNAL(triggered()), this, SLOT(importPage())); -} - -void UBBoardController::startScript() -{ - freezeW3CWidgets(false); -} - -void UBBoardController::stopScript() -{ - freezeW3CWidgets(true); -} - -void UBBoardController::initToolbarTexts() -{ - QList allToolbarActions; - - allToolbarActions << mMainWindow->boardToolBar->actions(); - allToolbarActions << mMainWindow->webToolBar->actions(); - allToolbarActions << mMainWindow->documentToolBar->actions(); - - foreach(QAction* action, allToolbarActions) - { - QString nominalText = action->text(); - QString shortText = truncate(nominalText, 48); - QPair texts(nominalText, shortText); - - mActionTexts.insert(action, texts); - } -} - - -void UBBoardController::setToolbarTexts() -{ - bool highResolution = mMainWindow->width() > 1024; - QSize iconSize; - - if (highResolution) - iconSize = QSize(48, 32); - else - iconSize = QSize(32, 32); - - mMainWindow->boardToolBar->setIconSize(iconSize); - mMainWindow->webToolBar->setIconSize(iconSize); - mMainWindow->documentToolBar->setIconSize(iconSize); - - foreach(QAction* action, mActionTexts.keys()) - { - QPair texts = mActionTexts.value(action); - - if (highResolution) - action->setText(texts.first); - else - { - action->setText(texts.second); - } - - action->setToolTip(texts.first); - } -} - - -QString UBBoardController::truncate(QString text, int maxWidth) -{ - QFontMetricsF fontMetrics(mMainWindow->font()); - return fontMetrics.elidedText(text, Qt::ElideRight, maxWidth); -} - - -void UBBoardController::stylusToolDoubleClicked(int tool) -{ - if (tool == UBStylusTool::ZoomIn || tool == UBStylusTool::ZoomOut) - { - zoomRestore(); - } - else if (tool == UBStylusTool::Hand) - { - centerRestore(); - } -} - - - -void UBBoardController::addScene() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - - UBDocumentContainer::addPage(mActiveSceneIndex + 1); - - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - setActiveDocumentScene(mActiveSceneIndex + 1); - QApplication::restoreOverrideCursor(); -} - -void UBBoardController::addScene(UBGraphicsScene* scene, bool replaceActiveIfEmpty) -{ - if (scene) - { - UBGraphicsScene* clone = scene->sceneDeepCopy(); - - if (scene->document() && (scene->document() != selectedDocument())) - { - foreach(QUrl relativeFile, scene->relativeDependencies()) - { - QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); - QString target = selectedDocument()->persistencePath() + "/" + relativeFile.toString(); - - QFileInfo fi(target); - QDir d = fi.dir(); - - d.mkpath(d.absolutePath()); - QFile::copy(source, target); - } - } - - if (replaceActiveIfEmpty && mActiveScene->isEmpty()) - { - setActiveDocumentScene(mActiveSceneIndex); - } - else - { - persistCurrentScene(); - UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(selectedDocument(), clone, mActiveSceneIndex + 1); - setActiveDocumentScene(mActiveSceneIndex + 1); - } - - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } -} - - -void UBBoardController::addScene(UBDocumentProxy* proxy, int sceneIndex, bool replaceActiveIfEmpty) -{ - UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(proxy, sceneIndex); - - if (scene) - { - addScene(scene, replaceActiveIfEmpty); - } -} - -void UBBoardController::duplicateScene(int nIndex) -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - - QList scIndexes; - scIndexes << nIndex; - duplicatePages(scIndexes); - insertThumbPage(nIndex); - emit documentThumbnailsUpdated(this); - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - setActiveDocumentScene(nIndex + 1); - QApplication::restoreOverrideCursor(); - - emit pageChanged(); -} - -void UBBoardController::duplicateScene() -{ - if (UBApplication::applicationController->displayMode() != UBApplicationController::Board) - return; - duplicateScene(mActiveSceneIndex); -} - -UBGraphicsItem *UBBoardController::duplicateItem(UBItem *item, bool bAsync) -{ - if (!item) - return NULL; - - UBGraphicsItem *retItem = NULL; - - mLastCreatedItem = NULL; - - QUrl sourceUrl; - QByteArray pData; - - //common parameters for any item - QPointF itemPos; - QSizeF itemSize; - - QGraphicsItem *commonItem = dynamic_cast(item); - if (commonItem) - { - qreal shifting = UBSettings::settings()->objectFrameWidth; - itemPos = commonItem->pos() + QPointF(shifting,shifting); - itemSize = commonItem->boundingRect().size(); - commonItem->setSelected(false); - } - - UBMimeType::Enum itemMimeType; - - QString srcFile = item->sourceUrl().toLocalFile(); - if (srcFile.isEmpty()) - srcFile = item->sourceUrl().toString(); - - QString contentTypeHeader; - if (!srcFile.isEmpty()) - contentTypeHeader = UBFileSystemUtils::mimeTypeFromFileName(srcFile); - - if(NULL != qgraphicsitem_cast(commonItem)) - itemMimeType = UBMimeType::Group; - else - itemMimeType = UBFileSystemUtils::mimeTypeFromString(contentTypeHeader); - - switch(static_cast(itemMimeType)) - { - case UBMimeType::AppleWidget: - case UBMimeType::W3CWidget: - { - UBGraphicsWidgetItem *witem = dynamic_cast(item); - if (witem) - { - sourceUrl = witem->getOwnFolder(); - } - }break; - - case UBMimeType::Video: - case UBMimeType::Audio: - { - UBGraphicsMediaItem *mitem = dynamic_cast(item); - if (mitem) - { - sourceUrl = mitem->mediaFileUrl(); - if (bAsync) - { - downloadURL(sourceUrl, srcFile, itemPos, QSize(itemSize.width(), itemSize.height()), false, false); - return NULL; // async operation - } - } - }break; - - case UBMimeType::VectorImage: - { - UBGraphicsSvgItem *viitem = dynamic_cast(item); - if (viitem) - { - pData = viitem->fileData(); - sourceUrl = item->sourceUrl(); - } - }break; - - case UBMimeType::RasterImage: - { - UBGraphicsPixmapItem *pixitem = dynamic_cast(item); - if (pixitem) - { - QBuffer buffer(&pData); - buffer.open(QIODevice::WriteOnly); - QString format = UBFileSystemUtils::extension(item->sourceUrl().toLocalFile()); - pixitem->pixmap().save(&buffer, format.toLatin1()); - } - }break; - - case UBMimeType::Group: - { - UBGraphicsGroupContainerItem* groupItem = dynamic_cast(item); - UBGraphicsGroupContainerItem* duplicatedGroup = NULL; - - QList duplicatedItems; - QList children = groupItem->childItems(); - - mActiveScene->setURStackEnable(false); - foreach(QGraphicsItem* pIt, children){ - UBItem* pItem = dynamic_cast(pIt); - if(pItem){ // we diong sync duplication of all childs. - QGraphicsItem * itemToGroup = dynamic_cast(duplicateItem(pItem, false)); - if (itemToGroup) - duplicatedItems.append(itemToGroup); - } - } - duplicatedGroup = mActiveScene->createGroup(duplicatedItems); - duplicatedGroup->setTransform(groupItem->transform()); - groupItem->setSelected(false); - - retItem = dynamic_cast(duplicatedGroup); - - QGraphicsItem * itemToAdd = dynamic_cast(retItem); - if (itemToAdd) - { - mActiveScene->addItem(itemToAdd); - itemToAdd->setSelected(true); - } - mActiveScene->setURStackEnable(true); - }break; - - case UBMimeType::UNKNOWN: - { - QGraphicsItem *gitem = dynamic_cast(item->deepCopy()); - if (gitem) - { - mActiveScene->addItem(gitem); - gitem->setPos(itemPos); - mLastCreatedItem = gitem; - gitem->setSelected(true); - } - retItem = dynamic_cast(gitem); - }break; - } - - if (retItem) - { - QGraphicsItem *graphicsRetItem = dynamic_cast(retItem); - if (mActiveScene->isURStackIsEnabled()) { //should be deleted after scene own undo stack implemented - UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(mActiveScene, 0, graphicsRetItem); - UBApplication::undoStack->push(uc); - } - return retItem; - } - - UBItem *createdItem = downloadFinished(true, sourceUrl, srcFile, contentTypeHeader, pData, itemPos, QSize(itemSize.width(), itemSize.height()), false); - if (createdItem) - { - createdItem->setSourceUrl(item->sourceUrl()); - item->copyItemParameters(createdItem); - - QGraphicsItem *createdGitem = dynamic_cast(createdItem); - if (createdGitem) - createdGitem->setPos(itemPos); - mLastCreatedItem = dynamic_cast(createdItem); - mLastCreatedItem->setSelected(true); - - retItem = dynamic_cast(createdItem); - } - - return retItem; -} - -void UBBoardController::deleteScene(int nIndex) -{ - if (selectedDocument()->pageCount()>=2) - { - mDeletingSceneIndex = nIndex; - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - showMessage(tr("Delete page %1 from document").arg(nIndex), true); - - QList scIndexes; - scIndexes << nIndex; - deletePages(scIndexes); - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - if (nIndex >= pageCount()) - nIndex = pageCount()-1; - setActiveDocumentScene(nIndex); - showMessage(tr("Page %1 deleted").arg(nIndex)); - QApplication::restoreOverrideCursor(); - mDeletingSceneIndex = -1; - } -} - - -void UBBoardController::clearScene() -{ - if (mActiveScene) - { - freezeW3CWidgets(true); - mActiveScene->clearContent(UBGraphicsScene::clearItemsAndAnnotations); - updateActionStates(); - } -} - - -void UBBoardController::clearSceneItems() -{ - if (mActiveScene) - { - freezeW3CWidgets(true); - mActiveScene->clearContent(UBGraphicsScene::clearItems); - updateActionStates(); - } -} - - -void UBBoardController::clearSceneAnnotation() -{ - if (mActiveScene) - { - mActiveScene->clearContent(UBGraphicsScene::clearAnnotations); - updateActionStates(); - } -} - -void UBBoardController::clearSceneBackground() -{ - if (mActiveScene) - { - mActiveScene->clearContent(UBGraphicsScene::clearBackground); - updateActionStates(); - } -} - -void UBBoardController::showDocumentsDialog() -{ - if (selectedDocument()) - persistCurrentScene(); - - UBApplication::mainWindow->actionLibrary->setChecked(false); - -} - -void UBBoardController::libraryDialogClosed(int ret) -{ - Q_UNUSED(ret); - - mMainWindow->actionLibrary->setChecked(false); -} - - -void UBBoardController::blackout() -{ - UBApplication::applicationController->blackout(); -} - - -void UBBoardController::showKeyboard(bool show) -{ - if(show) - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - mPaletteManager->showVirtualKeyboard(show); -} - - -void UBBoardController::zoomIn(QPointF scenePoint) -{ - if (mControlView->transform().m11() > UB_MAX_ZOOM) - { - qApp->beep(); - return; - } - zoom(mZoomFactor, scenePoint); -} - - -void UBBoardController::zoomOut(QPointF scenePoint) -{ - if ((mControlView->horizontalScrollBar()->maximum() == 0) && (mControlView->verticalScrollBar()->maximum() == 0)) - { - // Do not zoom out if we reached the maximum - qApp->beep(); - return; - } - - qreal newZoomFactor = 1 / mZoomFactor; - - zoom(newZoomFactor, scenePoint); -} - - -void UBBoardController::zoomRestore() -{ - QTransform tr; - - tr.scale(mSystemScaleFactor, mSystemScaleFactor); - mControlView->setTransform(tr); - - centerRestore(); - - foreach(QGraphicsItem *gi, mActiveScene->selectedItems ()) - { - //force item to redraw the frame (for the anti scale calculation) - gi->setSelected(false); - gi->setSelected(true); - } - - emit zoomChanged(1.0); -} - - -void UBBoardController::centerRestore() -{ - centerOn(QPointF(0,0)); -} - - -void UBBoardController::centerOn(QPointF scenePoint) -{ - mControlView->centerOn(scenePoint); - UBApplication::applicationController->adjustDisplayView(); -} - - -void UBBoardController::zoom(const qreal ratio, QPointF scenePoint) -{ - - QPointF viewCenter = mControlView->mapToScene(QRect(0, 0, mControlView->width(), mControlView->height()).center()); - QPointF offset = scenePoint - viewCenter; - QPointF scalledOffset = offset / ratio; - - qreal currentZoom = ratio * mControlView->viewportTransform().m11() / mSystemScaleFactor; - - qreal usedRatio = ratio; - if (currentZoom > UB_MAX_ZOOM) - { - currentZoom = UB_MAX_ZOOM; - usedRatio = currentZoom * mSystemScaleFactor / mControlView->viewportTransform().m11(); - } - - mControlView->scale(usedRatio, usedRatio); - - QPointF newCenter = scenePoint - scalledOffset; - - mControlView->centerOn(newCenter); - - emit zoomChanged(currentZoom); - UBApplication::applicationController->adjustDisplayView(); - - emit controlViewportChanged(); - mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); -} - - -void UBBoardController::handScroll(qreal dx, qreal dy) -{ - mControlView->translate(dx, dy); - - UBApplication::applicationController->adjustDisplayView(); - - emit controlViewportChanged(); -} - - -void UBBoardController::previousScene() -{ - if (mActiveSceneIndex > 0) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(mActiveSceneIndex - 1); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - - -void UBBoardController::nextScene() -{ - if (mActiveSceneIndex < selectedDocument()->pageCount() - 1) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(mActiveSceneIndex + 1); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - - -void UBBoardController::firstScene() -{ - if (mActiveSceneIndex > 0) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(0); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - - -void UBBoardController::lastScene() -{ - if (mActiveSceneIndex < selectedDocument()->pageCount() - 1) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - persistCurrentScene(); - setActiveDocumentScene(selectedDocument()->pageCount() - 1); - QApplication::restoreOverrideCursor(); - } - - updateActionStates(); - emit pageChanged(); -} - -void UBBoardController::groupButtonClicked() -{ - QAction *groupAction = UBApplication::mainWindow->actionGroupItems; - QList selItems = activeScene()->selectedItems(); - if (!selItems.count()) { - qDebug() << "Got grouping request when there is no any selected item on the scene"; - return; - } - - if (groupAction->text() == mActionGroupText) { //The only way to get information from item, considering using smth else - UBGraphicsGroupContainerItem *groupItem = activeScene()->createGroup(selItems); - groupItem->setSelected(true); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - - } - else if (groupAction->text() == mActionUngroupText) { - //Considering one selected item and it's a group - if (selItems.count() > 1) - { - qDebug() << "can't make sense of ungrouping more then one item. Grouping action should be performed for that purpose"; - return; - } - UBGraphicsGroupContainerItem *currentGroup = dynamic_cast(selItems.first()); - if (currentGroup) { - currentGroup->destroy(); - } - } -} - -void UBBoardController::downloadURL(const QUrl& url, QString contentSourceUrl, const QPointF& pPos, const QSize& pSize, bool isBackground, bool internalData) -{ - qDebug() << "something has been dropped on the board! Url is: " << url.toString(); - QString sUrl = url.toString(); - - QGraphicsItem *oldBackgroundObject = NULL; - if (isBackground) - oldBackgroundObject = mActiveScene->backgroundObject(); - - if(sUrl.startsWith("uniboardTool://")) - { - downloadFinished(true, url, QUrl(), "application/vnd.mnemis-uniboard-tool", QByteArray(), pPos, pSize, isBackground); - } - else if (sUrl.startsWith("file://") || sUrl.startsWith("/")) - { - QUrl formedUrl = sUrl.startsWith("file://") ? url : QUrl::fromLocalFile(sUrl); - QString fileName = formedUrl.toLocalFile(); - QString contentType = UBFileSystemUtils::mimeTypeFromFileName(fileName); - - bool shouldLoadFileData = - contentType.startsWith("image") - || contentType.startsWith("application/widget") - || contentType.startsWith("application/vnd.apple-widget"); - - if (shouldLoadFileData) - { - QFile file(fileName); - file.open(QIODevice::ReadOnly); - downloadFinished(true, formedUrl, QUrl(), contentType, file.readAll(), pPos, pSize, isBackground, internalData); - file.close(); - } - else - { - // media items should be copyed in separate thread - - sDownloadFileDesc desc; - desc.modal = false; - desc.srcUrl = sUrl; - desc.originalSrcUrl = contentSourceUrl; - desc.currentSize = 0; - desc.name = QFileInfo(url.toString()).fileName(); - desc.totalSize = 0; // The total size will be retrieved during the download - desc.pos = pPos; - desc.size = pSize; - desc.isBackground = isBackground; - - UBDownloadManager::downloadManager()->addFileToDownload(desc); - } - } - else - { - QString urlString = url.toString(); - int parametersStringPosition = urlString.indexOf("?"); - if(parametersStringPosition != -1) - urlString = urlString.left(parametersStringPosition); - - // When we fall there, it means that we are dropping something from the web to the board - sDownloadFileDesc desc; - desc.modal = true; - desc.srcUrl = urlString; - desc.currentSize = 0; - desc.name = QFileInfo(urlString).fileName(); - desc.totalSize = 0; // The total size will be retrieved during the download - desc.pos = pPos; - desc.size = pSize; - desc.isBackground = isBackground; - - UBDownloadManager::downloadManager()->addFileToDownload(desc); - } - - if (isBackground && oldBackgroundObject != mActiveScene->backgroundObject()) - { - if (mActiveScene->isURStackIsEnabled()) { //should be deleted after scene own undo stack implemented - UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(mActiveScene, oldBackgroundObject, mActiveScene->backgroundObject()); - UBApplication::undoStack->push(uc); - } - } - - -} - - -UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QUrl contentUrl, QString pContentTypeHeader, - QByteArray pData, QPointF pPos, QSize pSize, - bool isBackground, bool internalData) -{ - QString mimeType = pContentTypeHeader; - - // In some cases "image/jpeg;charset=" is retourned by the drag-n-drop. That is - // why we will check if an ; exists and take the first part (the standard allows this kind of mimetype) - if(mimeType.isEmpty()) - mimeType = UBFileSystemUtils::mimeTypeFromFileName(sourceUrl.toString()); - - int position=mimeType.indexOf(";"); - if(position != -1) - mimeType=mimeType.left(position); - - UBMimeType::Enum itemMimeType = UBFileSystemUtils::mimeTypeFromString(mimeType); - - if (!pSuccess) - { - showMessage(tr("Downloading content %1 failed").arg(sourceUrl.toString())); - return NULL; - } - - - mActiveScene->deselectAllItems(); - - if (!sourceUrl.toString().startsWith("file://") && !sourceUrl.toString().startsWith("uniboardTool://")) - showMessage(tr("Download finished")); - - if (UBMimeType::RasterImage == itemMimeType) - { - - qDebug() << "accepting mime type" << mimeType << "as raster image"; - - - QPixmap pix; - if(pData.length() == 0){ - pix.load(sourceUrl.toLocalFile()); - } - else{ - QImage img; - img.loadFromData(pData); - pix = QPixmap::fromImage(img); - } - - UBGraphicsPixmapItem* pixItem = mActiveScene->addPixmap(pix, NULL, pPos, 1.); - pixItem->setSourceUrl(sourceUrl); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(pixItem, true); - } - else - { - mActiveScene->scaleToFitDocumentSize(pixItem, true, UBSettings::objectInControlViewMargin); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - pixItem->setSelected(true); - } - - return pixItem; - } - else if (UBMimeType::VectorImage == itemMimeType) - { - qDebug() << "accepting mime type" << mimeType << "as vecto image"; - - UBGraphicsSvgItem* svgItem = mActiveScene->addSvg(sourceUrl, pPos, pData); - svgItem->setSourceUrl(sourceUrl); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(svgItem); - } - else - { - mActiveScene->scaleToFitDocumentSize(svgItem, true, UBSettings::objectInControlViewMargin); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - svgItem->setSelected(true); - } - - return svgItem; - } - else if (UBMimeType::AppleWidget == itemMimeType) //mime type invented by us :-( - { - qDebug() << "accepting mime type" << mimeType << "as Apple widget"; - - QUrl widgetUrl = sourceUrl; - - if (pData.length() > 0) - { - widgetUrl = expandWidgetToTempDir(pData, "wdgt"); - } - - UBGraphicsWidgetItem* appleWidgetItem = mActiveScene->addAppleWidget(widgetUrl, pPos); - - appleWidgetItem->setSourceUrl(sourceUrl); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(appleWidgetItem); - } - else - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - - return appleWidgetItem; - } - else if (UBMimeType::W3CWidget == itemMimeType) - { - qDebug() << "accepting mime type" << mimeType << "as W3C widget"; - QUrl widgetUrl = sourceUrl; - - if (pData.length() > 0) - { - widgetUrl = expandWidgetToTempDir(pData); - } - - UBGraphicsWidgetItem *w3cWidgetItem = addW3cWidget(widgetUrl, pPos); - - if (isBackground) - { - mActiveScene->setAsBackgroundObject(w3cWidgetItem); - } - else - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - - return w3cWidgetItem; - } - else if (UBMimeType::Video == itemMimeType) - { - qDebug() << "accepting mime type" << mimeType << "as video"; - - UBGraphicsMediaItem *mediaVideoItem = 0; - QUuid uuid = QUuid::createUuid(); - if (pData.length() > 0) - { - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), - sourceUrl.toString(), - UBPersistenceManager::videoDirectory, - uuid, - destFile, - &pData); - if (!b) - { - showMessage(tr("Add file operation failed: file copying error")); - return NULL; - } - - QUrl url = QUrl::fromLocalFile(destFile); - - mediaVideoItem = mActiveScene->addMedia(url, false, pPos); - } - else - { - qDebug() << sourceUrl.toString(); - mediaVideoItem = addVideo(sourceUrl, false, pPos, true); - } - - if(mediaVideoItem){ - if (contentUrl.isEmpty()) - mediaVideoItem->setSourceUrl(sourceUrl); - else - mediaVideoItem->setSourceUrl(contentUrl); - mediaVideoItem->setUuid(uuid); - connect(this, SIGNAL(activeSceneChanged()), mediaVideoItem, SLOT(activeSceneChanged())); - } - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - - return mediaVideoItem; - } - else if (UBMimeType::Audio == itemMimeType) - { - qDebug() << "accepting mime type" << mimeType << "as audio"; - - UBGraphicsMediaItem *audioMediaItem = 0; - - QUuid uuid = QUuid::createUuid(); - if (pData.length() > 0) - { - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), - sourceUrl.toString(), - UBPersistenceManager::audioDirectory, - uuid, - destFile, - &pData); - if (!b) - { - showMessage(tr("Add file operation failed: file copying error")); - return NULL; - } - - QUrl url = QUrl::fromLocalFile(destFile); - - audioMediaItem = mActiveScene->addMedia(url, false, pPos); - } - else - { - audioMediaItem = addAudio(sourceUrl, false, pPos, true); - } - - if(audioMediaItem){ - if (contentUrl.isEmpty()) - audioMediaItem->setSourceUrl(sourceUrl); - else - audioMediaItem->setSourceUrl(contentUrl); - audioMediaItem->setUuid(uuid); - connect(this, SIGNAL(activeSceneChanged()), audioMediaItem, SLOT(activeSceneChanged())); - } - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - - return audioMediaItem; - } - - else if (UBMimeType::Flash == itemMimeType) - { - - qDebug() << "accepting mime type" << mimeType << "as flash"; - - QString sUrl = sourceUrl.toString(); - - if (sUrl.startsWith("file://") || sUrl.startsWith("/")) - { - sUrl = sourceUrl.toLocalFile(); - } - - QTemporaryFile* eduMediaFile = 0; - - if (sUrl.toLower().contains("edumedia-sciences.com")) - { - eduMediaFile = new QTemporaryFile("XXXXXX.swf"); - if (eduMediaFile->open()) - { - eduMediaFile->write(pData); - QFileInfo fi(*eduMediaFile); - sUrl = fi.absoluteFilePath(); - } - } - - QSize size; - - if (pSize.height() > 0 && pSize.width() > 0) - size = pSize; - else - size = mActiveScene->nominalSize() * .8; - - Q_UNUSED(internalData) - - QString widgetUrl = UBGraphicsW3CWidgetItem::createNPAPIWrapper(sUrl, mimeType, size); - emit npapiWidgetCreated(widgetUrl); - - if (widgetUrl.length() > 0) - { - UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); - widgetItem->setUuid(QUuid::createUuid()); - widgetItem->setSourceUrl(QUrl::fromLocalFile(widgetUrl)); - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - - return widgetItem; - } - - if (eduMediaFile) - delete eduMediaFile; - - } - else if (UBMimeType::PDF == itemMimeType) - { - qDebug() << "accepting mime type" << mimeType << "as PDF"; - qDebug() << "pdf data length: " << pData.size(); - qDebug() << "sourceurl : " + sourceUrl.toString(); - int result = 0; - if(!sourceUrl.isEmpty()){ - QStringList fileNames; - fileNames << sourceUrl.toLocalFile(); - result = UBDocumentManager::documentManager()->addFilesToDocument(selectedDocument(), fileNames); - } - else if(pData.size()){ - QTemporaryFile pdfFile("XXXXXX.pdf"); - if (pdfFile.open()) - { - pdfFile.write(pData); - QStringList fileNames; - fileNames << pdfFile.fileName(); - result = UBDocumentManager::documentManager()->addFilesToDocument(selectedDocument(), fileNames); - pdfFile.close(); - } - } - - if (result){ - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } - } - else if (UBMimeType::UniboardTool == itemMimeType) - { - qDebug() << "accepting mime type" << mimeType << "as Uniboard Tool"; - - if (sourceUrl.toString() == UBToolsManager::manager()->compass.id) - { - mActiveScene->addCompass(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->ruler.id) - { - mActiveScene->addRuler(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->protractor.id) - { - mActiveScene->addProtractor(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->triangle.id) - { - mActiveScene->addTriangle(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->cache.id) - { - mActiveScene->addCache(); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->magnifier.id) - { - UBMagnifierParams params; - params.x = controlContainer()->geometry().width() / 2; - params.y = controlContainer()->geometry().height() / 2; - params.zoom = 2; - params.sizePercentFromScene = 20; - mActiveScene->addMagnifier(params); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else if (sourceUrl.toString() == UBToolsManager::manager()->mask.id) - { - mActiveScene->addMask(pPos); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } - else - { - showMessage(tr("Unknown tool type %1").arg(sourceUrl.toString())); - } - } - else if (sourceUrl.toString().contains("edumedia-sciences.com")) - { - qDebug() << "accepting url " << sourceUrl.toString() << "as eduMedia content"; - - QTemporaryFile eduMediaZipFile("XXXXXX.edumedia"); - if (eduMediaZipFile.open()) - { - eduMediaZipFile.write(pData); - eduMediaZipFile.close(); - - QString tempDir = UBFileSystemUtils::createTempDir("uniboard-edumedia"); - - UBFileSystemUtils::expandZipToDir(eduMediaZipFile, tempDir); - - QDir appDir(tempDir); - - foreach(QString subDirName, appDir.entryList(QDir::AllDirs)) - { - QDir subDir(tempDir + "/" + subDirName + "/contents"); - - foreach(QString fileName, subDir.entryList(QDir::Files)) - { - if (fileName.toLower().endsWith(".swf")) - { - QString swfFile = tempDir + "/" + subDirName + "/contents/" + fileName; - - QSize size; - - if (pSize.height() > 0 && pSize.width() > 0) - size = pSize; - else - size = mActiveScene->nominalSize() * .8; - - QString widgetUrl = UBGraphicsW3CWidgetItem::createNPAPIWrapper(swfFile, "application/x-shockwave-flash", size); - - if (widgetUrl.length() > 0) - { - UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); - - widgetItem->setSourceUrl(sourceUrl); - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - - return widgetItem; - } - } - } - } - } - } - else - { - showMessage(tr("Unknown content type %1").arg(pContentTypeHeader)); - qWarning() << "ignoring mime type" << pContentTypeHeader ; - } - - return NULL; -} - -void UBBoardController::setActiveDocumentScene(int pSceneIndex) -{ - setActiveDocumentScene(selectedDocument(), pSceneIndex); -} - -void UBBoardController::setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, const int pSceneIndex, bool forceReload) -{ - saveViewState(); - - bool documentChange = selectedDocument() != pDocumentProxy; - - int index = pSceneIndex; - int sceneCount = pDocumentProxy->pageCount(); - if (index >= sceneCount && sceneCount > 0) - index = sceneCount - 1; - - UBGraphicsScene* targetScene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, index); - - bool sceneChange = targetScene != mActiveScene; - - if (targetScene) - { - freezeW3CWidgets(true); - - persistCurrentScene(); - - ClearUndoStack(); - - mActiveScene = targetScene; - mActiveSceneIndex = index; - setDocument(pDocumentProxy, forceReload); - - updateSystemScaleFactor(); - - mControlView->setScene(mActiveScene); - mDisplayView->setScene(mActiveScene); - mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); - pDocumentProxy->setDefaultDocumentSize(mActiveScene->nominalSize()); - updatePageSizeState(); - - adjustDisplayViews(); - - UBSettings::settings()->setDarkBackground(mActiveScene->isDarkBackground()); - UBSettings::settings()->setCrossedBackground(mActiveScene->isCrossedBackground()); - - freezeW3CWidgets(false); - } - - selectionChanged(); - - updateBackgroundActionsState(mActiveScene->isDarkBackground(), mActiveScene->isCrossedBackground()); - updateBackgroundState(); - - if(documentChange) - { - UBGraphicsTextItem::lastUsedTextColor = QColor(); - } - - - if (sceneChange) - { - emit activeSceneChanged(); - emit pageChanged(); - } -} - - -void UBBoardController::moveSceneToIndex(int source, int target) -{ - if (selectedDocument()) - { - - persistCurrentScene(); - - UBDocumentContainer::movePageToIndex(source, target); - - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(selectedDocument()); - mMovingSceneIndex = source; - setActiveDocumentScene(target); - mMovingSceneIndex = -1; - - } -} - -void UBBoardController::ClearUndoStack() -{ -// The code has been removed because it leads to a strange error and because the final goal has never been -// reached on tests and sound a little bit strange. -// Strange error: item->scene() crashes the application because item doesn't implement scene() method. I'm -// not able to give all the steps to reproduce this error sistematically but is quite frequent (~ twice per utilisation hours) -// strange goal: if item is on the undocommand, the item->scene() is null and the item is not on the deleted scene item list then -// then it's deleted. - - // QSet uniqueItems; -// // go through all stack command -// for(int i = 0; i < UBApplication::undoStack->count(); i++) -// { - -// UBAbstractUndoCommand *abstractCmd = (UBAbstractUndoCommand*)UBApplication::undoStack->command(i); -// if(abstractCmd->getType() != UBAbstractUndoCommand::undotype_GRAPHICITEM) -// continue; - -// UBGraphicsItemUndoCommand *cmd = (UBGraphicsItemUndoCommand*)UBApplication::undoStack->command(i); - -// // go through all added and removed objects, for create list of unique objects -// // grouped items will be deleted by groups, so we don't need do delete that items. -// QSetIterator itAdded(cmd->GetAddedList()); -// while (itAdded.hasNext()) -// { -// QGraphicsItem* item = itAdded.next(); -// if( !uniqueItems.contains(item) && !(item->parentItem() && UBGraphicsGroupContainerItem::Type == item->parentItem()->type())) -// uniqueItems.insert(item); -// } - -// QSetIterator itRemoved(cmd->GetRemovedList()); -// while (itRemoved.hasNext()) -// { -// QGraphicsItem* item = itRemoved.next(); -// if( !uniqueItems.contains(item) && !(item->parentItem() && UBGraphicsGroupContainerItem::Type == item->parentItem()->type())) -// uniqueItems.insert(item); -// } -// } - -// // go through all unique items, and check, ot on scene, or not. -// // if not on scene, than item can be deleted - -// QSetIterator itUniq(uniqueItems); -// while (itUniq.hasNext()) -// { -// QGraphicsItem* item = itUniq.next(); -// UBGraphicsScene *scene = NULL; -// if (item->scene()) { -// scene = dynamic_cast(item->scene()); -// } -// if(!scene) -// { -// if (!mActiveScene->deleteItem(item)) -// delete item; -// } -// } - - // clear stack, and command list - UBApplication::undoStack->clear(); - -} - -void UBBoardController::adjustDisplayViews() -{ - if (UBApplication::applicationController) - { - UBApplication::applicationController->adjustDisplayView(); - UBApplication::applicationController->adjustPreviousViews(mActiveSceneIndex, selectedDocument()); - } -} - - -void UBBoardController::changeBackground(bool isDark, bool isCrossed) -{ - bool currentIsDark = mActiveScene->isDarkBackground(); - bool currentIsCrossed = mActiveScene->isCrossedBackground(); - - if ((isDark != currentIsDark) || (currentIsCrossed != isCrossed)) - { - UBSettings::settings()->setDarkBackground(isDark); - UBSettings::settings()->setCrossedBackground(isCrossed); - - mActiveScene->setBackground(isDark, isCrossed); - - updateBackgroundState(); - - emit backgroundChanged(); - } -} - -void UBBoardController::boardViewResized(QResizeEvent* event) -{ - Q_UNUSED(event); - - int innerMargin = UBSettings::boardMargin; - int userHeight = mControlContainer->height() - (2 * innerMargin); - - mMessageWindow->move(innerMargin, innerMargin + userHeight - mMessageWindow->height()); - mMessageWindow->adjustSizeAndPosition(); - - UBApplication::applicationController->initViewState( - mControlView->horizontalScrollBar()->value(), - mControlView->verticalScrollBar()->value()); - - updateSystemScaleFactor(); - - mControlView->centerOn(0,0); - - if (mDisplayView) - mDisplayView->centerOn(0,0); - - mPaletteManager->containerResized(); - - UBApplication::boardController->controlView()->scene()->moveMagnifier(); - -} - - -void UBBoardController::documentWillBeDeleted(UBDocumentProxy* pProxy) -{ - if (selectedDocument() == pProxy) - { - if (!mIsClosing) - setActiveDocumentScene(UBPersistenceManager::persistenceManager()->createDocument()); - } -} - - -void UBBoardController::showMessage(const QString& message, bool showSpinningWheel) -{ - mMessageWindow->showMessage(message, showSpinningWheel); -} - - -void UBBoardController::hideMessage() -{ - mMessageWindow->hideMessage(); -} - - -void UBBoardController::setDisabled(bool disable) -{ - mMainWindow->boardToolBar->setDisabled(disable); - mControlView->setDisabled(disable); -} - - -void UBBoardController::selectionChanged() -{ - updateActionStates(); - emit pageSelectionChanged(activeSceneIndex()); -} - - -void UBBoardController::undoRedoStateChange(bool canUndo) -{ - Q_UNUSED(canUndo); - - mMainWindow->actionUndo->setEnabled(UBApplication::undoStack->canUndo()); - mMainWindow->actionRedo->setEnabled(UBApplication::undoStack->canRedo()); - - updateActionStates(); -} - - -void UBBoardController::updateActionStates() -{ - mMainWindow->actionBack->setEnabled(selectedDocument() && (mActiveSceneIndex > 0)); - mMainWindow->actionForward->setEnabled(selectedDocument() && (mActiveSceneIndex < selectedDocument()->pageCount() - 1)); - mMainWindow->actionErase->setEnabled(mActiveScene && !mActiveScene->isEmpty()); -} - - -UBGraphicsScene* UBBoardController::activeScene() const -{ - return mActiveScene; -} - - -int UBBoardController::activeSceneIndex() const -{ - return mActiveSceneIndex; -} - - -void UBBoardController::documentSceneChanged(UBDocumentProxy* pDocumentProxy, int pIndex) -{ - Q_UNUSED(pIndex); - - if(selectedDocument() == pDocumentProxy) - { - setActiveDocumentScene(mActiveSceneIndex); - } -} - -void UBBoardController::closing() -{ - mIsClosing = true; - ClearUndoStack(); - lastWindowClosed(); -} - -void UBBoardController::lastWindowClosed() -{ - if (!mCleanupDone) - { - bool teacherGuideModified = false; - if(UBApplication::boardController->paletteManager()->teacherGuideDockWidget()) - teacherGuideModified = UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified(); - if (selectedDocument()->pageCount() == 1 && (!mActiveScene || mActiveScene->isEmpty()) && !teacherGuideModified) - { - UBPersistenceManager::persistenceManager()->deleteDocument(selectedDocument()); - } - else - { - persistCurrentScene(); - } - - UBPersistenceManager::persistenceManager()->purgeEmptyDocuments(); - - mCleanupDone = true; - } -} - - - -void UBBoardController::setColorIndex(int pColorIndex) -{ - UBDrawingController::drawingController()->setColorIndex(pColorIndex); - - if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker && - UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Line && - UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Text && - UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Selector) - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); - } - - if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Pen || - UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line || - UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Text || - UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) - { - mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(pColorIndex); - mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(pColorIndex); - - if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) - { - // If we are in mode board, then do that - if(UBApplication::applicationController->displayMode() == UBApplicationController::Board) - { - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); - mMainWindow->actionPen->setChecked(true); - } - } - - emit penColorChanged(); - } - else if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Marker) - { - mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(pColorIndex); - mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(pColorIndex); - } -} - -void UBBoardController::colorPaletteChanged() -{ - mPenColorOnDarkBackground = UBSettings::settings()->penColor(true); - mPenColorOnLightBackground = UBSettings::settings()->penColor(false); - mMarkerColorOnDarkBackground = UBSettings::settings()->markerColor(true); - mMarkerColorOnLightBackground = UBSettings::settings()->markerColor(false); -} - - -qreal UBBoardController::currentZoom() -{ - if (mControlView) - return mControlView->viewportTransform().m11() / mSystemScaleFactor; - else - return 1.0; -} - -void UBBoardController::removeTool(UBToolWidget* toolWidget) -{ - toolWidget->hide(); - - delete toolWidget; -} - -void UBBoardController::hide() -{ - UBApplication::mainWindow->actionLibrary->setChecked(false); -} - -void UBBoardController::show() -{ - UBApplication::mainWindow->actionLibrary->setChecked(false); -} - -void UBBoardController::persistCurrentScene() -{ - if(UBPersistenceManager::persistenceManager() - && selectedDocument() && mActiveScene && mActiveSceneIndex != mDeletingSceneIndex - && (mActiveSceneIndex >= 0) && mActiveSceneIndex != mMovingSceneIndex - && (mActiveScene->isModified() || (UBApplication::boardController->paletteManager()->teacherGuideDockWidget() && UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified()))) - { - UBPersistenceManager::persistenceManager()->persistDocumentScene(selectedDocument(), mActiveScene, mActiveSceneIndex); - updatePage(mActiveSceneIndex); - } -} - -void UBBoardController::updateSystemScaleFactor() -{ - qreal newScaleFactor = 1.0; - - if (mActiveScene) - { - QSize pageNominalSize = mActiveScene->nominalSize(); - //we're going to keep scale factor untouched if the size is custom - QMap sizesMap = UBSettings::settings()->documentSizes; - // if(pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio16_9) || pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio4_3)) - { - QSize controlSize = controlViewport(); - - qreal hFactor = ((qreal)controlSize.width()) / ((qreal)pageNominalSize.width()); - qreal vFactor = ((qreal)controlSize.height()) / ((qreal)pageNominalSize.height()); - - newScaleFactor = qMin(hFactor, vFactor); - } - } - - if (mSystemScaleFactor != newScaleFactor) - { - mSystemScaleFactor = newScaleFactor; - emit systemScaleFactorChanged(newScaleFactor); - } - - UBGraphicsScene::SceneViewState viewState = mActiveScene->viewState(); - - QTransform scalingTransform; - - qreal scaleFactor = viewState.zoomFactor * mSystemScaleFactor; - scalingTransform.scale(scaleFactor, scaleFactor); - - mControlView->setTransform(scalingTransform); - mControlView->horizontalScrollBar()->setValue(viewState.horizontalPosition); - mControlView->verticalScrollBar()->setValue(viewState.verticalPostition); - mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11());} - - -void UBBoardController::setWidePageSize(bool checked) -{ - Q_UNUSED(checked); - QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9); - - if (mActiveScene->nominalSize() != newSize) - { - UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); - UBApplication::undoStack->push(uc); - - setPageSize(newSize); - } -} - - -void UBBoardController::setRegularPageSize(bool checked) -{ - Q_UNUSED(checked); - QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3); - - if (mActiveScene->nominalSize() != newSize) - { - UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); - UBApplication::undoStack->push(uc); - - setPageSize(newSize); - } -} - - -void UBBoardController::setPageSize(QSize newSize) -{ - if (mActiveScene->nominalSize() != newSize) - { - mActiveScene->setNominalSize(newSize); - - saveViewState(); - - updateSystemScaleFactor(); - updatePageSizeState(); - adjustDisplayViews(); - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - UBSettings::settings()->pageSize->set(newSize); - } -} - -void UBBoardController::notifyCache(bool visible) -{ - if(visible) - { - emit cacheEnabled(); - } - else - { - emit cacheDisabled(); - } - mCacheWidgetIsEnabled = visible; -} - -void UBBoardController::updatePageSizeState() -{ - if (mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9)) - { - mMainWindow->actionWidePageSize->setChecked(true); - } - else if(mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3)) - { - mMainWindow->actionRegularPageSize->setChecked(true); - } - else - { - mMainWindow->actionCustomPageSize->setChecked(true); - } -} - - -void UBBoardController::saveViewState() -{ - if (mActiveScene) - { - mActiveScene->setViewState(UBGraphicsScene::SceneViewState(currentZoom(), - mControlView->horizontalScrollBar()->value(), - mControlView->verticalScrollBar()->value())); - } -} - - -void UBBoardController::updateBackgroundState() -{ - //adjust background style - QString newBackgroundStyle; - - if (mActiveScene && mActiveScene->isDarkBackground()) - { - newBackgroundStyle ="QWidget {background-color: #0E0E0E}"; - } - else - { - newBackgroundStyle ="QWidget {background-color: #F1F1F1}"; - } -} - -void UBBoardController::stylusToolChanged(int tool) -{ - if (UBPlatformUtils::hasVirtualKeyboard() && mPaletteManager->mKeyboardPalette) - { - UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; - if(eTool != UBStylusTool::Selector && eTool != UBStylusTool::Text) - { - if(mPaletteManager->mKeyboardPalette->m_isVisible) - UBApplication::mainWindow->actionVirtualKeyboard->activate(QAction::Trigger); - } - } - - updateBackgroundState(); -} - - -QUrl UBBoardController::expandWidgetToTempDir(const QByteArray& pZipedData, const QString& ext) -{ - QUrl widgetUrl; - QTemporaryFile tmp; - - if (tmp.open()) - { - tmp.write(pZipedData); - tmp.flush(); - tmp.close(); - - QString tmpDir = UBFileSystemUtils::createTempDir() + "." + ext; - - if (UBFileSystemUtils::expandZipToDir(tmp, tmpDir)) - { - widgetUrl = QUrl::fromLocalFile(tmpDir); - } - } - - return widgetUrl; -} - - -void UBBoardController::grabScene(const QRectF& pSceneRect) -{ - if (mActiveScene) - { - QImage image(pSceneRect.width(), pSceneRect.height(), QImage::Format_ARGB32); - image.fill(Qt::transparent); - - QRectF targetRect(0, 0, pSceneRect.width(), pSceneRect.height()); - QPainter painter(&image); - painter.setRenderHint(QPainter::SmoothPixmapTransform); - painter.setRenderHint(QPainter::Antialiasing); - - mActiveScene->setRenderingContext(UBGraphicsScene::NonScreen); - mActiveScene->setRenderingQuality(UBItem::RenderingQualityHigh); - - mActiveScene->render(&painter, targetRect, pSceneRect); - - mActiveScene->setRenderingContext(UBGraphicsScene::Screen); - mActiveScene->setRenderingQuality(UBItem::RenderingQualityNormal); - - mPaletteManager->addItem(QPixmap::fromImage(image)); - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } -} - -UBGraphicsMediaItem* UBBoardController::addVideo(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos, bool bUseSource) -{ - QUuid uuid = QUuid::createUuid(); - QUrl concreteUrl = pSourceUrl; - - // media file is not in document folder yet - if (!bUseSource) - { - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), - pSourceUrl.toLocalFile(), - UBPersistenceManager::videoDirectory, - uuid, - destFile); - if (!b) - { - showMessage(tr("Add file operation failed: file copying error")); - return NULL; - } - concreteUrl = QUrl::fromLocalFile(destFile); - }// else we just use source Url. - - - UBGraphicsMediaItem* vi = mActiveScene->addMedia(concreteUrl, startPlay, pos); - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - if (vi) { - vi->setUuid(uuid); - vi->setSourceUrl(pSourceUrl); - } - - return vi; - -} - -UBGraphicsMediaItem* UBBoardController::addAudio(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos, bool bUseSource) -{ - QUuid uuid = QUuid::createUuid(); - QUrl concreteUrl = pSourceUrl; - - // media file is not in document folder yet - if (!bUseSource) - { - QString destFile; - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), - pSourceUrl.toLocalFile(), - UBPersistenceManager::audioDirectory, - uuid, - destFile); - if (!b) - { - showMessage(tr("Add file operation failed: file copying error")); - return NULL; - } - concreteUrl = QUrl::fromLocalFile(destFile); - }// else we just use source Url. - - UBGraphicsMediaItem* ai = mActiveScene->addMedia(concreteUrl, startPlay, pos); - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - - if (ai){ - ai->setUuid(uuid); - ai->setSourceUrl(pSourceUrl); - } - - return ai; - -} - -UBGraphicsWidgetItem *UBBoardController::addW3cWidget(const QUrl &pUrl, const QPointF &pos) -{ - UBGraphicsWidgetItem* w3cWidgetItem = 0; - - QUuid uuid = QUuid::createUuid(); - - QString destPath; - if (!UBPersistenceManager::persistenceManager()->addGraphicsWidgteToDocument(selectedDocument(), pUrl.toLocalFile(), uuid, destPath)) - return NULL; - QUrl newUrl = QUrl::fromLocalFile(destPath); - - w3cWidgetItem = mActiveScene->addW3CWidget(newUrl, pos); - - if (w3cWidgetItem) { - w3cWidgetItem->setUuid(uuid); - w3cWidgetItem->setOwnFolder(newUrl); - w3cWidgetItem->setSourceUrl(pUrl); - - QString struuid = UBStringUtils::toCanonicalUuid(uuid); - QString snapshotPath = selectedDocument()->persistencePath() + "/" + UBPersistenceManager::widgetDirectory + "/" + struuid + ".png"; - w3cWidgetItem->setSnapshotPath(QUrl::fromLocalFile(snapshotPath)); - UBGraphicsWidgetItem *tmpItem = dynamic_cast(w3cWidgetItem); - if (tmpItem && tmpItem->scene()) - tmpItem->takeSnapshot().save(snapshotPath, "PNG"); - - } - - return w3cWidgetItem; -} - -void UBBoardController::cut() -{ - //---------------------------------------------------------// - - QList selectedItems; - foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) - selectedItems << gi; - - //---------------------------------------------------------// - - QList selected; - foreach(QGraphicsItem* gi, selectedItems) - { - gi->setSelected(false); - - UBItem* ubItem = dynamic_cast(gi); - UBGraphicsItem *ubGi = dynamic_cast(gi); - - if (ubItem && ubGi && !mActiveScene->tools().contains(gi)) - { - selected << ubItem->deepCopy(); - ubGi->remove(); - } - } - - //---------------------------------------------------------// - - if (selected.size() > 0) - { - QClipboard *clipboard = QApplication::clipboard(); - - UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); - - mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); - clipboard->setMimeData(mimeGi); - - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - } - - //---------------------------------------------------------// -} - - -void UBBoardController::copy() -{ - QList selected; - - foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) - { - UBItem* ubItem = dynamic_cast(gi); - - if (ubItem && !mActiveScene->tools().contains(gi)) - { - UBItem *itemCopy = ubItem->deepCopy(); - if (itemCopy) - selected << itemCopy; - } - } - - if (selected.size() > 0) - { - QClipboard *clipboard = QApplication::clipboard(); - - UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); - - mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); - clipboard->setMimeData(mimeGi); - - } -} - - -void UBBoardController::paste() -{ - QClipboard *clipboard = QApplication::clipboard(); - QPointF pos(0, 0); - processMimeData(clipboard->mimeData(), pos); - - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); -} - - -void UBBoardController::processMimeData(const QMimeData* pMimeData, const QPointF& pPos) -{ - if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - const UBMimeData* mimeData = qobject_cast (pMimeData); - - if (mimeData) - { - int previousActiveSceneIndex = activeSceneIndex(); - int previousPageCount = selectedDocument()->pageCount(); - - foreach (UBMimeDataItem sourceItem, mimeData->items()) - addScene(sourceItem.documentProxy(), sourceItem.sceneIndex(), true); - - if (selectedDocument()->pageCount() < previousPageCount + mimeData->items().count()) - setActiveDocumentScene(previousActiveSceneIndex); - else - setActiveDocumentScene(previousActiveSceneIndex + 1); - - return; - } - } - - if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPageItem)) - { - const UBMimeDataGraphicsItem* mimeData = qobject_cast (pMimeData); - - if (mimeData) - { - foreach(UBItem* item, mimeData->items()) - { - QGraphicsItem* pItem = dynamic_cast(item); - if(NULL != pItem){ - duplicateItem(item); - } - } - - return; - } - } - - if(pMimeData->hasHtml()) - { - QString qsHtml = pMimeData->html(); - QString url = UBApplication::urlFromHtml(qsHtml); - - if("" != url) - { - downloadURL(url, QString(), pPos); - return; - } - } - - if (pMimeData->hasUrls()) - { - QList urls = pMimeData->urls(); - - int index = 0; - - const UBFeaturesMimeData *internalMimeData = qobject_cast(pMimeData); - bool internalData = false; - if (internalMimeData) { - internalData = true; - } - - foreach(const QUrl url, urls){ - QPointF pos(pPos + QPointF(index * 15, index * 15)); - - downloadURL(url, QString(), pos, QSize(), false, internalData); - index++; - } - - return; - } - - if (pMimeData->hasImage()) - { - QImage img = qvariant_cast (pMimeData->imageData()); - QPixmap pix = QPixmap::fromImage(img); - - // validate that the image is really an image, webkit does not fill properly the image mime data - if (pix.width() != 0 && pix.height() != 0) - { - mActiveScene->addPixmap(pix, NULL, pPos, 1.); - return; - } - } - - if (pMimeData->hasText()) - { - if("" != pMimeData->text()){ - // Sometimes, it is possible to have an URL as text. we check here if it is the case - QString qsTmp = pMimeData->text().remove(QRegExp("[\\0]")); - if(qsTmp.startsWith("http")){ - downloadURL(QUrl(qsTmp), QString(), pPos); - } - else{ - mActiveScene->addTextHtml(pMimeData->html(), pPos); - } - } - else{ -#ifdef Q_WS_MACX - // With Safari, in 95% of the drops, the mime datas are hidden in Apple Web Archive pasteboard type. - // This is due to the way Safari is working so we have to dig into the pasteboard in order to retrieve - // the data. - QString qsUrl = UBPlatformUtils::urlFromClipboard(); - if("" != qsUrl){ - // We finally got the url of the dropped ressource! Let's import it! - downloadURL(qsUrl, qsUrl, pPos); - return; - } -#endif - } - } -} - - -void UBBoardController::togglePodcast(bool checked) -{ - if (UBPodcastController::instance()) - UBPodcastController::instance()->toggleRecordingPalette(checked); -} - -void UBBoardController::moveGraphicsWidgetToControlView(UBGraphicsWidgetItem* graphicsWidget) -{ - mActiveScene->setURStackEnable(false); - UBGraphicsItem *toolW3C = duplicateItem(dynamic_cast(graphicsWidget)); - UBGraphicsWidgetItem *copyedGraphicsWidget = NULL; - - if (UBGraphicsWidgetItem::Type == toolW3C->type()) - copyedGraphicsWidget = static_cast(toolW3C); - - UBToolWidget *toolWidget = new UBToolWidget(copyedGraphicsWidget, mControlView); - - graphicsWidget->remove(false); - mActiveScene->addItemToDeletion(graphicsWidget); - - mActiveScene->setURStackEnable(true); - - QPoint controlViewPos = mControlView->mapFromScene(graphicsWidget->sceneBoundingRect().center()); - toolWidget->centerOn(mControlView->mapTo(mControlContainer, controlViewPos)); - toolWidget->show(); -} - - -void UBBoardController::moveToolWidgetToScene(UBToolWidget* toolWidget) -{ - UBGraphicsWidgetItem *widgetToScene = toolWidget->toolWidget(); - - widgetToScene->resetTransform(); - - QPoint mainWindowCenter = toolWidget->mapTo(mMainWindow, QPoint(toolWidget->width(), toolWidget->height()) / 2); - QPoint controlViewCenter = mControlView->mapFrom(mMainWindow, mainWindowCenter); - QPointF scenePos = mControlView->mapToScene(controlViewCenter); - - mActiveScene->addGraphicsWidget(widgetToScene, scenePos); - - toolWidget->remove(); -} - - -void UBBoardController::updateBackgroundActionsState(bool isDark, bool isCrossed) -{ - if (isDark && !isCrossed) - mMainWindow->actionPlainDarkBackground->setChecked(true); - else if (isDark && isCrossed) - mMainWindow->actionCrossedDarkBackground->setChecked(true); - else if (!isDark && isCrossed) - mMainWindow->actionCrossedLightBackground->setChecked(true); - else - mMainWindow->actionPlainLightBackground->setChecked(true); -} - - -void UBBoardController::addItem() -{ - QString defaultPath = UBSettings::settings()->lastImportToLibraryPath->get().toString(); - - QString extensions; - foreach(QString ext, UBSettings::imageFileExtensions) - { - extensions += " *."; - extensions += ext; - } - - QString filename = QFileDialog::getOpenFileName(mControlContainer, tr("Add Item"), - defaultPath, - tr("All Supported (%1)").arg(extensions), NULL, QFileDialog::DontUseNativeDialog); - - if (filename.length() > 0) - { - mPaletteManager->addItem(QUrl::fromLocalFile(filename)); - QFileInfo source(filename); - UBSettings::settings()->lastImportToLibraryPath->set(QVariant(source.absolutePath())); - } -} - -void UBBoardController::importPage() -{ - int pageCount = selectedDocument()->pageCount(); - if (UBApplication::documentController->addFileToDocument(selectedDocument())) - { - setActiveDocumentScene(selectedDocument(), pageCount, true); - } -} - -void UBBoardController::notifyPageChanged() -{ - emit pageChanged(); -} - -void UBBoardController::onDownloadModalFinished() -{ - -} - -void UBBoardController::displayMetaData(QMap metadatas) -{ - emit displayMetadata(metadatas); -} - -void UBBoardController::freezeW3CWidgets(bool freeze) -{ - if (mActiveSceneIndex >= 0) - { - QList list = UBApplication::boardController->activeScene()->getFastAccessItems(); - foreach(QGraphicsItem *item, list) - { - freezeW3CWidget(item, freeze); - } - } -} - -void UBBoardController::freezeW3CWidget(QGraphicsItem *item, bool freeze) -{ - if(item->type() == UBGraphicsW3CWidgetItem::Type) - { - UBGraphicsW3CWidgetItem* item_casted = dynamic_cast(item); - if (0 == item_casted) - return; - - if (freeze) { - item_casted->load(QUrl(UBGraphicsW3CWidgetItem::freezedWidgetFilePath())); - } else - item_casted->loadMainHtml(); - } -} + + +#include "UBBoardController.h" + +#include +#include + +#include "frameworks/UBFileSystemUtils.h" +#include "frameworks/UBPlatformUtils.h" + +#include "core/UBApplication.h" +#include "core/UBSettings.h" +#include "core/UBSetting.h" +#include "core/UBPersistenceManager.h" +#include "core/UBApplicationController.h" +#include "core/UBDocumentManager.h" +#include "core/UBMimeData.h" +#include "core/UBDownloadManager.h" + +#include "network/UBHttpGet.h" + +#include "gui/UBMessageWindow.h" +#include "gui/UBResources.h" +#include "gui/UBToolbarButtonGroup.h" +#include "gui/UBMainWindow.h" +#include "gui/UBToolWidget.h" +#include "gui/UBKeyboardPalette.h" +#include "gui/UBMagnifer.h" +#include "gui/UBDockPaletteWidget.h" +#include "gui/UBDockTeacherGuideWidget.h" +#include "gui/UBTeacherGuideWidget.h" + +#include "domain/UBGraphicsPixmapItem.h" +#include "domain/UBGraphicsItemUndoCommand.h" +#include "domain/UBGraphicsProxyWidget.h" +#include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsWidgetItem.h" +#include "domain/UBGraphicsMediaItem.h" +#include "domain/UBGraphicsPDFItem.h" +#include "domain/UBGraphicsTextItem.h" +#include "domain/UBPageSizeUndoCommand.h" +#include "domain/UBGraphicsGroupContainerItem.h" +#include "domain/UBItem.h" +#include "board/UBFeaturesController.h" +#include "domain/UBGraphicsStrokesGroup.h" + +#include "gui/UBFeaturesWidget.h" + +#include "tools/UBToolsManager.h" + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentController.h" + +#include "board/UBDrawingController.h" +#include "board/UBBoardView.h" + +#include "podcast/UBPodcastController.h" + +#include "adaptors/UBMetadataDcSubsetAdaptor.h" +#include "adaptors/UBSvgSubsetAdaptor.h" + +#include "UBBoardPaletteManager.h" + +#include "core/UBSettings.h" + +#include "core/memcheck.h" + +UBBoardController::UBBoardController(UBMainWindow* mainWindow) + : UBDocumentContainer(mainWindow->centralWidget()) + , mMainWindow(mainWindow) + , mActiveScene(0) + , mActiveSceneIndex(-1) + , mPaletteManager(0) + , mSoftwareUpdateDialog(0) + , mMessageWindow(0) + , mControlView(0) + , mDisplayView(0) + , mControlContainer(0) + , mControlLayout(0) + , mZoomFactor(1.0) + , mIsClosing(false) + , mSystemScaleFactor(1.0) + , mCleanupDone(false) + , mCacheWidgetIsEnabled(false) + , mDeletingSceneIndex(-1) + , mMovingSceneIndex(-1) + , mActionGroupText(tr("Group")) + , mActionUngroupText(tr("Ungroup")) +{ + mZoomFactor = UBSettings::settings()->boardZoomFactor->get().toDouble(); + + int penColorIndex = UBSettings::settings()->penColorIndex(); + int markerColorIndex = UBSettings::settings()->markerColorIndex(); + + mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(penColorIndex); + mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(penColorIndex); + mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(markerColorIndex); + mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(markerColorIndex); + + QDesktopWidget* desktop = UBApplication::desktop(); + int dpiCommon = (desktop->physicalDpiX() + desktop->physicalDpiY()) / 2; + int sPixelsPerMillimeter = qRound(dpiCommon / UBGeometryUtils::inchSize); + UBSettings::settings()->crossSize = 10*sPixelsPerMillimeter; +} + + +void UBBoardController::init() +{ + setupViews(); + setupToolbar(); + + connect(UBApplication::undoStack, SIGNAL(canUndoChanged(bool)) + , this, SLOT(undoRedoStateChange(bool))); + + connect(UBApplication::undoStack, SIGNAL(canRedoChanged (bool)) + , this, SLOT(undoRedoStateChange(bool))); + + connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) + , this, SLOT(setToolCursor(int))); + + connect(UBDrawingController::drawingController(), SIGNAL(stylusToolChanged(int)) + , this, SLOT(stylusToolChanged(int))); + + connect(UBApplication::app(), SIGNAL(lastWindowClosed()) + , this, SLOT(lastWindowClosed())); + + connect(UBDownloadManager::downloadManager(), SIGNAL(downloadModalFinished()), this, SLOT(onDownloadModalFinished())); + connect(UBDownloadManager::downloadManager(), SIGNAL(addDownloadedFileToBoard(bool,QUrl,QUrl,QString,QByteArray,QPointF,QSize,bool)), this, SLOT(downloadFinished(bool,QUrl,QUrl,QString,QByteArray,QPointF,QSize,bool))); + + UBDocumentProxy* doc = UBPersistenceManager::persistenceManager()->createDocument(); + + setActiveDocumentScene(doc); + + connect(UBApplication::mainWindow->actionGroupItems, SIGNAL(triggered()), this, SLOT(groupButtonClicked())); + + undoRedoStateChange(true); +} + + +UBBoardController::~UBBoardController() +{ + delete mDisplayView; +} + + +int UBBoardController::currentPage() +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return mActiveSceneIndex; + return mActiveSceneIndex + 1; +} + +void UBBoardController::setupViews() +{ + mControlContainer = new QWidget(mMainWindow->centralWidget()); + + mControlLayout = new QHBoxLayout(mControlContainer); + mControlLayout->setContentsMargins(0, 0, 0, 0); + + mControlView = new UBBoardView(this, mControlContainer, true, false); + mControlView->setInteractive(true); + mControlView->setMouseTracking(true); + + mControlView->grabGesture(Qt::SwipeGesture); + + mControlView->setTransformationAnchor(QGraphicsView::NoAnchor); + + mControlLayout->addWidget(mControlView); + mControlContainer->setObjectName("ubBoardControlContainer"); + mMainWindow->addBoardWidget(mControlContainer); + + connect(mControlView, SIGNAL(resized(QResizeEvent*)), this, SLOT(boardViewResized(QResizeEvent*))); + + // TODO UB 4.x Optimization do we have to create the display view even if their is + // only 1 screen + // + mDisplayView = new UBBoardView(this, UBItemLayerType::FixedBackground, UBItemLayerType::Tool, 0); + mDisplayView->setInteractive(false); + mDisplayView->setTransformationAnchor(QGraphicsView::NoAnchor); + + mMessageWindow = new UBMessageWindow(mControlView); + mMessageWindow->hide(); + + mPaletteManager = new UBBoardPaletteManager(mControlContainer, this); + connect(this, SIGNAL(activeSceneChanged()), mPaletteManager, SLOT(activeSceneChanged())); + +} + + +void UBBoardController::setupLayout() +{ + if(mPaletteManager) + mPaletteManager->setupLayout(); +} + + +void UBBoardController::setBoxing(QRect displayRect) +{ + if (displayRect.isNull()) + { + mControlLayout->setContentsMargins(0, 0, 0, 0); + return; + } + + qreal controlWidth = (qreal)mMainWindow->centralWidget()->width(); + qreal controlHeight = (qreal)mMainWindow->centralWidget()->height(); + qreal displayWidth = (qreal)displayRect.width(); + qreal displayHeight = (qreal)displayRect.height(); + + qreal displayRatio = displayWidth / displayHeight; + qreal controlRatio = controlWidth / controlHeight; + + if (displayRatio < controlRatio) + { + // Pillarboxing + int boxWidth = (controlWidth - (displayWidth * (controlHeight / displayHeight))) / 2; + mControlLayout->setContentsMargins(boxWidth, 0, boxWidth, 0); + } + else if (displayRatio > controlRatio) + { + // Letterboxing + int boxHeight = (controlHeight - (displayHeight * (controlWidth / displayWidth))) / 2; + mControlLayout->setContentsMargins(0, boxHeight, 0, boxHeight); + } + else + { + // No boxing + mControlLayout->setContentsMargins(0, 0, 0, 0); + } +} + + +QSize UBBoardController::displayViewport() +{ + return mDisplayView->geometry().size(); +} + + +QSize UBBoardController::controlViewport() +{ + return mControlView->geometry().size(); +} + + +QRectF UBBoardController::controlGeometry() +{ + return mControlView->geometry(); +} + + +void UBBoardController::setupToolbar() +{ + UBSettings *settings = UBSettings::settings(); + + // Setup color choice widget + QList colorActions; + colorActions.append(mMainWindow->actionColor0); + colorActions.append(mMainWindow->actionColor1); + colorActions.append(mMainWindow->actionColor2); + colorActions.append(mMainWindow->actionColor3); + + UBToolbarButtonGroup *colorChoice = + new UBToolbarButtonGroup(mMainWindow->boardToolBar, colorActions); + + mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice); + + connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), colorChoice, SLOT(displayText(QVariant))); + connect(colorChoice, SIGNAL(activated(int)), this, SLOT(setColorIndex(int))); + connect(UBDrawingController::drawingController(), SIGNAL(colorIndexChanged(int)), colorChoice, SLOT(setCurrentIndex(int))); + connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), colorChoice, SLOT(colorPaletteChanged())); + connect(UBDrawingController::drawingController(), SIGNAL(colorPaletteChanged()), this, SLOT(colorPaletteChanged())); + + colorChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); + colorChoice->colorPaletteChanged(); + + // Setup line width choice widget + QList lineWidthActions; + lineWidthActions.append(mMainWindow->actionLineSmall); + lineWidthActions.append(mMainWindow->actionLineMedium); + lineWidthActions.append(mMainWindow->actionLineLarge); + + UBToolbarButtonGroup *lineWidthChoice = + new UBToolbarButtonGroup(mMainWindow->boardToolBar, lineWidthActions); + + connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), lineWidthChoice, SLOT(displayText(QVariant))); + + connect(lineWidthChoice, SIGNAL(activated(int)) + , UBDrawingController::drawingController(), SLOT(setLineWidthIndex(int))); + + connect(UBDrawingController::drawingController(), SIGNAL(lineWidthIndexChanged(int)) + , lineWidthChoice, SLOT(setCurrentIndex(int))); + + lineWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); + + mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice); + + //-----------------------------------------------------------// + // Setup eraser width choice widget + + QList eraserWidthActions; + eraserWidthActions.append(mMainWindow->actionEraserSmall); + eraserWidthActions.append(mMainWindow->actionEraserMedium); + eraserWidthActions.append(mMainWindow->actionEraserLarge); + + UBToolbarButtonGroup *eraserWidthChoice = + new UBToolbarButtonGroup(mMainWindow->boardToolBar, eraserWidthActions); + + mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice); + + connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), eraserWidthChoice, SLOT(displayText(QVariant))); + connect(eraserWidthChoice, SIGNAL(activated(int)), UBDrawingController::drawingController(), SLOT(setEraserWidthIndex(int))); + + eraserWidthChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); + eraserWidthChoice->setCurrentIndex(settings->eraserWidthIndex()); + + mMainWindow->boardToolBar->insertSeparator(mMainWindow->actionBackgrounds); + + //-----------------------------------------------------------// + + UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard); + UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->tutorialToolBar, mMainWindow->actionBoard); + + UBApplication::app()->decorateActionMenu(mMainWindow->actionMenu); + + mMainWindow->actionBoard->setVisible(false); + + mMainWindow->webToolBar->hide(); + mMainWindow->documentToolBar->hide(); + mMainWindow->tutorialToolBar->hide(); + + connectToolbar(); + initToolbarTexts(); +} + + +void UBBoardController::setToolCursor(int tool) +{ + if (mActiveScene) + { + mActiveScene->setToolCursor(tool); + } + + mControlView->setToolCursor(tool); +} + + +void UBBoardController::connectToolbar() +{ + connect(mMainWindow->actionAdd, SIGNAL(triggered()), this, SLOT(addItem())); + connect(mMainWindow->actionNewPage, SIGNAL(triggered()), this, SLOT(addScene())); + connect(mMainWindow->actionDuplicatePage, SIGNAL(triggered()), this, SLOT(duplicateScene())); + + connect(mMainWindow->actionClearPage, SIGNAL(triggered()), this, SLOT(clearScene())); + connect(mMainWindow->actionEraseItems, SIGNAL(triggered()), this, SLOT(clearSceneItems())); + connect(mMainWindow->actionEraseAnnotations, SIGNAL(triggered()), this, SLOT(clearSceneAnnotation())); + connect(mMainWindow->actionEraseBackground,SIGNAL(triggered()),this,SLOT(clearSceneBackground())); + + connect(mMainWindow->actionUndo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(undo())); + connect(mMainWindow->actionRedo, SIGNAL(triggered()), UBApplication::undoStack, SLOT(redo())); + connect(mMainWindow->actionRedo, SIGNAL(triggered()), this, SLOT(startScript())); + connect(mMainWindow->actionBack, SIGNAL( triggered()), this, SLOT(previousScene())); + connect(mMainWindow->actionForward, SIGNAL(triggered()), this, SLOT(nextScene())); + connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(stopScript())); + connect(mMainWindow->actionSleep, SIGNAL(triggered()), this, SLOT(blackout())); + connect(mMainWindow->actionVirtualKeyboard, SIGNAL(triggered(bool)), this, SLOT(showKeyboard(bool))); + connect(mMainWindow->actionImportPage, SIGNAL(triggered()), this, SLOT(importPage())); +} + +void UBBoardController::startScript() +{ + freezeW3CWidgets(false); +} + +void UBBoardController::stopScript() +{ + freezeW3CWidgets(true); +} + +void UBBoardController::initToolbarTexts() +{ + QList allToolbarActions; + + allToolbarActions << mMainWindow->boardToolBar->actions(); + allToolbarActions << mMainWindow->webToolBar->actions(); + allToolbarActions << mMainWindow->documentToolBar->actions(); + + foreach(QAction* action, allToolbarActions) + { + QString nominalText = action->text(); + QString shortText = truncate(nominalText, 48); + QPair texts(nominalText, shortText); + + mActionTexts.insert(action, texts); + } +} + + +void UBBoardController::setToolbarTexts() +{ + bool highResolution = mMainWindow->width() > 1024; + QSize iconSize; + + if (highResolution) + iconSize = QSize(48, 32); + else + iconSize = QSize(32, 32); + + mMainWindow->boardToolBar->setIconSize(iconSize); + mMainWindow->webToolBar->setIconSize(iconSize); + mMainWindow->documentToolBar->setIconSize(iconSize); + + foreach(QAction* action, mActionTexts.keys()) + { + QPair texts = mActionTexts.value(action); + + if (highResolution) + action->setText(texts.first); + else + { + action->setText(texts.second); + } + + action->setToolTip(texts.first); + } +} + + +QString UBBoardController::truncate(QString text, int maxWidth) +{ + QFontMetricsF fontMetrics(mMainWindow->font()); + return fontMetrics.elidedText(text, Qt::ElideRight, maxWidth); +} + + +void UBBoardController::stylusToolDoubleClicked(int tool) +{ + if (tool == UBStylusTool::ZoomIn || tool == UBStylusTool::ZoomOut) + { + zoomRestore(); + } + else if (tool == UBStylusTool::Hand) + { + centerRestore(); + } +} + + + +void UBBoardController::addScene() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + + UBDocumentContainer::addPage(mActiveSceneIndex + 1); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + setActiveDocumentScene(mActiveSceneIndex + 1); + QApplication::restoreOverrideCursor(); +} + +void UBBoardController::addScene(UBGraphicsScene* scene, bool replaceActiveIfEmpty) +{ + if (scene) + { + UBGraphicsScene* clone = scene->sceneDeepCopy(); + + if (scene->document() && (scene->document() != selectedDocument())) + { + foreach(QUrl relativeFile, scene->relativeDependencies()) + { + QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); + QString target = selectedDocument()->persistencePath() + "/" + relativeFile.toString(); + + QFileInfo fi(target); + QDir d = fi.dir(); + + d.mkpath(d.absolutePath()); + QFile::copy(source, target); + } + } + + if (replaceActiveIfEmpty && mActiveScene->isEmpty()) + { + setActiveDocumentScene(mActiveSceneIndex); + } + else + { + persistCurrentScene(); + UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(selectedDocument(), clone, mActiveSceneIndex + 1); + setActiveDocumentScene(mActiveSceneIndex + 1); + } + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } +} + + +void UBBoardController::addScene(UBDocumentProxy* proxy, int sceneIndex, bool replaceActiveIfEmpty) +{ + UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(proxy, sceneIndex); + + if (scene) + { + addScene(scene, replaceActiveIfEmpty); + } +} + +void UBBoardController::duplicateScene(int nIndex) +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + + QList scIndexes; + scIndexes << nIndex; + duplicatePages(scIndexes); + insertThumbPage(nIndex); + emit documentThumbnailsUpdated(this); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + setActiveDocumentScene(nIndex + 1); + QApplication::restoreOverrideCursor(); + + emit pageChanged(); +} + +void UBBoardController::duplicateScene() +{ + if (UBApplication::applicationController->displayMode() != UBApplicationController::Board) + return; + duplicateScene(mActiveSceneIndex); +} + +UBGraphicsItem *UBBoardController::duplicateItem(UBItem *item, bool bAsync) +{ + if (!item) + return NULL; + + UBGraphicsItem *retItem = NULL; + + mLastCreatedItem = NULL; + + QUrl sourceUrl; + QByteArray pData; + + //common parameters for any item + QPointF itemPos; + QSizeF itemSize; + + QGraphicsItem *commonItem = dynamic_cast(item); + if (commonItem) + { + qreal shifting = UBSettings::settings()->objectFrameWidth; + itemPos = commonItem->pos() + QPointF(shifting,shifting); + itemSize = commonItem->boundingRect().size(); + commonItem->setSelected(false); + } + + UBMimeType::Enum itemMimeType; + + QString srcFile = item->sourceUrl().toLocalFile(); + if (srcFile.isEmpty()) + srcFile = item->sourceUrl().toString(); + + QString contentTypeHeader; + if (!srcFile.isEmpty()) + contentTypeHeader = UBFileSystemUtils::mimeTypeFromFileName(srcFile); + + if(NULL != qgraphicsitem_cast(commonItem)) + itemMimeType = UBMimeType::Group; + else + itemMimeType = UBFileSystemUtils::mimeTypeFromString(contentTypeHeader); + + switch(static_cast(itemMimeType)) + { + case UBMimeType::AppleWidget: + case UBMimeType::W3CWidget: + { + UBGraphicsWidgetItem *witem = dynamic_cast(item); + if (witem) + { + sourceUrl = witem->getOwnFolder(); + } + }break; + + case UBMimeType::Video: + case UBMimeType::Audio: + { + UBGraphicsMediaItem *mitem = dynamic_cast(item); + if (mitem) + { + sourceUrl = mitem->mediaFileUrl(); + if (bAsync) + { + downloadURL(sourceUrl, srcFile, itemPos, QSize(itemSize.width(), itemSize.height()), false, false); + return NULL; // async operation + } + } + }break; + + case UBMimeType::VectorImage: + { + UBGraphicsSvgItem *viitem = dynamic_cast(item); + if (viitem) + { + pData = viitem->fileData(); + sourceUrl = item->sourceUrl(); + } + }break; + + case UBMimeType::RasterImage: + { + UBGraphicsPixmapItem *pixitem = dynamic_cast(item); + if (pixitem) + { + QBuffer buffer(&pData); + buffer.open(QIODevice::WriteOnly); + QString format = UBFileSystemUtils::extension(item->sourceUrl().toLocalFile()); + pixitem->pixmap().save(&buffer, format.toLatin1()); + } + }break; + + case UBMimeType::Group: + { + UBGraphicsGroupContainerItem* groupItem = dynamic_cast(item); + UBGraphicsGroupContainerItem* duplicatedGroup = NULL; + + QList duplicatedItems; + QList children = groupItem->childItems(); + + mActiveScene->setURStackEnable(false); + foreach(QGraphicsItem* pIt, children){ + UBItem* pItem = dynamic_cast(pIt); + if(pItem){ // we diong sync duplication of all childs. + QGraphicsItem * itemToGroup = dynamic_cast(duplicateItem(pItem, false)); + if (itemToGroup) + duplicatedItems.append(itemToGroup); + } + } + duplicatedGroup = mActiveScene->createGroup(duplicatedItems); + duplicatedGroup->setTransform(groupItem->transform()); + groupItem->setSelected(false); + + retItem = dynamic_cast(duplicatedGroup); + + QGraphicsItem * itemToAdd = dynamic_cast(retItem); + if (itemToAdd) + { + mActiveScene->addItem(itemToAdd); + itemToAdd->setSelected(true); + } + mActiveScene->setURStackEnable(true); + }break; + + case UBMimeType::UNKNOWN: + { + QGraphicsItem *gitem = dynamic_cast(item->deepCopy()); + if (gitem) + { + mActiveScene->addItem(gitem); + gitem->setPos(itemPos); + mLastCreatedItem = gitem; + gitem->setSelected(true); + } + retItem = dynamic_cast(gitem); + }break; + } + + if (retItem) + { + QGraphicsItem *graphicsRetItem = dynamic_cast(retItem); + if (mActiveScene->isURStackIsEnabled()) { //should be deleted after scene own undo stack implemented + UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(mActiveScene, 0, graphicsRetItem); + UBApplication::undoStack->push(uc); + } + return retItem; + } + + UBItem *createdItem = downloadFinished(true, sourceUrl, srcFile, contentTypeHeader, pData, itemPos, QSize(itemSize.width(), itemSize.height()), false); + if (createdItem) + { + createdItem->setSourceUrl(item->sourceUrl()); + item->copyItemParameters(createdItem); + + QGraphicsItem *createdGitem = dynamic_cast(createdItem); + if (createdGitem) + createdGitem->setPos(itemPos); + mLastCreatedItem = dynamic_cast(createdItem); + mLastCreatedItem->setSelected(true); + + retItem = dynamic_cast(createdItem); + } + + return retItem; +} + +void UBBoardController::deleteScene(int nIndex) +{ + if (selectedDocument()->pageCount()>=2) + { + mDeletingSceneIndex = nIndex; + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + showMessage(tr("Delete page %1 from document").arg(nIndex), true); + + QList scIndexes; + scIndexes << nIndex; + deletePages(scIndexes); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + if (nIndex >= pageCount()) + nIndex = pageCount()-1; + setActiveDocumentScene(nIndex); + showMessage(tr("Page %1 deleted").arg(nIndex)); + QApplication::restoreOverrideCursor(); + mDeletingSceneIndex = -1; + } +} + + +void UBBoardController::clearScene() +{ + if (mActiveScene) + { + freezeW3CWidgets(true); + mActiveScene->clearContent(UBGraphicsScene::clearItemsAndAnnotations); + updateActionStates(); + } +} + + +void UBBoardController::clearSceneItems() +{ + if (mActiveScene) + { + freezeW3CWidgets(true); + mActiveScene->clearContent(UBGraphicsScene::clearItems); + updateActionStates(); + } +} + + +void UBBoardController::clearSceneAnnotation() +{ + if (mActiveScene) + { + mActiveScene->clearContent(UBGraphicsScene::clearAnnotations); + updateActionStates(); + } +} + +void UBBoardController::clearSceneBackground() +{ + if (mActiveScene) + { + mActiveScene->clearContent(UBGraphicsScene::clearBackground); + updateActionStates(); + } +} + +void UBBoardController::showDocumentsDialog() +{ + if (selectedDocument()) + persistCurrentScene(); + + UBApplication::mainWindow->actionLibrary->setChecked(false); + +} + +void UBBoardController::libraryDialogClosed(int ret) +{ + Q_UNUSED(ret); + + mMainWindow->actionLibrary->setChecked(false); +} + + +void UBBoardController::blackout() +{ + UBApplication::applicationController->blackout(); +} + + +void UBBoardController::showKeyboard(bool show) +{ + if(show) + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + mPaletteManager->showVirtualKeyboard(show); +} + + +void UBBoardController::zoomIn(QPointF scenePoint) +{ + if (mControlView->transform().m11() > UB_MAX_ZOOM) + { + qApp->beep(); + return; + } + zoom(mZoomFactor, scenePoint); +} + + +void UBBoardController::zoomOut(QPointF scenePoint) +{ + if ((mControlView->horizontalScrollBar()->maximum() == 0) && (mControlView->verticalScrollBar()->maximum() == 0)) + { + // Do not zoom out if we reached the maximum + qApp->beep(); + return; + } + + qreal newZoomFactor = 1 / mZoomFactor; + + zoom(newZoomFactor, scenePoint); +} + + +void UBBoardController::zoomRestore() +{ + QTransform tr; + + tr.scale(mSystemScaleFactor, mSystemScaleFactor); + mControlView->setTransform(tr); + + centerRestore(); + + foreach(QGraphicsItem *gi, mActiveScene->selectedItems ()) + { + //force item to redraw the frame (for the anti scale calculation) + gi->setSelected(false); + gi->setSelected(true); + } + + emit zoomChanged(1.0); +} + + +void UBBoardController::centerRestore() +{ + centerOn(QPointF(0,0)); +} + + +void UBBoardController::centerOn(QPointF scenePoint) +{ + mControlView->centerOn(scenePoint); + UBApplication::applicationController->adjustDisplayView(); +} + + +void UBBoardController::zoom(const qreal ratio, QPointF scenePoint) +{ + + QPointF viewCenter = mControlView->mapToScene(QRect(0, 0, mControlView->width(), mControlView->height()).center()); + QPointF offset = scenePoint - viewCenter; + QPointF scalledOffset = offset / ratio; + + qreal currentZoom = ratio * mControlView->viewportTransform().m11() / mSystemScaleFactor; + + qreal usedRatio = ratio; + if (currentZoom > UB_MAX_ZOOM) + { + currentZoom = UB_MAX_ZOOM; + usedRatio = currentZoom * mSystemScaleFactor / mControlView->viewportTransform().m11(); + } + + mControlView->scale(usedRatio, usedRatio); + + QPointF newCenter = scenePoint - scalledOffset; + + mControlView->centerOn(newCenter); + + emit zoomChanged(currentZoom); + UBApplication::applicationController->adjustDisplayView(); + + emit controlViewportChanged(); + mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); +} + + +void UBBoardController::handScroll(qreal dx, qreal dy) +{ + mControlView->translate(dx, dy); + + UBApplication::applicationController->adjustDisplayView(); + + emit controlViewportChanged(); +} + + +void UBBoardController::previousScene() +{ + if (mActiveSceneIndex > 0) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(mActiveSceneIndex - 1); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + + +void UBBoardController::nextScene() +{ + if (mActiveSceneIndex < selectedDocument()->pageCount() - 1) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(mActiveSceneIndex + 1); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + + +void UBBoardController::firstScene() +{ + if (mActiveSceneIndex > 0) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(0); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + + +void UBBoardController::lastScene() +{ + if (mActiveSceneIndex < selectedDocument()->pageCount() - 1) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + persistCurrentScene(); + setActiveDocumentScene(selectedDocument()->pageCount() - 1); + QApplication::restoreOverrideCursor(); + } + + updateActionStates(); + emit pageChanged(); +} + +void UBBoardController::groupButtonClicked() +{ + QAction *groupAction = UBApplication::mainWindow->actionGroupItems; + QList selItems = activeScene()->selectedItems(); + if (!selItems.count()) { + qDebug() << "Got grouping request when there is no any selected item on the scene"; + return; + } + + if (groupAction->text() == mActionGroupText) { //The only way to get information from item, considering using smth else + UBGraphicsGroupContainerItem *groupItem = activeScene()->createGroup(selItems); + groupItem->setSelected(true); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + + } + else if (groupAction->text() == mActionUngroupText) { + //Considering one selected item and it's a group + if (selItems.count() > 1) + { + qDebug() << "can't make sense of ungrouping more then one item. Grouping action should be performed for that purpose"; + return; + } + UBGraphicsGroupContainerItem *currentGroup = dynamic_cast(selItems.first()); + if (currentGroup) { + currentGroup->destroy(); + } + } +} + +void UBBoardController::downloadURL(const QUrl& url, QString contentSourceUrl, const QPointF& pPos, const QSize& pSize, bool isBackground, bool internalData) +{ + qDebug() << "something has been dropped on the board! Url is: " << url.toString(); + QString sUrl = url.toString(); + + QGraphicsItem *oldBackgroundObject = NULL; + if (isBackground) + oldBackgroundObject = mActiveScene->backgroundObject(); + + if(sUrl.startsWith("uniboardTool://")) + { + downloadFinished(true, url, QUrl(), "application/vnd.mnemis-uniboard-tool", QByteArray(), pPos, pSize, isBackground); + } + else if (sUrl.startsWith("file://") || sUrl.startsWith("/")) + { + QUrl formedUrl = sUrl.startsWith("file://") ? url : QUrl::fromLocalFile(sUrl); + QString fileName = formedUrl.toLocalFile(); + QString contentType = UBFileSystemUtils::mimeTypeFromFileName(fileName); + + bool shouldLoadFileData = + contentType.startsWith("image") + || contentType.startsWith("application/widget") + || contentType.startsWith("application/vnd.apple-widget"); + + if (shouldLoadFileData) + { + QFile file(fileName); + file.open(QIODevice::ReadOnly); + downloadFinished(true, formedUrl, QUrl(), contentType, file.readAll(), pPos, pSize, isBackground, internalData); + file.close(); + } + else + { + // media items should be copyed in separate thread + + sDownloadFileDesc desc; + desc.modal = false; + desc.srcUrl = sUrl; + desc.originalSrcUrl = contentSourceUrl; + desc.currentSize = 0; + desc.name = QFileInfo(url.toString()).fileName(); + desc.totalSize = 0; // The total size will be retrieved during the download + desc.pos = pPos; + desc.size = pSize; + desc.isBackground = isBackground; + + UBDownloadManager::downloadManager()->addFileToDownload(desc); + } + } + else + { + QString urlString = url.toString(); + int parametersStringPosition = urlString.indexOf("?"); + if(parametersStringPosition != -1) + urlString = urlString.left(parametersStringPosition); + + // When we fall there, it means that we are dropping something from the web to the board + sDownloadFileDesc desc; + desc.modal = true; + desc.srcUrl = urlString; + desc.currentSize = 0; + desc.name = QFileInfo(urlString).fileName(); + desc.totalSize = 0; // The total size will be retrieved during the download + desc.pos = pPos; + desc.size = pSize; + desc.isBackground = isBackground; + + UBDownloadManager::downloadManager()->addFileToDownload(desc); + } + + if (isBackground && oldBackgroundObject != mActiveScene->backgroundObject()) + { + if (mActiveScene->isURStackIsEnabled()) { //should be deleted after scene own undo stack implemented + UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(mActiveScene, oldBackgroundObject, mActiveScene->backgroundObject()); + UBApplication::undoStack->push(uc); + } + } + + +} + + +UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QUrl contentUrl, QString pContentTypeHeader, + QByteArray pData, QPointF pPos, QSize pSize, + bool isBackground, bool internalData) +{ + QString mimeType = pContentTypeHeader; + + // In some cases "image/jpeg;charset=" is retourned by the drag-n-drop. That is + // why we will check if an ; exists and take the first part (the standard allows this kind of mimetype) + if(mimeType.isEmpty()) + mimeType = UBFileSystemUtils::mimeTypeFromFileName(sourceUrl.toString()); + + int position=mimeType.indexOf(";"); + if(position != -1) + mimeType=mimeType.left(position); + + UBMimeType::Enum itemMimeType = UBFileSystemUtils::mimeTypeFromString(mimeType); + + if (!pSuccess) + { + showMessage(tr("Downloading content %1 failed").arg(sourceUrl.toString())); + return NULL; + } + + + mActiveScene->deselectAllItems(); + + if (!sourceUrl.toString().startsWith("file://") && !sourceUrl.toString().startsWith("uniboardTool://")) + showMessage(tr("Download finished")); + + if (UBMimeType::RasterImage == itemMimeType) + { + + qDebug() << "accepting mime type" << mimeType << "as raster image"; + + + QPixmap pix; + if(pData.length() == 0){ + pix.load(sourceUrl.toLocalFile()); + } + else{ + QImage img; + img.loadFromData(pData); + pix = QPixmap::fromImage(img); + } + + UBGraphicsPixmapItem* pixItem = mActiveScene->addPixmap(pix, NULL, pPos, 1.); + pixItem->setSourceUrl(sourceUrl); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(pixItem, true); + } + else + { + mActiveScene->scaleToFitDocumentSize(pixItem, true, UBSettings::objectInControlViewMargin); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + pixItem->setSelected(true); + } + + return pixItem; + } + else if (UBMimeType::VectorImage == itemMimeType) + { + qDebug() << "accepting mime type" << mimeType << "as vecto image"; + + UBGraphicsSvgItem* svgItem = mActiveScene->addSvg(sourceUrl, pPos, pData); + svgItem->setSourceUrl(sourceUrl); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(svgItem); + } + else + { + mActiveScene->scaleToFitDocumentSize(svgItem, true, UBSettings::objectInControlViewMargin); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + svgItem->setSelected(true); + } + + return svgItem; + } + else if (UBMimeType::AppleWidget == itemMimeType) //mime type invented by us :-( + { + qDebug() << "accepting mime type" << mimeType << "as Apple widget"; + + QUrl widgetUrl = sourceUrl; + + if (pData.length() > 0) + { + widgetUrl = expandWidgetToTempDir(pData, "wdgt"); + } + + UBGraphicsWidgetItem* appleWidgetItem = mActiveScene->addAppleWidget(widgetUrl, pPos); + + appleWidgetItem->setSourceUrl(sourceUrl); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(appleWidgetItem); + } + else + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + + return appleWidgetItem; + } + else if (UBMimeType::W3CWidget == itemMimeType) + { + qDebug() << "accepting mime type" << mimeType << "as W3C widget"; + QUrl widgetUrl = sourceUrl; + + if (pData.length() > 0) + { + widgetUrl = expandWidgetToTempDir(pData); + } + + UBGraphicsWidgetItem *w3cWidgetItem = addW3cWidget(widgetUrl, pPos); + + if (isBackground) + { + mActiveScene->setAsBackgroundObject(w3cWidgetItem); + } + else + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + + return w3cWidgetItem; + } + else if (UBMimeType::Video == itemMimeType) + { + qDebug() << "accepting mime type" << mimeType << "as video"; + + UBGraphicsMediaItem *mediaVideoItem = 0; + QUuid uuid = QUuid::createUuid(); + if (pData.length() > 0) + { + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), + sourceUrl.toString(), + UBPersistenceManager::videoDirectory, + uuid, + destFile, + &pData); + if (!b) + { + showMessage(tr("Add file operation failed: file copying error")); + return NULL; + } + + QUrl url = QUrl::fromLocalFile(destFile); + + mediaVideoItem = mActiveScene->addMedia(url, false, pPos); + } + else + { + qDebug() << sourceUrl.toString(); + mediaVideoItem = addVideo(sourceUrl, false, pPos, true); + } + + if(mediaVideoItem){ + if (contentUrl.isEmpty()) + mediaVideoItem->setSourceUrl(sourceUrl); + else + mediaVideoItem->setSourceUrl(contentUrl); + mediaVideoItem->setUuid(uuid); + connect(this, SIGNAL(activeSceneChanged()), mediaVideoItem, SLOT(activeSceneChanged())); + } + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + + return mediaVideoItem; + } + else if (UBMimeType::Audio == itemMimeType) + { + qDebug() << "accepting mime type" << mimeType << "as audio"; + + UBGraphicsMediaItem *audioMediaItem = 0; + + QUuid uuid = QUuid::createUuid(); + if (pData.length() > 0) + { + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), + sourceUrl.toString(), + UBPersistenceManager::audioDirectory, + uuid, + destFile, + &pData); + if (!b) + { + showMessage(tr("Add file operation failed: file copying error")); + return NULL; + } + + QUrl url = QUrl::fromLocalFile(destFile); + + audioMediaItem = mActiveScene->addMedia(url, false, pPos); + } + else + { + audioMediaItem = addAudio(sourceUrl, false, pPos, true); + } + + if(audioMediaItem){ + if (contentUrl.isEmpty()) + audioMediaItem->setSourceUrl(sourceUrl); + else + audioMediaItem->setSourceUrl(contentUrl); + audioMediaItem->setUuid(uuid); + connect(this, SIGNAL(activeSceneChanged()), audioMediaItem, SLOT(activeSceneChanged())); + } + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + + return audioMediaItem; + } + + else if (UBMimeType::Flash == itemMimeType) + { + + qDebug() << "accepting mime type" << mimeType << "as flash"; + + QString sUrl = sourceUrl.toString(); + + if (sUrl.startsWith("file://") || sUrl.startsWith("/")) + { + sUrl = sourceUrl.toLocalFile(); + } + + QTemporaryFile* eduMediaFile = 0; + + if (sUrl.toLower().contains("edumedia-sciences.com")) + { + eduMediaFile = new QTemporaryFile("XXXXXX.swf"); + if (eduMediaFile->open()) + { + eduMediaFile->write(pData); + QFileInfo fi(*eduMediaFile); + sUrl = fi.absoluteFilePath(); + } + } + + QSize size; + + if (pSize.height() > 0 && pSize.width() > 0) + size = pSize; + else + size = mActiveScene->nominalSize() * .8; + + Q_UNUSED(internalData) + + QString widgetUrl = UBGraphicsW3CWidgetItem::createNPAPIWrapper(sUrl, mimeType, size); + emit npapiWidgetCreated(widgetUrl); + + if (widgetUrl.length() > 0) + { + UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); + widgetItem->setUuid(QUuid::createUuid()); + widgetItem->setSourceUrl(QUrl::fromLocalFile(widgetUrl)); + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + + return widgetItem; + } + + if (eduMediaFile) + delete eduMediaFile; + + } + else if (UBMimeType::PDF == itemMimeType) + { + qDebug() << "accepting mime type" << mimeType << "as PDF"; + qDebug() << "pdf data length: " << pData.size(); + qDebug() << "sourceurl : " + sourceUrl.toString(); + int result = 0; + if(!sourceUrl.isEmpty()){ + QStringList fileNames; + fileNames << sourceUrl.toLocalFile(); + result = UBDocumentManager::documentManager()->addFilesToDocument(selectedDocument(), fileNames); + } + else if(pData.size()){ + QTemporaryFile pdfFile("XXXXXX.pdf"); + if (pdfFile.open()) + { + pdfFile.write(pData); + QStringList fileNames; + fileNames << pdfFile.fileName(); + result = UBDocumentManager::documentManager()->addFilesToDocument(selectedDocument(), fileNames); + pdfFile.close(); + } + } + + if (result){ + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } + } + else if (UBMimeType::UniboardTool == itemMimeType) + { + qDebug() << "accepting mime type" << mimeType << "as Uniboard Tool"; + + if (sourceUrl.toString() == UBToolsManager::manager()->compass.id) + { + mActiveScene->addCompass(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->ruler.id) + { + mActiveScene->addRuler(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->protractor.id) + { + mActiveScene->addProtractor(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->triangle.id) + { + mActiveScene->addTriangle(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->cache.id) + { + mActiveScene->addCache(); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->magnifier.id) + { + UBMagnifierParams params; + params.x = controlContainer()->geometry().width() / 2; + params.y = controlContainer()->geometry().height() / 2; + params.zoom = 2; + params.sizePercentFromScene = 20; + mActiveScene->addMagnifier(params); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else if (sourceUrl.toString() == UBToolsManager::manager()->mask.id) + { + mActiveScene->addMask(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } + else + { + showMessage(tr("Unknown tool type %1").arg(sourceUrl.toString())); + } + } + else if (sourceUrl.toString().contains("edumedia-sciences.com")) + { + qDebug() << "accepting url " << sourceUrl.toString() << "as eduMedia content"; + + QTemporaryFile eduMediaZipFile("XXXXXX.edumedia"); + if (eduMediaZipFile.open()) + { + eduMediaZipFile.write(pData); + eduMediaZipFile.close(); + + QString tempDir = UBFileSystemUtils::createTempDir("uniboard-edumedia"); + + UBFileSystemUtils::expandZipToDir(eduMediaZipFile, tempDir); + + QDir appDir(tempDir); + + foreach(QString subDirName, appDir.entryList(QDir::AllDirs)) + { + QDir subDir(tempDir + "/" + subDirName + "/contents"); + + foreach(QString fileName, subDir.entryList(QDir::Files)) + { + if (fileName.toLower().endsWith(".swf")) + { + QString swfFile = tempDir + "/" + subDirName + "/contents/" + fileName; + + QSize size; + + if (pSize.height() > 0 && pSize.width() > 0) + size = pSize; + else + size = mActiveScene->nominalSize() * .8; + + QString widgetUrl = UBGraphicsW3CWidgetItem::createNPAPIWrapper(swfFile, "application/x-shockwave-flash", size); + + if (widgetUrl.length() > 0) + { + UBGraphicsWidgetItem *widgetItem = mActiveScene->addW3CWidget(QUrl::fromLocalFile(widgetUrl), pPos); + + widgetItem->setSourceUrl(sourceUrl); + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + + return widgetItem; + } + } + } + } + } + } + else + { + showMessage(tr("Unknown content type %1").arg(pContentTypeHeader)); + qWarning() << "ignoring mime type" << pContentTypeHeader ; + } + + return NULL; +} + +void UBBoardController::setActiveDocumentScene(int pSceneIndex) +{ + setActiveDocumentScene(selectedDocument(), pSceneIndex); +} + +void UBBoardController::setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, const int pSceneIndex, bool forceReload) +{ + saveViewState(); + + bool documentChange = selectedDocument() != pDocumentProxy; + + int index = pSceneIndex; + int sceneCount = pDocumentProxy->pageCount(); + if (index >= sceneCount && sceneCount > 0) + index = sceneCount - 1; + + UBGraphicsScene* targetScene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, index); + + bool sceneChange = targetScene != mActiveScene; + + if (targetScene) + { + freezeW3CWidgets(true); + + persistCurrentScene(); + + ClearUndoStack(); + + mActiveScene = targetScene; + mActiveSceneIndex = index; + setDocument(pDocumentProxy, forceReload); + + updateSystemScaleFactor(); + + mControlView->setScene(mActiveScene); + mDisplayView->setScene(mActiveScene); + mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11()); + pDocumentProxy->setDefaultDocumentSize(mActiveScene->nominalSize()); + updatePageSizeState(); + + adjustDisplayViews(); + + UBSettings::settings()->setDarkBackground(mActiveScene->isDarkBackground()); + UBSettings::settings()->setCrossedBackground(mActiveScene->isCrossedBackground()); + + freezeW3CWidgets(false); + } + + selectionChanged(); + + updateBackgroundActionsState(mActiveScene->isDarkBackground(), mActiveScene->isCrossedBackground()); + updateBackgroundState(); + + if(documentChange) + { + UBGraphicsTextItem::lastUsedTextColor = QColor(); + } + + + if (sceneChange) + { + emit activeSceneChanged(); + emit pageChanged(); + } +} + + +void UBBoardController::moveSceneToIndex(int source, int target) +{ + if (selectedDocument()) + { + + persistCurrentScene(); + + UBDocumentContainer::movePageToIndex(source, target); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(selectedDocument()); + mMovingSceneIndex = source; + setActiveDocumentScene(target); + mMovingSceneIndex = -1; + + } +} + +void UBBoardController::ClearUndoStack() +{ +// The code has been removed because it leads to a strange error and because the final goal has never been +// reached on tests and sound a little bit strange. +// Strange error: item->scene() crashes the application because item doesn't implement scene() method. I'm +// not able to give all the steps to reproduce this error sistematically but is quite frequent (~ twice per utilisation hours) +// strange goal: if item is on the undocommand, the item->scene() is null and the item is not on the deleted scene item list then +// then it's deleted. + + // QSet uniqueItems; +// // go through all stack command +// for(int i = 0; i < UBApplication::undoStack->count(); i++) +// { + +// UBAbstractUndoCommand *abstractCmd = (UBAbstractUndoCommand*)UBApplication::undoStack->command(i); +// if(abstractCmd->getType() != UBAbstractUndoCommand::undotype_GRAPHICITEM) +// continue; + +// UBGraphicsItemUndoCommand *cmd = (UBGraphicsItemUndoCommand*)UBApplication::undoStack->command(i); + +// // go through all added and removed objects, for create list of unique objects +// // grouped items will be deleted by groups, so we don't need do delete that items. +// QSetIterator itAdded(cmd->GetAddedList()); +// while (itAdded.hasNext()) +// { +// QGraphicsItem* item = itAdded.next(); +// if( !uniqueItems.contains(item) && !(item->parentItem() && UBGraphicsGroupContainerItem::Type == item->parentItem()->type())) +// uniqueItems.insert(item); +// } + +// QSetIterator itRemoved(cmd->GetRemovedList()); +// while (itRemoved.hasNext()) +// { +// QGraphicsItem* item = itRemoved.next(); +// if( !uniqueItems.contains(item) && !(item->parentItem() && UBGraphicsGroupContainerItem::Type == item->parentItem()->type())) +// uniqueItems.insert(item); +// } +// } + +// // go through all unique items, and check, ot on scene, or not. +// // if not on scene, than item can be deleted + +// QSetIterator itUniq(uniqueItems); +// while (itUniq.hasNext()) +// { +// QGraphicsItem* item = itUniq.next(); +// UBGraphicsScene *scene = NULL; +// if (item->scene()) { +// scene = dynamic_cast(item->scene()); +// } +// if(!scene) +// { +// if (!mActiveScene->deleteItem(item)) +// delete item; +// } +// } + + // clear stack, and command list + UBApplication::undoStack->clear(); + +} + +void UBBoardController::adjustDisplayViews() +{ + if (UBApplication::applicationController) + { + UBApplication::applicationController->adjustDisplayView(); + UBApplication::applicationController->adjustPreviousViews(mActiveSceneIndex, selectedDocument()); + } +} + + +void UBBoardController::changeBackground(bool isDark, bool isCrossed) +{ + bool currentIsDark = mActiveScene->isDarkBackground(); + bool currentIsCrossed = mActiveScene->isCrossedBackground(); + + if ((isDark != currentIsDark) || (currentIsCrossed != isCrossed)) + { + UBSettings::settings()->setDarkBackground(isDark); + UBSettings::settings()->setCrossedBackground(isCrossed); + + mActiveScene->setBackground(isDark, isCrossed); + + updateBackgroundState(); + + emit backgroundChanged(); + } +} + +void UBBoardController::boardViewResized(QResizeEvent* event) +{ + Q_UNUSED(event); + + int innerMargin = UBSettings::boardMargin; + int userHeight = mControlContainer->height() - (2 * innerMargin); + + mMessageWindow->move(innerMargin, innerMargin + userHeight - mMessageWindow->height()); + mMessageWindow->adjustSizeAndPosition(); + + UBApplication::applicationController->initViewState( + mControlView->horizontalScrollBar()->value(), + mControlView->verticalScrollBar()->value()); + + updateSystemScaleFactor(); + + mControlView->centerOn(0,0); + + if (mDisplayView) + mDisplayView->centerOn(0,0); + + mPaletteManager->containerResized(); + + UBApplication::boardController->controlView()->scene()->moveMagnifier(); + +} + + +void UBBoardController::documentWillBeDeleted(UBDocumentProxy* pProxy) +{ + if (selectedDocument() == pProxy) + { + if (!mIsClosing) + setActiveDocumentScene(UBPersistenceManager::persistenceManager()->createDocument()); + } +} + + +void UBBoardController::showMessage(const QString& message, bool showSpinningWheel) +{ + mMessageWindow->showMessage(message, showSpinningWheel); +} + + +void UBBoardController::hideMessage() +{ + mMessageWindow->hideMessage(); +} + + +void UBBoardController::setDisabled(bool disable) +{ + mMainWindow->boardToolBar->setDisabled(disable); + mControlView->setDisabled(disable); +} + + +void UBBoardController::selectionChanged() +{ + updateActionStates(); + emit pageSelectionChanged(activeSceneIndex()); +} + + +void UBBoardController::undoRedoStateChange(bool canUndo) +{ + Q_UNUSED(canUndo); + + mMainWindow->actionUndo->setEnabled(UBApplication::undoStack->canUndo()); + mMainWindow->actionRedo->setEnabled(UBApplication::undoStack->canRedo()); + + updateActionStates(); +} + + +void UBBoardController::updateActionStates() +{ + mMainWindow->actionBack->setEnabled(selectedDocument() && (mActiveSceneIndex > 0)); + mMainWindow->actionForward->setEnabled(selectedDocument() && (mActiveSceneIndex < selectedDocument()->pageCount() - 1)); + mMainWindow->actionErase->setEnabled(mActiveScene && !mActiveScene->isEmpty()); +} + + +UBGraphicsScene* UBBoardController::activeScene() const +{ + return mActiveScene; +} + + +int UBBoardController::activeSceneIndex() const +{ + return mActiveSceneIndex; +} + + +void UBBoardController::documentSceneChanged(UBDocumentProxy* pDocumentProxy, int pIndex) +{ + Q_UNUSED(pIndex); + + if(selectedDocument() == pDocumentProxy) + { + setActiveDocumentScene(mActiveSceneIndex); + } +} + +void UBBoardController::closing() +{ + mIsClosing = true; + ClearUndoStack(); + lastWindowClosed(); +} + +void UBBoardController::lastWindowClosed() +{ + if (!mCleanupDone) + { + bool teacherGuideModified = false; + if(UBApplication::boardController->paletteManager()->teacherGuideDockWidget()) + teacherGuideModified = UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified(); + if (selectedDocument()->pageCount() == 1 && (!mActiveScene || mActiveScene->isEmpty()) && !teacherGuideModified) + { + UBPersistenceManager::persistenceManager()->deleteDocument(selectedDocument()); + } + else + { + persistCurrentScene(); + } + + UBPersistenceManager::persistenceManager()->purgeEmptyDocuments(); + + mCleanupDone = true; + } +} + + + +void UBBoardController::setColorIndex(int pColorIndex) +{ + UBDrawingController::drawingController()->setColorIndex(pColorIndex); + + if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker && + UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Line && + UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Text && + UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Selector) + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); + } + + if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Pen || + UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line || + UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Text || + UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) + { + mPenColorOnDarkBackground = UBSettings::settings()->penColors(true).at(pColorIndex); + mPenColorOnLightBackground = UBSettings::settings()->penColors(false).at(pColorIndex); + + if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) + { + // If we are in mode board, then do that + if(UBApplication::applicationController->displayMode() == UBApplicationController::Board) + { + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Pen); + mMainWindow->actionPen->setChecked(true); + } + } + + emit penColorChanged(); + } + else if (UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Marker) + { + mMarkerColorOnDarkBackground = UBSettings::settings()->markerColors(true).at(pColorIndex); + mMarkerColorOnLightBackground = UBSettings::settings()->markerColors(false).at(pColorIndex); + } +} + +void UBBoardController::colorPaletteChanged() +{ + mPenColorOnDarkBackground = UBSettings::settings()->penColor(true); + mPenColorOnLightBackground = UBSettings::settings()->penColor(false); + mMarkerColorOnDarkBackground = UBSettings::settings()->markerColor(true); + mMarkerColorOnLightBackground = UBSettings::settings()->markerColor(false); +} + + +qreal UBBoardController::currentZoom() +{ + if (mControlView) + return mControlView->viewportTransform().m11() / mSystemScaleFactor; + else + return 1.0; +} + +void UBBoardController::removeTool(UBToolWidget* toolWidget) +{ + toolWidget->hide(); + + delete toolWidget; +} + +void UBBoardController::hide() +{ + UBApplication::mainWindow->actionLibrary->setChecked(false); +} + +void UBBoardController::show() +{ + UBApplication::mainWindow->actionLibrary->setChecked(false); +} + +void UBBoardController::persistCurrentScene() +{ + if(UBPersistenceManager::persistenceManager() + && selectedDocument() && mActiveScene && mActiveSceneIndex != mDeletingSceneIndex + && (mActiveSceneIndex >= 0) && mActiveSceneIndex != mMovingSceneIndex + && (mActiveScene->isModified() || (UBApplication::boardController->paletteManager()->teacherGuideDockWidget() && UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified()))) + { + UBPersistenceManager::persistenceManager()->persistDocumentScene(selectedDocument(), mActiveScene, mActiveSceneIndex); + updatePage(mActiveSceneIndex); + } +} + +void UBBoardController::updateSystemScaleFactor() +{ + qreal newScaleFactor = 1.0; + + if (mActiveScene) + { + QSize pageNominalSize = mActiveScene->nominalSize(); + //we're going to keep scale factor untouched if the size is custom + QMap sizesMap = UBSettings::settings()->documentSizes; + // if(pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio16_9) || pageNominalSize == sizesMap.value(DocumentSizeRatio::Ratio4_3)) + { + QSize controlSize = controlViewport(); + + qreal hFactor = ((qreal)controlSize.width()) / ((qreal)pageNominalSize.width()); + qreal vFactor = ((qreal)controlSize.height()) / ((qreal)pageNominalSize.height()); + + newScaleFactor = qMin(hFactor, vFactor); + } + } + + if (mSystemScaleFactor != newScaleFactor) + { + mSystemScaleFactor = newScaleFactor; + emit systemScaleFactorChanged(newScaleFactor); + } + + UBGraphicsScene::SceneViewState viewState = mActiveScene->viewState(); + + QTransform scalingTransform; + + qreal scaleFactor = viewState.zoomFactor * mSystemScaleFactor; + scalingTransform.scale(scaleFactor, scaleFactor); + + mControlView->setTransform(scalingTransform); + mControlView->horizontalScrollBar()->setValue(viewState.horizontalPosition); + mControlView->verticalScrollBar()->setValue(viewState.verticalPostition); + mActiveScene->setBackgroundZoomFactor(mControlView->transform().m11());} + + +void UBBoardController::setWidePageSize(bool checked) +{ + Q_UNUSED(checked); + QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9); + + if (mActiveScene->nominalSize() != newSize) + { + UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); + UBApplication::undoStack->push(uc); + + setPageSize(newSize); + } +} + + +void UBBoardController::setRegularPageSize(bool checked) +{ + Q_UNUSED(checked); + QSize newSize = UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3); + + if (mActiveScene->nominalSize() != newSize) + { + UBPageSizeUndoCommand* uc = new UBPageSizeUndoCommand(mActiveScene, mActiveScene->nominalSize(), newSize); + UBApplication::undoStack->push(uc); + + setPageSize(newSize); + } +} + + +void UBBoardController::setPageSize(QSize newSize) +{ + if (mActiveScene->nominalSize() != newSize) + { + mActiveScene->setNominalSize(newSize); + + saveViewState(); + + updateSystemScaleFactor(); + updatePageSizeState(); + adjustDisplayViews(); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + UBSettings::settings()->pageSize->set(newSize); + } +} + +void UBBoardController::notifyCache(bool visible) +{ + if(visible) + { + emit cacheEnabled(); + } + else + { + emit cacheDisabled(); + } + mCacheWidgetIsEnabled = visible; +} + +void UBBoardController::updatePageSizeState() +{ + if (mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio16_9)) + { + mMainWindow->actionWidePageSize->setChecked(true); + } + else if(mActiveScene->nominalSize() == UBSettings::settings()->documentSizes.value(DocumentSizeRatio::Ratio4_3)) + { + mMainWindow->actionRegularPageSize->setChecked(true); + } + else + { + mMainWindow->actionCustomPageSize->setChecked(true); + } +} + + +void UBBoardController::saveViewState() +{ + if (mActiveScene) + { + mActiveScene->setViewState(UBGraphicsScene::SceneViewState(currentZoom(), + mControlView->horizontalScrollBar()->value(), + mControlView->verticalScrollBar()->value())); + } +} + + +void UBBoardController::updateBackgroundState() +{ + //adjust background style + QString newBackgroundStyle; + + if (mActiveScene && mActiveScene->isDarkBackground()) + { + newBackgroundStyle ="QWidget {background-color: #0E0E0E}"; + } + else + { + newBackgroundStyle ="QWidget {background-color: #F1F1F1}"; + } +} + +void UBBoardController::stylusToolChanged(int tool) +{ + if (UBPlatformUtils::hasVirtualKeyboard() && mPaletteManager->mKeyboardPalette) + { + UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; + if(eTool != UBStylusTool::Selector && eTool != UBStylusTool::Text) + { + if(mPaletteManager->mKeyboardPalette->m_isVisible) + UBApplication::mainWindow->actionVirtualKeyboard->activate(QAction::Trigger); + } + } + + updateBackgroundState(); +} + + +QUrl UBBoardController::expandWidgetToTempDir(const QByteArray& pZipedData, const QString& ext) +{ + QUrl widgetUrl; + QTemporaryFile tmp; + + if (tmp.open()) + { + tmp.write(pZipedData); + tmp.flush(); + tmp.close(); + + QString tmpDir = UBFileSystemUtils::createTempDir() + "." + ext; + + if (UBFileSystemUtils::expandZipToDir(tmp, tmpDir)) + { + widgetUrl = QUrl::fromLocalFile(tmpDir); + } + } + + return widgetUrl; +} + + +void UBBoardController::grabScene(const QRectF& pSceneRect) +{ + if (mActiveScene) + { + QImage image(pSceneRect.width(), pSceneRect.height(), QImage::Format_ARGB32); + image.fill(Qt::transparent); + + QRectF targetRect(0, 0, pSceneRect.width(), pSceneRect.height()); + QPainter painter(&image); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::Antialiasing); + + mActiveScene->setRenderingContext(UBGraphicsScene::NonScreen); + mActiveScene->setRenderingQuality(UBItem::RenderingQualityHigh); + + mActiveScene->render(&painter, targetRect, pSceneRect); + + mActiveScene->setRenderingContext(UBGraphicsScene::Screen); + mActiveScene->setRenderingQuality(UBItem::RenderingQualityNormal); + + mPaletteManager->addItem(QPixmap::fromImage(image)); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } +} + +UBGraphicsMediaItem* UBBoardController::addVideo(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos, bool bUseSource) +{ + QUuid uuid = QUuid::createUuid(); + QUrl concreteUrl = pSourceUrl; + + // media file is not in document folder yet + if (!bUseSource) + { + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), + pSourceUrl.toLocalFile(), + UBPersistenceManager::videoDirectory, + uuid, + destFile); + if (!b) + { + showMessage(tr("Add file operation failed: file copying error")); + return NULL; + } + concreteUrl = QUrl::fromLocalFile(destFile); + }// else we just use source Url. + + + UBGraphicsMediaItem* vi = mActiveScene->addMedia(concreteUrl, startPlay, pos); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + if (vi) { + vi->setUuid(uuid); + vi->setSourceUrl(pSourceUrl); + } + + return vi; + +} + +UBGraphicsMediaItem* UBBoardController::addAudio(const QUrl& pSourceUrl, bool startPlay, const QPointF& pos, bool bUseSource) +{ + QUuid uuid = QUuid::createUuid(); + QUrl concreteUrl = pSourceUrl; + + // media file is not in document folder yet + if (!bUseSource) + { + QString destFile; + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(selectedDocument(), + pSourceUrl.toLocalFile(), + UBPersistenceManager::audioDirectory, + uuid, + destFile); + if (!b) + { + showMessage(tr("Add file operation failed: file copying error")); + return NULL; + } + concreteUrl = QUrl::fromLocalFile(destFile); + }// else we just use source Url. + + UBGraphicsMediaItem* ai = mActiveScene->addMedia(concreteUrl, startPlay, pos); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + + if (ai){ + ai->setUuid(uuid); + ai->setSourceUrl(pSourceUrl); + } + + return ai; + +} + +UBGraphicsWidgetItem *UBBoardController::addW3cWidget(const QUrl &pUrl, const QPointF &pos) +{ + UBGraphicsWidgetItem* w3cWidgetItem = 0; + + QUuid uuid = QUuid::createUuid(); + + QString destPath; + if (!UBPersistenceManager::persistenceManager()->addGraphicsWidgteToDocument(selectedDocument(), pUrl.toLocalFile(), uuid, destPath)) + return NULL; + QUrl newUrl = QUrl::fromLocalFile(destPath); + + w3cWidgetItem = mActiveScene->addW3CWidget(newUrl, pos); + + if (w3cWidgetItem) { + w3cWidgetItem->setUuid(uuid); + w3cWidgetItem->setOwnFolder(newUrl); + w3cWidgetItem->setSourceUrl(pUrl); + + QString struuid = UBStringUtils::toCanonicalUuid(uuid); + QString snapshotPath = selectedDocument()->persistencePath() + "/" + UBPersistenceManager::widgetDirectory + "/" + struuid + ".png"; + w3cWidgetItem->setSnapshotPath(QUrl::fromLocalFile(snapshotPath)); + UBGraphicsWidgetItem *tmpItem = dynamic_cast(w3cWidgetItem); + if (tmpItem && tmpItem->scene()) + tmpItem->takeSnapshot().save(snapshotPath, "PNG"); + + } + + return w3cWidgetItem; +} + +void UBBoardController::cut() +{ + //---------------------------------------------------------// + + QList selectedItems; + foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) + selectedItems << gi; + + //---------------------------------------------------------// + + QList selected; + foreach(QGraphicsItem* gi, selectedItems) + { + gi->setSelected(false); + + UBItem* ubItem = dynamic_cast(gi); + UBGraphicsItem *ubGi = dynamic_cast(gi); + + if (ubItem && ubGi && !mActiveScene->tools().contains(gi)) + { + selected << ubItem->deepCopy(); + ubGi->remove(); + } + } + + //---------------------------------------------------------// + + if (selected.size() > 0) + { + QClipboard *clipboard = QApplication::clipboard(); + + UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); + + mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); + clipboard->setMimeData(mimeGi); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + } + + //---------------------------------------------------------// +} + + +void UBBoardController::copy() +{ + QList selected; + + foreach(QGraphicsItem* gi, mActiveScene->selectedItems()) + { + UBItem* ubItem = dynamic_cast(gi); + + if (ubItem && !mActiveScene->tools().contains(gi)) + { + UBItem *itemCopy = ubItem->deepCopy(); + if (itemCopy) + selected << itemCopy; + } + } + + if (selected.size() > 0) + { + QClipboard *clipboard = QApplication::clipboard(); + + UBMimeDataGraphicsItem* mimeGi = new UBMimeDataGraphicsItem(selected); + + mimeGi->setData(UBApplication::mimeTypeUniboardPageItem, QByteArray()); + clipboard->setMimeData(mimeGi); + + } +} + + +void UBBoardController::paste() +{ + QClipboard *clipboard = QApplication::clipboard(); + QPointF pos(0, 0); + processMimeData(clipboard->mimeData(), pos); + + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); +} + + +void UBBoardController::processMimeData(const QMimeData* pMimeData, const QPointF& pPos) +{ + if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + const UBMimeData* mimeData = qobject_cast (pMimeData); + + if (mimeData) + { + int previousActiveSceneIndex = activeSceneIndex(); + int previousPageCount = selectedDocument()->pageCount(); + + foreach (UBMimeDataItem sourceItem, mimeData->items()) + addScene(sourceItem.documentProxy(), sourceItem.sceneIndex(), true); + + if (selectedDocument()->pageCount() < previousPageCount + mimeData->items().count()) + setActiveDocumentScene(previousActiveSceneIndex); + else + setActiveDocumentScene(previousActiveSceneIndex + 1); + + return; + } + } + + if (pMimeData->hasFormat(UBApplication::mimeTypeUniboardPageItem)) + { + const UBMimeDataGraphicsItem* mimeData = qobject_cast (pMimeData); + + if (mimeData) + { + foreach(UBItem* item, mimeData->items()) + { + QGraphicsItem* pItem = dynamic_cast(item); + if(NULL != pItem){ + duplicateItem(item); + } + } + + return; + } + } + + if(pMimeData->hasHtml()) + { + QString qsHtml = pMimeData->html(); + QString url = UBApplication::urlFromHtml(qsHtml); + + if("" != url) + { + downloadURL(url, QString(), pPos); + return; + } + } + + if (pMimeData->hasUrls()) + { + QList urls = pMimeData->urls(); + + int index = 0; + + const UBFeaturesMimeData *internalMimeData = qobject_cast(pMimeData); + bool internalData = false; + if (internalMimeData) { + internalData = true; + } + + foreach(const QUrl url, urls){ + QPointF pos(pPos + QPointF(index * 15, index * 15)); + + downloadURL(url, QString(), pos, QSize(), false, internalData); + index++; + } + + return; + } + + if (pMimeData->hasImage()) + { + QImage img = qvariant_cast (pMimeData->imageData()); + QPixmap pix = QPixmap::fromImage(img); + + // validate that the image is really an image, webkit does not fill properly the image mime data + if (pix.width() != 0 && pix.height() != 0) + { + mActiveScene->addPixmap(pix, NULL, pPos, 1.); + return; + } + } + + if (pMimeData->hasText()) + { + if("" != pMimeData->text()){ + // Sometimes, it is possible to have an URL as text. we check here if it is the case + QString qsTmp = pMimeData->text().remove(QRegExp("[\\0]")); + if(qsTmp.startsWith("http")){ + downloadURL(QUrl(qsTmp), QString(), pPos); + } + else{ + mActiveScene->addTextHtml(pMimeData->html(), pPos); + } + } + else{ +#ifdef Q_WS_MACX + // With Safari, in 95% of the drops, the mime datas are hidden in Apple Web Archive pasteboard type. + // This is due to the way Safari is working so we have to dig into the pasteboard in order to retrieve + // the data. + QString qsUrl = UBPlatformUtils::urlFromClipboard(); + if("" != qsUrl){ + // We finally got the url of the dropped ressource! Let's import it! + downloadURL(qsUrl, qsUrl, pPos); + return; + } +#endif + } + } +} + + +void UBBoardController::togglePodcast(bool checked) +{ + if (UBPodcastController::instance()) + UBPodcastController::instance()->toggleRecordingPalette(checked); +} + +void UBBoardController::moveGraphicsWidgetToControlView(UBGraphicsWidgetItem* graphicsWidget) +{ + mActiveScene->setURStackEnable(false); + UBGraphicsItem *toolW3C = duplicateItem(dynamic_cast(graphicsWidget)); + UBGraphicsWidgetItem *copyedGraphicsWidget = NULL; + + if (UBGraphicsWidgetItem::Type == toolW3C->type()) + copyedGraphicsWidget = static_cast(toolW3C); + + UBToolWidget *toolWidget = new UBToolWidget(copyedGraphicsWidget, mControlView); + + graphicsWidget->remove(false); + mActiveScene->addItemToDeletion(graphicsWidget); + + mActiveScene->setURStackEnable(true); + + QPoint controlViewPos = mControlView->mapFromScene(graphicsWidget->sceneBoundingRect().center()); + toolWidget->centerOn(mControlView->mapTo(mControlContainer, controlViewPos)); + toolWidget->show(); +} + + +void UBBoardController::moveToolWidgetToScene(UBToolWidget* toolWidget) +{ + UBGraphicsWidgetItem *widgetToScene = toolWidget->toolWidget(); + + widgetToScene->resetTransform(); + + QPoint mainWindowCenter = toolWidget->mapTo(mMainWindow, QPoint(toolWidget->width(), toolWidget->height()) / 2); + QPoint controlViewCenter = mControlView->mapFrom(mMainWindow, mainWindowCenter); + QPointF scenePos = mControlView->mapToScene(controlViewCenter); + + mActiveScene->addGraphicsWidget(widgetToScene, scenePos); + + toolWidget->remove(); +} + + +void UBBoardController::updateBackgroundActionsState(bool isDark, bool isCrossed) +{ + if (isDark && !isCrossed) + mMainWindow->actionPlainDarkBackground->setChecked(true); + else if (isDark && isCrossed) + mMainWindow->actionCrossedDarkBackground->setChecked(true); + else if (!isDark && isCrossed) + mMainWindow->actionCrossedLightBackground->setChecked(true); + else + mMainWindow->actionPlainLightBackground->setChecked(true); +} + + +void UBBoardController::addItem() +{ + QString defaultPath = UBSettings::settings()->lastImportToLibraryPath->get().toString(); + + QString extensions; + foreach(QString ext, UBSettings::imageFileExtensions) + { + extensions += " *."; + extensions += ext; + } + + QString filename = QFileDialog::getOpenFileName(mControlContainer, tr("Add Item"), + defaultPath, + tr("All Supported (%1)").arg(extensions), NULL, QFileDialog::DontUseNativeDialog); + + if (filename.length() > 0) + { + mPaletteManager->addItem(QUrl::fromLocalFile(filename)); + QFileInfo source(filename); + UBSettings::settings()->lastImportToLibraryPath->set(QVariant(source.absolutePath())); + } +} + +void UBBoardController::importPage() +{ + int pageCount = selectedDocument()->pageCount(); + if (UBApplication::documentController->addFileToDocument(selectedDocument())) + { + setActiveDocumentScene(selectedDocument(), pageCount, true); + } +} + +void UBBoardController::notifyPageChanged() +{ + emit pageChanged(); +} + +void UBBoardController::onDownloadModalFinished() +{ + +} + +void UBBoardController::displayMetaData(QMap metadatas) +{ + emit displayMetadata(metadatas); +} + +void UBBoardController::freezeW3CWidgets(bool freeze) +{ + if (mActiveSceneIndex >= 0) + { + QList list = UBApplication::boardController->activeScene()->getFastAccessItems(); + foreach(QGraphicsItem *item, list) + { + freezeW3CWidget(item, freeze); + } + } +} + +void UBBoardController::freezeW3CWidget(QGraphicsItem *item, bool freeze) +{ + if(item->type() == UBGraphicsW3CWidgetItem::Type) + { + UBGraphicsW3CWidgetItem* item_casted = dynamic_cast(item); + if (0 == item_casted) + return; + + if (freeze) { + item_casted->load(QUrl(UBGraphicsW3CWidgetItem::freezedWidgetFilePath())); + } else + item_casted->loadMainHtml(); + } +} diff --git a/src/board/UBBoardController.h b/src/board/UBBoardController.h index 5497b9be..10be4e81 100644 --- a/src/board/UBBoardController.h +++ b/src/board/UBBoardController.h @@ -19,295 +19,295 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBBOARDCONTROLLER_H_ -#define UBBOARDCONTROLLER_H_ - -#include - -#include -#include "document/UBDocumentContainer.h" - -class UBMainWindow; -class UBApplication; -class UBBoardView; - -class UBDocumentController; -class UBMessageWindow; -class UBGraphicsScene; -class UBDocumentProxy; -class UBBlackoutWidget; -class UBToolWidget; -class UBVersion; -class UBSoftwareUpdate; -class UBSoftwareUpdateDialog; -class UBGraphicsMediaItem; -class UBGraphicsVideoItem; -class UBGraphicsAudioItem; -class UBGraphicsWidgetItem; -class UBBoardPaletteManager; -class UBItem; -class UBGraphicsItem; - - -class UBBoardController : public UBDocumentContainer -{ - Q_OBJECT - - public: - UBBoardController(UBMainWindow *mainWindow); - virtual ~UBBoardController(); - - void init(); - void setupLayout(); - - UBGraphicsScene* activeScene() const; - int activeSceneIndex() const; - QSize displayViewport(); - QSize controlViewport(); - QRectF controlGeometry(); - void closing(); - - int currentPage(); - - QWidget* controlContainer() - { - return mControlContainer; - } - - UBBoardView* controlView() - { - return mControlView; - } - - UBBoardView* displayView() - { - return mDisplayView; - } - - UBGraphicsScene* activeScene() - { - return mActiveScene; - } - - void setPenColorOnDarkBackground(const QColor& pColor) - { - if (mPenColorOnDarkBackground == pColor) - return; - - mPenColorOnDarkBackground = pColor; - emit penColorChanged(); - } - - void setPenColorOnLightBackground(const QColor& pColor) - { - if (mPenColorOnLightBackground == pColor) - return; - - mPenColorOnLightBackground = pColor; - emit penColorChanged(); - } - - void setMarkerColorOnDarkBackground(const QColor& pColor) - { - mMarkerColorOnDarkBackground = pColor; - } - - void setMarkerColorOnLightBackground(const QColor& pColor) - { - mMarkerColorOnLightBackground = pColor; - } - - QColor penColorOnDarkBackground() - { - return mPenColorOnDarkBackground; - } - - QColor penColorOnLightBackground() - { - return mPenColorOnLightBackground; - } - - QColor markerColorOnDarkBackground() - { - return mMarkerColorOnDarkBackground; - } - - QColor markerColorOnLightBackground() - { - return mMarkerColorOnLightBackground; - } - - qreal systemScaleFactor() - { - return mSystemScaleFactor; - } - qreal currentZoom(); - void persistCurrentScene(); - void showNewVersionAvailable(bool automatic, const UBVersion &installedVersion, const UBSoftwareUpdate &softwareUpdate); - void setBoxing(QRect displayRect); - void setToolbarTexts(); - static QUrl expandWidgetToTempDir(const QByteArray& pZipedData, const QString& pExtension = QString("wgt")); -// static QRect freeRectInGlobalPos() const {return ;} - void setPageSize(QSize newSize); - UBBoardPaletteManager *paletteManager() - { - return mPaletteManager; - } - - void notifyCache(bool visible); - void notifyPageChanged(); - void displayMetaData(QMap metadatas); - - void ClearUndoStack(); - - void setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, int pSceneIndex = 0, bool forceReload = false); - void setActiveDocumentScene(int pSceneIndex); - - void moveSceneToIndex(int source, int target); - void duplicateScene(int index); - UBGraphicsItem *duplicateItem(UBItem *item, bool bAsync = true); - void deleteScene(int index); - - bool cacheIsVisible() {return mCacheWidgetIsEnabled;} - - QString actionGroupText(){ return mActionGroupText;} - QString actionUngroupText(){ return mActionUngroupText;} - - public slots: - void showDocumentsDialog(); - void showKeyboard(bool show); - void togglePodcast(bool checked); - void blackout(); - void addScene(); - void addScene(UBDocumentProxy* proxy, int sceneIndex, bool replaceActiveIfEmpty = false); - void addScene(UBGraphicsScene* scene, bool replaceActiveIfEmpty = false); - void duplicateScene(); - void importPage(); - void clearScene(); - void clearSceneItems(); - void clearSceneAnnotation(); - void clearSceneBackground(); - void zoomIn(QPointF scenePoint = QPointF(0,0)); - void zoomOut(QPointF scenePoint = QPointF(0,0)); - void zoomRestore(); - void centerRestore(); - void centerOn(QPointF scenePoint = QPointF(0,0)); - void zoom(const qreal ratio, QPointF scenePoint); - void handScroll(qreal dx, qreal dy); - void previousScene(); - void nextScene(); - void firstScene(); - void lastScene(); - void groupButtonClicked(); - void downloadURL(const QUrl& url, QString contentSourceUrl = QString(), const QPointF& pPos = QPointF(0.0, 0.0), const QSize& pSize = QSize(), bool isBackground = false, bool internalData = false); - UBItem *downloadFinished(bool pSuccess, QUrl sourceUrl, QUrl contentUrl, QString pHeader, - QByteArray pData, QPointF pPos, QSize pSize, - bool isBackground = false, bool internalData = false); - void changeBackground(bool isDark, bool isCrossed); - void setToolCursor(int tool); - void showMessage(const QString& message, bool showSpinningWheel = false); - void hideMessage(); - void setDisabled(bool disable); - void setColorIndex(int pColorIndex); - void removeTool(UBToolWidget* toolWidget); - void hide(); - void show(); - void setWidePageSize(bool checked); - void setRegularPageSize(bool checked); - void stylusToolChanged(int tool); - void grabScene(const QRectF& pSceneRect); - UBGraphicsMediaItem* addVideo(const QUrl& pUrl, bool startPlay, const QPointF& pos, bool bUseSource = false); - UBGraphicsMediaItem* addAudio(const QUrl& pUrl, bool startPlay, const QPointF& pos, bool bUseSource = false); - UBGraphicsWidgetItem *addW3cWidget(const QUrl& pUrl, const QPointF& pos); - - void cut(); - void copy(); - void paste(); - void processMimeData(const QMimeData* pMimeData, const QPointF& pPos); - void moveGraphicsWidgetToControlView(UBGraphicsWidgetItem* graphicWidget); - void moveToolWidgetToScene(UBToolWidget* toolWidget); - void addItem(); - - void freezeW3CWidgets(bool freeze); - void freezeW3CWidget(QGraphicsItem* item, bool freeze); - void startScript(); - void stopScript(); - - signals: - void newPageAdded(); - void activeSceneChanged(); - void zoomChanged(qreal pZoomFactor); - void systemScaleFactorChanged(qreal pSystemScaleFactor); - void penColorChanged(); - void controlViewportChanged(); - void backgroundChanged(); - void cacheEnabled(); - void cacheDisabled(); - void pageChanged(); - void documentReorganized(int index); - void displayMetadata(QMap metadata); - void pageSelectionChanged(int index); - void npapiWidgetCreated(const QString &Url); - - protected: - void setupViews(); - void setupToolbar(); - void connectToolbar(); - void initToolbarTexts(); - void updateActionStates(); - void updateSystemScaleFactor(); - QString truncate(QString text, int maxWidth); - - protected slots: - void selectionChanged(); - void undoRedoStateChange(bool canUndo); - void documentSceneChanged(UBDocumentProxy* proxy, int pIndex); - - private: - void updatePageSizeState(); - void saveViewState(); - void adjustDisplayViews(); - - UBMainWindow *mMainWindow; - UBGraphicsScene* mActiveScene; - int mActiveSceneIndex; - UBBoardPaletteManager *mPaletteManager; - UBSoftwareUpdateDialog *mSoftwareUpdateDialog; - UBMessageWindow *mMessageWindow; - UBBoardView *mControlView; - UBBoardView *mDisplayView; - QWidget *mControlContainer; - QHBoxLayout *mControlLayout; - qreal mZoomFactor; - bool mIsClosing; - QColor mPenColorOnDarkBackground; - QColor mPenColorOnLightBackground; - QColor mMarkerColorOnDarkBackground; - QColor mMarkerColorOnLightBackground; - qreal mSystemScaleFactor; - bool mCleanupDone; - QMap > mActionTexts; - bool mCacheWidgetIsEnabled; - QGraphicsItem* mLastCreatedItem; - int mDeletingSceneIndex; - int mMovingSceneIndex; - QString mActionGroupText; - QString mActionUngroupText; - - private slots: - void stylusToolDoubleClicked(int tool); - void boardViewResized(QResizeEvent* event); - void documentWillBeDeleted(UBDocumentProxy* pProxy); - void updateBackgroundActionsState(bool isDark, bool isCrossed); - void updateBackgroundState(); - void colorPaletteChanged(); - void libraryDialogClosed(int ret); - void lastWindowClosed(); - void onDownloadModalFinished(); - -}; - - -#endif /* UBBOARDCONTROLLER_H_ */ + + +#ifndef UBBOARDCONTROLLER_H_ +#define UBBOARDCONTROLLER_H_ + +#include + +#include +#include "document/UBDocumentContainer.h" + +class UBMainWindow; +class UBApplication; +class UBBoardView; + +class UBDocumentController; +class UBMessageWindow; +class UBGraphicsScene; +class UBDocumentProxy; +class UBBlackoutWidget; +class UBToolWidget; +class UBVersion; +class UBSoftwareUpdate; +class UBSoftwareUpdateDialog; +class UBGraphicsMediaItem; +class UBGraphicsVideoItem; +class UBGraphicsAudioItem; +class UBGraphicsWidgetItem; +class UBBoardPaletteManager; +class UBItem; +class UBGraphicsItem; + + +class UBBoardController : public UBDocumentContainer +{ + Q_OBJECT + + public: + UBBoardController(UBMainWindow *mainWindow); + virtual ~UBBoardController(); + + void init(); + void setupLayout(); + + UBGraphicsScene* activeScene() const; + int activeSceneIndex() const; + QSize displayViewport(); + QSize controlViewport(); + QRectF controlGeometry(); + void closing(); + + int currentPage(); + + QWidget* controlContainer() + { + return mControlContainer; + } + + UBBoardView* controlView() + { + return mControlView; + } + + UBBoardView* displayView() + { + return mDisplayView; + } + + UBGraphicsScene* activeScene() + { + return mActiveScene; + } + + void setPenColorOnDarkBackground(const QColor& pColor) + { + if (mPenColorOnDarkBackground == pColor) + return; + + mPenColorOnDarkBackground = pColor; + emit penColorChanged(); + } + + void setPenColorOnLightBackground(const QColor& pColor) + { + if (mPenColorOnLightBackground == pColor) + return; + + mPenColorOnLightBackground = pColor; + emit penColorChanged(); + } + + void setMarkerColorOnDarkBackground(const QColor& pColor) + { + mMarkerColorOnDarkBackground = pColor; + } + + void setMarkerColorOnLightBackground(const QColor& pColor) + { + mMarkerColorOnLightBackground = pColor; + } + + QColor penColorOnDarkBackground() + { + return mPenColorOnDarkBackground; + } + + QColor penColorOnLightBackground() + { + return mPenColorOnLightBackground; + } + + QColor markerColorOnDarkBackground() + { + return mMarkerColorOnDarkBackground; + } + + QColor markerColorOnLightBackground() + { + return mMarkerColorOnLightBackground; + } + + qreal systemScaleFactor() + { + return mSystemScaleFactor; + } + qreal currentZoom(); + void persistCurrentScene(); + void showNewVersionAvailable(bool automatic, const UBVersion &installedVersion, const UBSoftwareUpdate &softwareUpdate); + void setBoxing(QRect displayRect); + void setToolbarTexts(); + static QUrl expandWidgetToTempDir(const QByteArray& pZipedData, const QString& pExtension = QString("wgt")); +// static QRect freeRectInGlobalPos() const {return ;} + void setPageSize(QSize newSize); + UBBoardPaletteManager *paletteManager() + { + return mPaletteManager; + } + + void notifyCache(bool visible); + void notifyPageChanged(); + void displayMetaData(QMap metadatas); + + void ClearUndoStack(); + + void setActiveDocumentScene(UBDocumentProxy* pDocumentProxy, int pSceneIndex = 0, bool forceReload = false); + void setActiveDocumentScene(int pSceneIndex); + + void moveSceneToIndex(int source, int target); + void duplicateScene(int index); + UBGraphicsItem *duplicateItem(UBItem *item, bool bAsync = true); + void deleteScene(int index); + + bool cacheIsVisible() {return mCacheWidgetIsEnabled;} + + QString actionGroupText(){ return mActionGroupText;} + QString actionUngroupText(){ return mActionUngroupText;} + + public slots: + void showDocumentsDialog(); + void showKeyboard(bool show); + void togglePodcast(bool checked); + void blackout(); + void addScene(); + void addScene(UBDocumentProxy* proxy, int sceneIndex, bool replaceActiveIfEmpty = false); + void addScene(UBGraphicsScene* scene, bool replaceActiveIfEmpty = false); + void duplicateScene(); + void importPage(); + void clearScene(); + void clearSceneItems(); + void clearSceneAnnotation(); + void clearSceneBackground(); + void zoomIn(QPointF scenePoint = QPointF(0,0)); + void zoomOut(QPointF scenePoint = QPointF(0,0)); + void zoomRestore(); + void centerRestore(); + void centerOn(QPointF scenePoint = QPointF(0,0)); + void zoom(const qreal ratio, QPointF scenePoint); + void handScroll(qreal dx, qreal dy); + void previousScene(); + void nextScene(); + void firstScene(); + void lastScene(); + void groupButtonClicked(); + void downloadURL(const QUrl& url, QString contentSourceUrl = QString(), const QPointF& pPos = QPointF(0.0, 0.0), const QSize& pSize = QSize(), bool isBackground = false, bool internalData = false); + UBItem *downloadFinished(bool pSuccess, QUrl sourceUrl, QUrl contentUrl, QString pHeader, + QByteArray pData, QPointF pPos, QSize pSize, + bool isBackground = false, bool internalData = false); + void changeBackground(bool isDark, bool isCrossed); + void setToolCursor(int tool); + void showMessage(const QString& message, bool showSpinningWheel = false); + void hideMessage(); + void setDisabled(bool disable); + void setColorIndex(int pColorIndex); + void removeTool(UBToolWidget* toolWidget); + void hide(); + void show(); + void setWidePageSize(bool checked); + void setRegularPageSize(bool checked); + void stylusToolChanged(int tool); + void grabScene(const QRectF& pSceneRect); + UBGraphicsMediaItem* addVideo(const QUrl& pUrl, bool startPlay, const QPointF& pos, bool bUseSource = false); + UBGraphicsMediaItem* addAudio(const QUrl& pUrl, bool startPlay, const QPointF& pos, bool bUseSource = false); + UBGraphicsWidgetItem *addW3cWidget(const QUrl& pUrl, const QPointF& pos); + + void cut(); + void copy(); + void paste(); + void processMimeData(const QMimeData* pMimeData, const QPointF& pPos); + void moveGraphicsWidgetToControlView(UBGraphicsWidgetItem* graphicWidget); + void moveToolWidgetToScene(UBToolWidget* toolWidget); + void addItem(); + + void freezeW3CWidgets(bool freeze); + void freezeW3CWidget(QGraphicsItem* item, bool freeze); + void startScript(); + void stopScript(); + + signals: + void newPageAdded(); + void activeSceneChanged(); + void zoomChanged(qreal pZoomFactor); + void systemScaleFactorChanged(qreal pSystemScaleFactor); + void penColorChanged(); + void controlViewportChanged(); + void backgroundChanged(); + void cacheEnabled(); + void cacheDisabled(); + void pageChanged(); + void documentReorganized(int index); + void displayMetadata(QMap metadata); + void pageSelectionChanged(int index); + void npapiWidgetCreated(const QString &Url); + + protected: + void setupViews(); + void setupToolbar(); + void connectToolbar(); + void initToolbarTexts(); + void updateActionStates(); + void updateSystemScaleFactor(); + QString truncate(QString text, int maxWidth); + + protected slots: + void selectionChanged(); + void undoRedoStateChange(bool canUndo); + void documentSceneChanged(UBDocumentProxy* proxy, int pIndex); + + private: + void updatePageSizeState(); + void saveViewState(); + void adjustDisplayViews(); + + UBMainWindow *mMainWindow; + UBGraphicsScene* mActiveScene; + int mActiveSceneIndex; + UBBoardPaletteManager *mPaletteManager; + UBSoftwareUpdateDialog *mSoftwareUpdateDialog; + UBMessageWindow *mMessageWindow; + UBBoardView *mControlView; + UBBoardView *mDisplayView; + QWidget *mControlContainer; + QHBoxLayout *mControlLayout; + qreal mZoomFactor; + bool mIsClosing; + QColor mPenColorOnDarkBackground; + QColor mPenColorOnLightBackground; + QColor mMarkerColorOnDarkBackground; + QColor mMarkerColorOnLightBackground; + qreal mSystemScaleFactor; + bool mCleanupDone; + QMap > mActionTexts; + bool mCacheWidgetIsEnabled; + QGraphicsItem* mLastCreatedItem; + int mDeletingSceneIndex; + int mMovingSceneIndex; + QString mActionGroupText; + QString mActionUngroupText; + + private slots: + void stylusToolDoubleClicked(int tool); + void boardViewResized(QResizeEvent* event); + void documentWillBeDeleted(UBDocumentProxy* pProxy); + void updateBackgroundActionsState(bool isDark, bool isCrossed); + void updateBackgroundState(); + void colorPaletteChanged(); + void libraryDialogClosed(int ret); + void lastWindowClosed(); + void onDownloadModalFinished(); + +}; + + +#endif /* UBBOARDCONTROLLER_H_ */ diff --git a/src/board/UBBoardPaletteManager.cpp b/src/board/UBBoardPaletteManager.cpp index 582118bb..086da59b 100644 --- a/src/board/UBBoardPaletteManager.cpp +++ b/src/board/UBBoardPaletteManager.cpp @@ -19,984 +19,984 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBBoardPaletteManager.h" - -#include "frameworks/UBPlatformUtils.h" -#include "frameworks/UBFileSystemUtils.h" - -#include "core/UBApplication.h" -#include "core/UBApplicationController.h" -#include "core/UBSettings.h" -#include "core/UBSetting.h" -#include "core/UBDisplayManager.h" - -#include "gui/UBMainWindow.h" -#include "gui/UBStylusPalette.h" -#include "gui/UBKeyboardPalette.h" -#include "gui/UBToolWidget.h" -#include "gui/UBZoomPalette.h" -#include "gui/UBWebToolsPalette.h" -#include "gui/UBActionPalette.h" -#include "gui/UBFavoriteToolPalette.h" -#include "gui/UBDockTeacherGuideWidget.h" - - -#include "web/UBWebPage.h" -#include "web/UBWebController.h" -#include "web/browser/WBBrowserWindow.h" -#include "web/browser/WBTabWidget.h" -#include "web/browser/WBWebView.h" - -#include "desktop/UBDesktopAnnotationController.h" - - -#include "network/UBNetworkAccessManager.h" -#include "network/UBServerXMLHttpRequest.h" - -#include "domain/UBGraphicsScene.h" -#include "domain/UBGraphicsPixmapItem.h" - -#include "document/UBDocumentProxy.h" -#include "podcast/UBPodcastController.h" -#include "board/UBDrawingController.h" - -#include "tools/UBToolsManager.h" - -#include "UBBoardController.h" - -#include "document/UBDocumentController.h" - -#include "core/memcheck.h" - -UBBoardPaletteManager::UBBoardPaletteManager(QWidget* container, UBBoardController* pBoardController) - : QObject(container) - , mKeyboardPalette(0) - , mWebToolsCurrentPalette(0) - , mContainer(container) - , mBoardControler(pBoardController) - , mStylusPalette(0) - , mZoomPalette(0) - , mLeftPalette(NULL) - , mRightPalette(NULL) - , mBackgroundsPalette(0) - , mToolsPalette(0) - , mAddItemPalette(0) - , mErasePalette(NULL) - , mPagePalette(NULL) - , mPendingPageButtonPressed(false) - , mPendingZoomButtonPressed(false) - , mPendingPanButtonPressed(false) - , mPendingEraseButtonPressed(false) - , mpPageNavigWidget(NULL) - , mpCachePropWidget(NULL) - , mpDownloadWidget(NULL) - , mpTeacherGuideWidget(NULL) - , mDownloadInProgress(false) -{ - setupPalettes(); - connectPalettes(); -} - - -UBBoardPaletteManager::~UBBoardPaletteManager() -{ - -// mAddedItemPalette is delete automatically because of is parent -// that changes depending on the mode - -// mMainWindow->centralWidget is the parent of mStylusPalette -// do not delete this here. -} - -void UBBoardPaletteManager::initPalettesPosAtStartup() -{ - mStylusPalette->initPosition(); -} - -void UBBoardPaletteManager::setupLayout() -{ - -} - -/** - * \brief Set up the dock palette widgets - */ -void UBBoardPaletteManager::setupDockPaletteWidgets() -{ - - //------------------------------------------------// - // Create the widgets for the dock palettes - - mpPageNavigWidget = new UBPageNavigationWidget(); - - mpCachePropWidget = new UBCachePropertiesWidget(); - - mpDownloadWidget = new UBDockDownloadWidget(); - - // Add the dock palettes - mLeftPalette = new UBLeftPalette(mContainer); - - // LEFT palette widgets - mpPageNavigWidget = new UBPageNavigationWidget(); - mLeftPalette->registerWidget(mpPageNavigWidget); - mLeftPalette->addTab(mpPageNavigWidget); - - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool() || UBSettings::settings()->teacherGuideLessonPagesActivated->get().toBool()){ - mpTeacherGuideWidget = new UBDockTeacherGuideWidget(); - mLeftPalette->registerWidget(mpTeacherGuideWidget); - mLeftPalette->addTab(mpTeacherGuideWidget); - } - - mLeftPalette->connectSignals(); - mLeftPalette->showTabWidget(0); - - mRightPalette = new UBRightPalette(mContainer); - // RIGHT palette widgets - mpFeaturesWidget = new UBFeaturesWidget(); - mRightPalette->registerWidget(mpFeaturesWidget); - mRightPalette->addTab(mpFeaturesWidget); - - // The cache widget will be visible only if a cache is put on the page - mRightPalette->registerWidget(mpCachePropWidget); - - // The download widget will be part of the right palette but - // will become visible only when the first download starts - mRightPalette->registerWidget(mpDownloadWidget); - mRightPalette->connectSignals(); - changeMode(eUBDockPaletteWidget_BOARD, true); - - // Hide the tabs that must be hidden - mRightPalette->removeTab(mpDownloadWidget); - mRightPalette->removeTab(mpCachePropWidget); - -} - -void UBBoardPaletteManager::slot_changeMainMode(UBApplicationController::MainMode mainMode) -{ -// Board = 0, Internet, Document, Tutorial, ParaschoolEditor, WebDocument - - switch( mainMode ) - { - case UBApplicationController::Board: - { - // call changeMode only when switch NOT from desktop mode - if(!UBApplication::applicationController->isShowingDesktop()) - changeMode(eUBDockPaletteWidget_BOARD); - } - break; - - case UBApplicationController::Tutorial: - { - if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) - mKeyboardPalette->hide(); - } - break; - - case UBApplicationController::Internet: - changeMode(eUBDockPaletteWidget_WEB); - break; - - case UBApplicationController::Document: - changeMode(eUBDockPaletteWidget_DOCUMENT); - break; - - default: - { - if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) - mKeyboardPalette->hide(); - } - break; - } -} - -void UBBoardPaletteManager::slot_changeDesktopMode(bool isDesktop) -{ - UBApplicationController::MainMode currMode = UBApplication::applicationController->displayMode(); - if(!isDesktop) - { - switch( currMode ) - { - case UBApplicationController::Board: - changeMode(eUBDockPaletteWidget_BOARD); - break; - - default: - break; - } - } - else - changeMode(eUBDockPaletteWidget_DESKTOP); -} - -void UBBoardPaletteManager::setupPalettes() -{ - - if (UBPlatformUtils::hasVirtualKeyboard()) - { - mKeyboardPalette = new UBKeyboardPalette(0); -#ifndef Q_WS_WIN - connect(mKeyboardPalette, SIGNAL(closed()), mKeyboardPalette, SLOT(onDeactivated())); -#endif - } - - - setupDockPaletteWidgets(); - - - // Add the other palettes - mStylusPalette = new UBStylusPalette(mContainer, UBSettings::settings()->appToolBarOrientationVertical->get().toBool() ? Qt::Vertical : Qt::Horizontal); - connect(mStylusPalette, SIGNAL(stylusToolDoubleClicked(int)), UBApplication::boardController, SLOT(stylusToolDoubleClicked(int))); - mStylusPalette->show(); // always show stylus palette at startup - - mZoomPalette = new UBZoomPalette(mContainer); - - mStylusPalette->stackUnder(mZoomPalette); - - QList backgroundsActions; - - backgroundsActions << UBApplication::mainWindow->actionPlainLightBackground; - backgroundsActions << UBApplication::mainWindow->actionCrossedLightBackground; - backgroundsActions << UBApplication::mainWindow->actionPlainDarkBackground; - backgroundsActions << UBApplication::mainWindow->actionCrossedDarkBackground; - - mBackgroundsPalette = new UBActionPalette(backgroundsActions, Qt::Horizontal , mContainer); - mBackgroundsPalette->setButtonIconSize(QSize(128, 128)); - mBackgroundsPalette->groupActions(); - mBackgroundsPalette->setClosable(true); - mBackgroundsPalette->setAutoClose(true); - mBackgroundsPalette->adjustSizeAndPosition(); - mBackgroundsPalette->hide(); - - QList addItemActions; - - addItemActions << UBApplication::mainWindow->actionAddItemToCurrentPage; - addItemActions << UBApplication::mainWindow->actionAddItemToNewPage; - addItemActions << UBApplication::mainWindow->actionAddItemToLibrary; - - mAddItemPalette = new UBActionPalette(addItemActions, Qt::Horizontal, mContainer); - mAddItemPalette->setButtonIconSize(QSize(128, 128)); - mAddItemPalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - mAddItemPalette->groupActions(); - mAddItemPalette->setClosable(true); - mAddItemPalette->adjustSizeAndPosition(); - mAddItemPalette->hide(); - - QList eraseActions; - - eraseActions << UBApplication::mainWindow->actionEraseAnnotations; - eraseActions << UBApplication::mainWindow->actionEraseItems; - eraseActions << UBApplication::mainWindow->actionClearPage; - eraseActions << UBApplication::mainWindow->actionEraseBackground; - - mErasePalette = new UBActionPalette(eraseActions, Qt::Horizontal , mContainer); - mErasePalette->setButtonIconSize(QSize(128, 128)); - mErasePalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - mErasePalette->groupActions(); - mErasePalette->setClosable(true); - mErasePalette->adjustSizeAndPosition(); - mErasePalette->hide(); - - QList pageActions; - - pageActions << UBApplication::mainWindow->actionNewPage; - pageActions << UBApplication::mainWindow->actionDuplicatePage; - pageActions << UBApplication::mainWindow->actionImportPage; - - mPagePalette = new UBActionPalette(pageActions, Qt::Horizontal , mContainer); - mPagePalette->setButtonIconSize(QSize(128, 128)); - mPagePalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - mPagePalette->groupActions(); - mPagePalette->setClosable(true); - mPagePalette->adjustSizeAndPosition(); - mPagePalette->hide(); - - connect(UBSettings::settings()->appToolBarOrientationVertical, SIGNAL(changed(QVariant)), this, SLOT(changeStylusPaletteOrientation(QVariant))); -} - -void UBBoardPaletteManager::pagePaletteButtonPressed() -{ - mPageButtonPressedTime = QTime::currentTime(); - - mPendingPageButtonPressed = true; - QTimer::singleShot(1000, this, SLOT(pagePaletteButtonReleased())); -} - - -void UBBoardPaletteManager::pagePaletteButtonReleased() -{ - if (mPendingPageButtonPressed) - { - if( mPageButtonPressedTime.msecsTo(QTime::currentTime()) > 900) - { - // The palette is reinstanciated because the duplication depends on the current scene - delete(mPagePalette); - mPagePalette = 0; - QListpageActions; - pageActions << UBApplication::mainWindow->actionNewPage; - UBBoardController* boardController = UBApplication::boardController; - if(UBApplication::documentController->pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(boardController->activeSceneIndex()))){ - pageActions << UBApplication::mainWindow->actionDuplicatePage; - } - pageActions << UBApplication::mainWindow->actionImportPage; - - mPagePalette = new UBActionPalette(pageActions, Qt::Horizontal , mContainer); - mPagePalette->setButtonIconSize(QSize(128, 128)); - mPagePalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - mPagePalette->groupActions(); - mPagePalette->setClosable(true); - - // As we recreate the pagePalette every time, we must reconnect the slots - connect(UBApplication::mainWindow->actionNewPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); - connect(UBApplication::mainWindow->actionDuplicatePage, SIGNAL(triggered()), mPagePalette, SLOT(close())); - connect(UBApplication::mainWindow->actionImportPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); - connect(mPagePalette, SIGNAL(closed()), this, SLOT(pagePaletteClosed())); - - togglePagePalette(true); - } - else - { - UBApplication::mainWindow->actionNewPage->trigger(); - } - - mPendingPageButtonPressed = false; - } -} - -void UBBoardPaletteManager::erasePaletteButtonPressed() -{ - mEraseButtonPressedTime = QTime::currentTime(); - - mPendingEraseButtonPressed = true; - QTimer::singleShot(1000, this, SLOT(erasePaletteButtonReleased())); -} - - -void UBBoardPaletteManager::erasePaletteButtonReleased() -{ - if (mPendingEraseButtonPressed) - { - if( mEraseButtonPressedTime.msecsTo(QTime::currentTime()) > 900) - { - toggleErasePalette(true); - } - else - { - UBApplication::mainWindow->actionClearPage->trigger(); - } - - mPendingEraseButtonPressed = false; - } -} - - - -void UBBoardPaletteManager::linkClicked(const QUrl& url) -{ - UBApplication::applicationController->showInternet(); - UBApplication::webController->loadUrl(url); -} - - -void UBBoardPaletteManager::purchaseLinkActivated(const QString& link) -{ - UBApplication::applicationController->showInternet(); - UBApplication::webController->loadUrl(QUrl(link)); -} - -void UBBoardPaletteManager::connectPalettes() -{ - connect(UBApplication::mainWindow->actionStylus, SIGNAL(toggled(bool)), this, SLOT(toggleStylusPalette(bool))); - - foreach(QWidget *widget, UBApplication::mainWindow->actionZoomIn->associatedWidgets()) - { - QAbstractButton *button = qobject_cast(widget); - if (button) - { - connect(button, SIGNAL(pressed()), this, SLOT(zoomButtonPressed())); - connect(button, SIGNAL(released()), this, SLOT(zoomButtonReleased())); - } - } - - foreach(QWidget *widget, UBApplication::mainWindow->actionZoomOut->associatedWidgets()) - { - QAbstractButton *button = qobject_cast(widget); - if (button) - { - connect(button, SIGNAL(pressed()), this, SLOT(zoomButtonPressed())); - connect(button, SIGNAL(released()), this, SLOT(zoomButtonReleased())); - } - } - - foreach(QWidget *widget, UBApplication::mainWindow->actionHand->associatedWidgets()) - { - QAbstractButton *button = qobject_cast(widget); - if (button) - { - connect(button, SIGNAL(pressed()), this, SLOT(panButtonPressed())); - connect(button, SIGNAL(released()), this, SLOT(panButtonReleased())); - } - } - - connect(UBApplication::mainWindow->actionBackgrounds, SIGNAL(toggled(bool)), this, SLOT(toggleBackgroundPalette(bool))); - connect(mBackgroundsPalette, SIGNAL(closed()), this, SLOT(backgroundPaletteClosed())); - - connect(UBApplication::mainWindow->actionPlainLightBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); - connect(UBApplication::mainWindow->actionCrossedLightBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); - connect(UBApplication::mainWindow->actionPlainDarkBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); - connect(UBApplication::mainWindow->actionCrossedDarkBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); - connect(UBApplication::mainWindow->actionPodcast, SIGNAL(triggered(bool)), this, SLOT(tooglePodcastPalette(bool))); - - connect(UBApplication::mainWindow->actionAddItemToCurrentPage, SIGNAL(triggered()), this, SLOT(addItemToCurrentPage())); - connect(UBApplication::mainWindow->actionAddItemToNewPage, SIGNAL(triggered()), this, SLOT(addItemToNewPage())); - connect(UBApplication::mainWindow->actionAddItemToLibrary, SIGNAL(triggered()), this, SLOT(addItemToLibrary())); - - connect(UBApplication::mainWindow->actionEraseItems, SIGNAL(triggered()), mErasePalette, SLOT(close())); - connect(UBApplication::mainWindow->actionEraseAnnotations, SIGNAL(triggered()), mErasePalette, SLOT(close())); - connect(UBApplication::mainWindow->actionClearPage, SIGNAL(triggered()), mErasePalette, SLOT(close())); - connect(UBApplication::mainWindow->actionEraseBackground,SIGNAL(triggered()),mErasePalette,SLOT(close())); - connect(mErasePalette, SIGNAL(closed()), this, SLOT(erasePaletteClosed())); - - foreach(QWidget *widget, UBApplication::mainWindow->actionErase->associatedWidgets()) - { - QAbstractButton *button = qobject_cast(widget); - if (button) - { - connect(button, SIGNAL(pressed()), this, SLOT(erasePaletteButtonPressed())); - connect(button, SIGNAL(released()), this, SLOT(erasePaletteButtonReleased())); - } - } - - connect(UBApplication::mainWindow->actionNewPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); - connect(UBApplication::mainWindow->actionDuplicatePage, SIGNAL(triggered()), mPagePalette, SLOT(close())); - connect(UBApplication::mainWindow->actionImportPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); - connect(mPagePalette, SIGNAL(closed()), this, SLOT(pagePaletteClosed())); - - foreach(QWidget *widget, UBApplication::mainWindow->actionPages->associatedWidgets()) - { - QAbstractButton *button = qobject_cast(widget); - if (button) - { - connect(button, SIGNAL(pressed()), this, SLOT(pagePaletteButtonPressed())); - connect(button, SIGNAL(released()), this, SLOT(pagePaletteButtonReleased())); - } - } - -} - - -bool isFirstResized = true; -void UBBoardPaletteManager::containerResized() -{ - int innerMargin = UBSettings::boardMargin; - - int userLeft = innerMargin; - int userWidth = mContainer->width() - (2 * innerMargin); - int userTop = innerMargin; - int userHeight = mContainer->height() - (2 * innerMargin); - - if(mStylusPalette) - { - mStylusPalette->move(userLeft, userTop); - mStylusPalette->adjustSizeAndPosition(); - mStylusPalette->initPosition(); - } - - if(mZoomPalette) - { - mZoomPalette->move(userLeft + userWidth - mZoomPalette->width() - , userTop + userHeight /*- mPageNumberPalette->height()*/ - innerMargin - mZoomPalette->height()); - mZoomPalette->adjustSizeAndPosition(); - } - - if (isFirstResized && mKeyboardPalette && mKeyboardPalette->parent() == UBApplication::boardController->controlContainer()) - { - isFirstResized = false; - mKeyboardPalette->move(userLeft + (userWidth - mKeyboardPalette->width())/2, - userTop + (userHeight - mKeyboardPalette->height())/2); - mKeyboardPalette->adjustSizeAndPosition(); - } - - if(mLeftPalette) - { - mLeftPalette->resize(mLeftPalette->width()-1, mContainer->height()); - mLeftPalette->resize(mLeftPalette->width(), mContainer->height()); - } - - if(mRightPalette) - { - mRightPalette->resize(mRightPalette->width()-1, mContainer->height()); - mRightPalette->resize(mRightPalette->width(), mContainer->height()); - } -} - - -void UBBoardPaletteManager::changeBackground() -{ - if (UBApplication::mainWindow->actionCrossedLightBackground->isChecked()) - UBApplication::boardController->changeBackground(false, true); - else if (UBApplication::mainWindow->actionPlainDarkBackground->isChecked()) - UBApplication::boardController->changeBackground(true, false); - else if (UBApplication::mainWindow->actionCrossedDarkBackground->isChecked()) - UBApplication::boardController->changeBackground(true, true); - else - UBApplication::boardController->changeBackground(false, false); - - UBApplication::mainWindow->actionBackgrounds->setChecked(false); -} - - -void UBBoardPaletteManager::activeSceneChanged() -{ - UBGraphicsScene *activeScene = UBApplication::boardController->activeScene(); - int pageIndex = UBApplication::boardController->activeSceneIndex(); - - if (mStylusPalette) - connect(mStylusPalette, SIGNAL(mouseEntered()), activeScene, SLOT(hideEraser())); - - if (mpPageNavigWidget) - { - mpPageNavigWidget->setPageNumber(UBDocumentContainer::pageFromSceneIndex(pageIndex), activeScene->document()->pageCount()); - } - - if (mZoomPalette) - connect(mZoomPalette, SIGNAL(mouseEntered()), activeScene, SLOT(hideEraser())); - - if (mBackgroundsPalette) - connect(mBackgroundsPalette, SIGNAL(mouseEntered()), activeScene, SLOT(hideEraser())); -} - - -void UBBoardPaletteManager::toggleBackgroundPalette(bool checked) -{ - mBackgroundsPalette->setVisible(checked); - - if (checked) - { - UBApplication::mainWindow->actionErase->setChecked(false); - UBApplication::mainWindow->actionNewPage->setChecked(false); - - mBackgroundsPalette->adjustSizeAndPosition(); - mBackgroundsPalette->move((mContainer->width() - mBackgroundsPalette->width()) / 2, - (mContainer->height() - mBackgroundsPalette->height()) / 5); - } -} - - -void UBBoardPaletteManager::backgroundPaletteClosed() -{ - UBApplication::mainWindow->actionBackgrounds->setChecked(false); -} - - -void UBBoardPaletteManager::toggleStylusPalette(bool checked) -{ - mStylusPalette->setVisible(checked); -} - - -void UBBoardPaletteManager::toggleErasePalette(bool checked) -{ - mErasePalette->setVisible(checked); - if (checked) - { - UBApplication::mainWindow->actionBackgrounds->setChecked(false); - UBApplication::mainWindow->actionNewPage->setChecked(false); - - mErasePalette->adjustSizeAndPosition(); - mErasePalette->move((mContainer->width() - mErasePalette->width()) / 2, - (mContainer->height() - mErasePalette->height()) / 5); - } -} - - -void UBBoardPaletteManager::erasePaletteClosed() -{ - UBApplication::mainWindow->actionErase->setChecked(false); -} - - -void UBBoardPaletteManager::togglePagePalette(bool checked) -{ - mPagePalette->setVisible(checked); - if (checked) - { - UBApplication::mainWindow->actionBackgrounds->setChecked(false); - UBApplication::mainWindow->actionErase->setChecked(false); - - mPagePalette->adjustSizeAndPosition(); - mPagePalette->move((mContainer->width() - mPagePalette->width()) / 2, - (mContainer->height() - mPagePalette->height()) / 5); - } -} - - -void UBBoardPaletteManager::pagePaletteClosed() -{ - UBApplication::mainWindow->actionPages->setChecked(false); -} - - -void UBBoardPaletteManager::tooglePodcastPalette(bool checked) -{ - UBPodcastController::instance()->toggleRecordingPalette(checked); -} - - -void UBBoardPaletteManager::addItem(const QUrl& pUrl) -{ - mItemUrl = pUrl; - mPixmap = QPixmap(); - mPos = QPointF(0, 0); - mScaleFactor = 1.; - - mAddItemPalette->show(); - mAddItemPalette->adjustSizeAndPosition(); - - mAddItemPalette->move((mContainer->width() - mAddItemPalette->width()) / 2, - (mContainer->height() - mAddItemPalette->height()) / 5); -} - -void UBBoardPaletteManager::changeMode(eUBDockPaletteWidgetMode newMode, bool isInit) -{ - bool rightPaletteVisible = mRightPalette->switchMode(newMode); - bool leftPaletteVisible = mLeftPalette->switchMode(newMode); - - switch( newMode ) - { - case eUBDockPaletteWidget_BOARD: - { - // On Application start up the mAddItemPalette isn't initialized yet - if(mAddItemPalette){ - mAddItemPalette->setParent(UBApplication::boardController->controlContainer()); - } - mLeftPalette->assignParent(mContainer); - mRightPalette->assignParent(mContainer); - mRightPalette->stackUnder(mStylusPalette); - mLeftPalette->stackUnder(mStylusPalette); - if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) - { - - if(mKeyboardPalette->m_isVisible) - { - mKeyboardPalette->hide(); - mKeyboardPalette->setParent(UBApplication::boardController->controlContainer()); - mKeyboardPalette->show(); - } - else - mKeyboardPalette->setParent(UBApplication::boardController->controlContainer()); - } - - mLeftPalette->setVisible(leftPaletteVisible); - mRightPalette->setVisible(rightPaletteVisible); -#ifdef Q_WS_WIN - if (rightPaletteVisible) - mRightPalette->setAdditionalVOffset(0); -#endif - - if( !isInit ) - containerResized(); - if (mWebToolsCurrentPalette) - mWebToolsCurrentPalette->hide(); - } - break; - - case eUBDockPaletteWidget_DESKTOP: - { - mAddItemPalette->setParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); - mLeftPalette->assignParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); - mRightPalette->assignParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); - mStylusPalette->raise(); - - if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) - { - - if(mKeyboardPalette->m_isVisible) - { - mKeyboardPalette->hide(); -#ifndef Q_WS_X11 - mKeyboardPalette->setParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); -#else - mKeyboardPalette->setParent(0); -#endif -#ifdef Q_WS_MAC - mKeyboardPalette->setWindowFlags(Qt::Dialog | Qt::Popup | Qt::FramelessWindowHint); -#endif - mKeyboardPalette->show(); - } - else -// In linux keyboard in desktop mode have to allways be with null parent -#ifdef Q_WS_X11 - mKeyboardPalette->setParent(0); -#else - mKeyboardPalette->setParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); -#endif //Q_WS_X11 -#ifdef Q_WS_MAC - mKeyboardPalette->setWindowFlags(Qt::Dialog | Qt::Popup | Qt::FramelessWindowHint); -#endif - - } - - mLeftPalette->setVisible(leftPaletteVisible); - mRightPalette->setVisible(rightPaletteVisible); -#ifdef Q_WS_WIN - if (rightPaletteVisible && UBSettings::settings()->appToolBarPositionedAtTop->get().toBool()) - mRightPalette->setAdditionalVOffset(30); -#endif - - if(!isInit) - UBApplication::applicationController->uninotesController()->TransparentWidgetResized(); - - if (mWebToolsCurrentPalette) - mWebToolsCurrentPalette->hide(); - } - break; - - case eUBDockPaletteWidget_WEB: - { - mAddItemPalette->setParent(UBApplication::mainWindow); - if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) - { -// tmp variable? -// WBBrowserWindow* brWnd = UBApplication::webController->GetCurrentWebBrowser(); - - if(mKeyboardPalette->m_isVisible) - { - mKeyboardPalette->hide(); - mKeyboardPalette->setParent(UBApplication::mainWindow); - mKeyboardPalette->show(); - } - else - mKeyboardPalette->setParent(UBApplication::mainWindow); - } - - } - break; - - case eUBDockPaletteWidget_DOCUMENT: - { - mLeftPalette->setVisible(leftPaletteVisible); - mRightPalette->setVisible(rightPaletteVisible); - mLeftPalette->assignParent(UBApplication::documentController->controlView()); - mRightPalette->assignParent(UBApplication::documentController->controlView()); - if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) - { - - if(mKeyboardPalette->m_isVisible) - { - mKeyboardPalette->hide(); - mKeyboardPalette->setParent(UBApplication::documentController->controlView()); - mKeyboardPalette->show(); - } - else - mKeyboardPalette->setParent(UBApplication::documentController->controlView()); - } - if (mWebToolsCurrentPalette) - mWebToolsCurrentPalette->hide(); - } - break; - - default: - { - mLeftPalette->setVisible(leftPaletteVisible); - mRightPalette->setVisible(rightPaletteVisible); - mLeftPalette->assignParent(0); - mRightPalette->assignParent(0); - if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) - { - - if(mKeyboardPalette->m_isVisible) - { - mKeyboardPalette->hide(); - mKeyboardPalette->setParent(0); - mKeyboardPalette->show(); - } - else - mKeyboardPalette->setParent(0); - } - } - break; - } - - if( !isInit ) - UBApplication::boardController->notifyPageChanged(); - - emit signal_changeMode(newMode); -} - -void UBBoardPaletteManager::addItem(const QPixmap& pPixmap, const QPointF& pos, qreal scaleFactor, const QUrl& sourceUrl) -{ - mItemUrl = sourceUrl; - mPixmap = pPixmap; - mPos = pos; - mScaleFactor = scaleFactor; - - mAddItemPalette->show(); - mAddItemPalette->adjustSizeAndPosition(); - - mAddItemPalette->move((mContainer->width() - mAddItemPalette->width()) / 2, - (mContainer->height() - mAddItemPalette->height()) / 5); -} - - -void UBBoardPaletteManager::addItemToCurrentPage() -{ - UBApplication::applicationController->showBoard(); - mAddItemPalette->hide(); - if(mPixmap.isNull()) - UBApplication::boardController->downloadURL(mItemUrl); - else - { - UBGraphicsPixmapItem* item = UBApplication::boardController->activeScene()->addPixmap(mPixmap, NULL, mPos, mScaleFactor); - - item->setSourceUrl(mItemUrl); - item->setSelected(true); - - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); - } -} - - -void UBBoardPaletteManager::addItemToNewPage() -{ - UBApplication::boardController->addScene(); - addItemToCurrentPage(); -} - - -void UBBoardPaletteManager::addItemToLibrary() -{ - if(mPixmap.isNull()) - { - mPixmap = QPixmap(mItemUrl.toLocalFile()); - } - - if(!mPixmap.isNull()) - { - if(mScaleFactor != 1.) - { - mPixmap = mPixmap.scaled(mScaleFactor * mPixmap.width(), mScaleFactor* mPixmap.height() - , Qt::KeepAspectRatio, Qt::SmoothTransformation); - } - QImage image = mPixmap.toImage(); - - QDateTime now = QDateTime::currentDateTime(); - QString capturedName = tr("CapturedImage") + "-" + now.toString("dd-MM-yyyy hh-mm-ss") + ".png"; - mpFeaturesWidget->importImage(image, capturedName); - } - else - { - UBApplication::showMessage(tr("Error Adding Image to Library")); - } - - mAddItemPalette->hide(); -} - -void UBBoardPaletteManager::zoomButtonPressed() -{ - mZoomButtonPressedTime = QTime::currentTime(); - - mPendingZoomButtonPressed = true; - QTimer::singleShot(1000, this, SLOT(zoomButtonReleased())); -} - - -void UBBoardPaletteManager::zoomButtonReleased() -{ - if (mPendingZoomButtonPressed) - { - if(mZoomButtonPressedTime.msecsTo(QTime::currentTime()) > 900) - { - mBoardControler->zoomRestore(); - } - - mPendingZoomButtonPressed = false; - } -} - -void UBBoardPaletteManager::panButtonPressed() -{ - mPanButtonPressedTime = QTime::currentTime(); - - mPendingPanButtonPressed = true; - QTimer::singleShot(1000, this, SLOT(panButtonReleased())); -} - - -void UBBoardPaletteManager::panButtonReleased() -{ - if (mPendingPanButtonPressed) - { - if(mPanButtonPressedTime.msecsTo(QTime::currentTime()) > 900) - { - mBoardControler->centerRestore(); - } - - mPendingPanButtonPressed = false; - } -} - -void UBBoardPaletteManager::showVirtualKeyboard(bool show) -{ - if (mKeyboardPalette) - mKeyboardPalette->setVisible(show); -} - -void UBBoardPaletteManager::changeStylusPaletteOrientation(QVariant var) -{ - bool bVertical = var.toBool(); - bool bVisible = mStylusPalette->isVisible(); - - // Clean the old palette - if(NULL != mStylusPalette) - { - delete mStylusPalette; - mStylusPalette = NULL; - } - - // Create the new palette - if(bVertical) - { - mStylusPalette = new UBStylusPalette(mContainer, Qt::Vertical); - } - else - { - mStylusPalette = new UBStylusPalette(mContainer, Qt::Horizontal); - } - - connect(mStylusPalette, SIGNAL(stylusToolDoubleClicked(int)), UBApplication::boardController, SLOT(stylusToolDoubleClicked(int))); - mStylusPalette->setVisible(bVisible); // always show stylus palette at startup -} - - -void UBBoardPaletteManager::connectToDocumentController() -{ - emit connectToDocController(); -} - -void UBBoardPaletteManager::refreshPalettes() -{ - mRightPalette->update(); - mLeftPalette->update(); -} - -void UBBoardPaletteManager::startDownloads() -{ - if(!mDownloadInProgress) - { - mDownloadInProgress = true; - mpDownloadWidget->setVisibleState(true); - mRightPalette->addTab(mpDownloadWidget); - } -} - -void UBBoardPaletteManager::stopDownloads() -{ - if(mDownloadInProgress) - { - mDownloadInProgress = false; - mpDownloadWidget->setVisibleState(false); - mRightPalette->removeTab(mpDownloadWidget); - } -} + + +#include "UBBoardPaletteManager.h" + +#include "frameworks/UBPlatformUtils.h" +#include "frameworks/UBFileSystemUtils.h" + +#include "core/UBApplication.h" +#include "core/UBApplicationController.h" +#include "core/UBSettings.h" +#include "core/UBSetting.h" +#include "core/UBDisplayManager.h" + +#include "gui/UBMainWindow.h" +#include "gui/UBStylusPalette.h" +#include "gui/UBKeyboardPalette.h" +#include "gui/UBToolWidget.h" +#include "gui/UBZoomPalette.h" +#include "gui/UBWebToolsPalette.h" +#include "gui/UBActionPalette.h" +#include "gui/UBFavoriteToolPalette.h" +#include "gui/UBDockTeacherGuideWidget.h" + + +#include "web/UBWebPage.h" +#include "web/UBWebController.h" +#include "web/browser/WBBrowserWindow.h" +#include "web/browser/WBTabWidget.h" +#include "web/browser/WBWebView.h" + +#include "desktop/UBDesktopAnnotationController.h" + + +#include "network/UBNetworkAccessManager.h" +#include "network/UBServerXMLHttpRequest.h" + +#include "domain/UBGraphicsScene.h" +#include "domain/UBGraphicsPixmapItem.h" + +#include "document/UBDocumentProxy.h" +#include "podcast/UBPodcastController.h" +#include "board/UBDrawingController.h" + +#include "tools/UBToolsManager.h" + +#include "UBBoardController.h" + +#include "document/UBDocumentController.h" + +#include "core/memcheck.h" + +UBBoardPaletteManager::UBBoardPaletteManager(QWidget* container, UBBoardController* pBoardController) + : QObject(container) + , mKeyboardPalette(0) + , mWebToolsCurrentPalette(0) + , mContainer(container) + , mBoardControler(pBoardController) + , mStylusPalette(0) + , mZoomPalette(0) + , mLeftPalette(NULL) + , mRightPalette(NULL) + , mBackgroundsPalette(0) + , mToolsPalette(0) + , mAddItemPalette(0) + , mErasePalette(NULL) + , mPagePalette(NULL) + , mPendingPageButtonPressed(false) + , mPendingZoomButtonPressed(false) + , mPendingPanButtonPressed(false) + , mPendingEraseButtonPressed(false) + , mpPageNavigWidget(NULL) + , mpCachePropWidget(NULL) + , mpDownloadWidget(NULL) + , mpTeacherGuideWidget(NULL) + , mDownloadInProgress(false) +{ + setupPalettes(); + connectPalettes(); +} + + +UBBoardPaletteManager::~UBBoardPaletteManager() +{ + +// mAddedItemPalette is delete automatically because of is parent +// that changes depending on the mode + +// mMainWindow->centralWidget is the parent of mStylusPalette +// do not delete this here. +} + +void UBBoardPaletteManager::initPalettesPosAtStartup() +{ + mStylusPalette->initPosition(); +} + +void UBBoardPaletteManager::setupLayout() +{ + +} + +/** + * \brief Set up the dock palette widgets + */ +void UBBoardPaletteManager::setupDockPaletteWidgets() +{ + + //------------------------------------------------// + // Create the widgets for the dock palettes + + mpPageNavigWidget = new UBPageNavigationWidget(); + + mpCachePropWidget = new UBCachePropertiesWidget(); + + mpDownloadWidget = new UBDockDownloadWidget(); + + // Add the dock palettes + mLeftPalette = new UBLeftPalette(mContainer); + + // LEFT palette widgets + mpPageNavigWidget = new UBPageNavigationWidget(); + mLeftPalette->registerWidget(mpPageNavigWidget); + mLeftPalette->addTab(mpPageNavigWidget); + + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool() || UBSettings::settings()->teacherGuideLessonPagesActivated->get().toBool()){ + mpTeacherGuideWidget = new UBDockTeacherGuideWidget(); + mLeftPalette->registerWidget(mpTeacherGuideWidget); + mLeftPalette->addTab(mpTeacherGuideWidget); + } + + mLeftPalette->connectSignals(); + mLeftPalette->showTabWidget(0); + + mRightPalette = new UBRightPalette(mContainer); + // RIGHT palette widgets + mpFeaturesWidget = new UBFeaturesWidget(); + mRightPalette->registerWidget(mpFeaturesWidget); + mRightPalette->addTab(mpFeaturesWidget); + + // The cache widget will be visible only if a cache is put on the page + mRightPalette->registerWidget(mpCachePropWidget); + + // The download widget will be part of the right palette but + // will become visible only when the first download starts + mRightPalette->registerWidget(mpDownloadWidget); + mRightPalette->connectSignals(); + changeMode(eUBDockPaletteWidget_BOARD, true); + + // Hide the tabs that must be hidden + mRightPalette->removeTab(mpDownloadWidget); + mRightPalette->removeTab(mpCachePropWidget); + +} + +void UBBoardPaletteManager::slot_changeMainMode(UBApplicationController::MainMode mainMode) +{ +// Board = 0, Internet, Document, Tutorial, ParaschoolEditor, WebDocument + + switch( mainMode ) + { + case UBApplicationController::Board: + { + // call changeMode only when switch NOT from desktop mode + if(!UBApplication::applicationController->isShowingDesktop()) + changeMode(eUBDockPaletteWidget_BOARD); + } + break; + + case UBApplicationController::Tutorial: + { + if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) + mKeyboardPalette->hide(); + } + break; + + case UBApplicationController::Internet: + changeMode(eUBDockPaletteWidget_WEB); + break; + + case UBApplicationController::Document: + changeMode(eUBDockPaletteWidget_DOCUMENT); + break; + + default: + { + if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) + mKeyboardPalette->hide(); + } + break; + } +} + +void UBBoardPaletteManager::slot_changeDesktopMode(bool isDesktop) +{ + UBApplicationController::MainMode currMode = UBApplication::applicationController->displayMode(); + if(!isDesktop) + { + switch( currMode ) + { + case UBApplicationController::Board: + changeMode(eUBDockPaletteWidget_BOARD); + break; + + default: + break; + } + } + else + changeMode(eUBDockPaletteWidget_DESKTOP); +} + +void UBBoardPaletteManager::setupPalettes() +{ + + if (UBPlatformUtils::hasVirtualKeyboard()) + { + mKeyboardPalette = new UBKeyboardPalette(0); +#ifndef Q_WS_WIN + connect(mKeyboardPalette, SIGNAL(closed()), mKeyboardPalette, SLOT(onDeactivated())); +#endif + } + + + setupDockPaletteWidgets(); + + + // Add the other palettes + mStylusPalette = new UBStylusPalette(mContainer, UBSettings::settings()->appToolBarOrientationVertical->get().toBool() ? Qt::Vertical : Qt::Horizontal); + connect(mStylusPalette, SIGNAL(stylusToolDoubleClicked(int)), UBApplication::boardController, SLOT(stylusToolDoubleClicked(int))); + mStylusPalette->show(); // always show stylus palette at startup + + mZoomPalette = new UBZoomPalette(mContainer); + + mStylusPalette->stackUnder(mZoomPalette); + + QList backgroundsActions; + + backgroundsActions << UBApplication::mainWindow->actionPlainLightBackground; + backgroundsActions << UBApplication::mainWindow->actionCrossedLightBackground; + backgroundsActions << UBApplication::mainWindow->actionPlainDarkBackground; + backgroundsActions << UBApplication::mainWindow->actionCrossedDarkBackground; + + mBackgroundsPalette = new UBActionPalette(backgroundsActions, Qt::Horizontal , mContainer); + mBackgroundsPalette->setButtonIconSize(QSize(128, 128)); + mBackgroundsPalette->groupActions(); + mBackgroundsPalette->setClosable(true); + mBackgroundsPalette->setAutoClose(true); + mBackgroundsPalette->adjustSizeAndPosition(); + mBackgroundsPalette->hide(); + + QList addItemActions; + + addItemActions << UBApplication::mainWindow->actionAddItemToCurrentPage; + addItemActions << UBApplication::mainWindow->actionAddItemToNewPage; + addItemActions << UBApplication::mainWindow->actionAddItemToLibrary; + + mAddItemPalette = new UBActionPalette(addItemActions, Qt::Horizontal, mContainer); + mAddItemPalette->setButtonIconSize(QSize(128, 128)); + mAddItemPalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + mAddItemPalette->groupActions(); + mAddItemPalette->setClosable(true); + mAddItemPalette->adjustSizeAndPosition(); + mAddItemPalette->hide(); + + QList eraseActions; + + eraseActions << UBApplication::mainWindow->actionEraseAnnotations; + eraseActions << UBApplication::mainWindow->actionEraseItems; + eraseActions << UBApplication::mainWindow->actionClearPage; + eraseActions << UBApplication::mainWindow->actionEraseBackground; + + mErasePalette = new UBActionPalette(eraseActions, Qt::Horizontal , mContainer); + mErasePalette->setButtonIconSize(QSize(128, 128)); + mErasePalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + mErasePalette->groupActions(); + mErasePalette->setClosable(true); + mErasePalette->adjustSizeAndPosition(); + mErasePalette->hide(); + + QList pageActions; + + pageActions << UBApplication::mainWindow->actionNewPage; + pageActions << UBApplication::mainWindow->actionDuplicatePage; + pageActions << UBApplication::mainWindow->actionImportPage; + + mPagePalette = new UBActionPalette(pageActions, Qt::Horizontal , mContainer); + mPagePalette->setButtonIconSize(QSize(128, 128)); + mPagePalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + mPagePalette->groupActions(); + mPagePalette->setClosable(true); + mPagePalette->adjustSizeAndPosition(); + mPagePalette->hide(); + + connect(UBSettings::settings()->appToolBarOrientationVertical, SIGNAL(changed(QVariant)), this, SLOT(changeStylusPaletteOrientation(QVariant))); +} + +void UBBoardPaletteManager::pagePaletteButtonPressed() +{ + mPageButtonPressedTime = QTime::currentTime(); + + mPendingPageButtonPressed = true; + QTimer::singleShot(1000, this, SLOT(pagePaletteButtonReleased())); +} + + +void UBBoardPaletteManager::pagePaletteButtonReleased() +{ + if (mPendingPageButtonPressed) + { + if( mPageButtonPressedTime.msecsTo(QTime::currentTime()) > 900) + { + // The palette is reinstanciated because the duplication depends on the current scene + delete(mPagePalette); + mPagePalette = 0; + QListpageActions; + pageActions << UBApplication::mainWindow->actionNewPage; + UBBoardController* boardController = UBApplication::boardController; + if(UBApplication::documentController->pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(boardController->activeSceneIndex()))){ + pageActions << UBApplication::mainWindow->actionDuplicatePage; + } + pageActions << UBApplication::mainWindow->actionImportPage; + + mPagePalette = new UBActionPalette(pageActions, Qt::Horizontal , mContainer); + mPagePalette->setButtonIconSize(QSize(128, 128)); + mPagePalette->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + mPagePalette->groupActions(); + mPagePalette->setClosable(true); + + // As we recreate the pagePalette every time, we must reconnect the slots + connect(UBApplication::mainWindow->actionNewPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); + connect(UBApplication::mainWindow->actionDuplicatePage, SIGNAL(triggered()), mPagePalette, SLOT(close())); + connect(UBApplication::mainWindow->actionImportPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); + connect(mPagePalette, SIGNAL(closed()), this, SLOT(pagePaletteClosed())); + + togglePagePalette(true); + } + else + { + UBApplication::mainWindow->actionNewPage->trigger(); + } + + mPendingPageButtonPressed = false; + } +} + +void UBBoardPaletteManager::erasePaletteButtonPressed() +{ + mEraseButtonPressedTime = QTime::currentTime(); + + mPendingEraseButtonPressed = true; + QTimer::singleShot(1000, this, SLOT(erasePaletteButtonReleased())); +} + + +void UBBoardPaletteManager::erasePaletteButtonReleased() +{ + if (mPendingEraseButtonPressed) + { + if( mEraseButtonPressedTime.msecsTo(QTime::currentTime()) > 900) + { + toggleErasePalette(true); + } + else + { + UBApplication::mainWindow->actionClearPage->trigger(); + } + + mPendingEraseButtonPressed = false; + } +} + + + +void UBBoardPaletteManager::linkClicked(const QUrl& url) +{ + UBApplication::applicationController->showInternet(); + UBApplication::webController->loadUrl(url); +} + + +void UBBoardPaletteManager::purchaseLinkActivated(const QString& link) +{ + UBApplication::applicationController->showInternet(); + UBApplication::webController->loadUrl(QUrl(link)); +} + +void UBBoardPaletteManager::connectPalettes() +{ + connect(UBApplication::mainWindow->actionStylus, SIGNAL(toggled(bool)), this, SLOT(toggleStylusPalette(bool))); + + foreach(QWidget *widget, UBApplication::mainWindow->actionZoomIn->associatedWidgets()) + { + QAbstractButton *button = qobject_cast(widget); + if (button) + { + connect(button, SIGNAL(pressed()), this, SLOT(zoomButtonPressed())); + connect(button, SIGNAL(released()), this, SLOT(zoomButtonReleased())); + } + } + + foreach(QWidget *widget, UBApplication::mainWindow->actionZoomOut->associatedWidgets()) + { + QAbstractButton *button = qobject_cast(widget); + if (button) + { + connect(button, SIGNAL(pressed()), this, SLOT(zoomButtonPressed())); + connect(button, SIGNAL(released()), this, SLOT(zoomButtonReleased())); + } + } + + foreach(QWidget *widget, UBApplication::mainWindow->actionHand->associatedWidgets()) + { + QAbstractButton *button = qobject_cast(widget); + if (button) + { + connect(button, SIGNAL(pressed()), this, SLOT(panButtonPressed())); + connect(button, SIGNAL(released()), this, SLOT(panButtonReleased())); + } + } + + connect(UBApplication::mainWindow->actionBackgrounds, SIGNAL(toggled(bool)), this, SLOT(toggleBackgroundPalette(bool))); + connect(mBackgroundsPalette, SIGNAL(closed()), this, SLOT(backgroundPaletteClosed())); + + connect(UBApplication::mainWindow->actionPlainLightBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); + connect(UBApplication::mainWindow->actionCrossedLightBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); + connect(UBApplication::mainWindow->actionPlainDarkBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); + connect(UBApplication::mainWindow->actionCrossedDarkBackground, SIGNAL(triggered()), this, SLOT(changeBackground())); + connect(UBApplication::mainWindow->actionPodcast, SIGNAL(triggered(bool)), this, SLOT(tooglePodcastPalette(bool))); + + connect(UBApplication::mainWindow->actionAddItemToCurrentPage, SIGNAL(triggered()), this, SLOT(addItemToCurrentPage())); + connect(UBApplication::mainWindow->actionAddItemToNewPage, SIGNAL(triggered()), this, SLOT(addItemToNewPage())); + connect(UBApplication::mainWindow->actionAddItemToLibrary, SIGNAL(triggered()), this, SLOT(addItemToLibrary())); + + connect(UBApplication::mainWindow->actionEraseItems, SIGNAL(triggered()), mErasePalette, SLOT(close())); + connect(UBApplication::mainWindow->actionEraseAnnotations, SIGNAL(triggered()), mErasePalette, SLOT(close())); + connect(UBApplication::mainWindow->actionClearPage, SIGNAL(triggered()), mErasePalette, SLOT(close())); + connect(UBApplication::mainWindow->actionEraseBackground,SIGNAL(triggered()),mErasePalette,SLOT(close())); + connect(mErasePalette, SIGNAL(closed()), this, SLOT(erasePaletteClosed())); + + foreach(QWidget *widget, UBApplication::mainWindow->actionErase->associatedWidgets()) + { + QAbstractButton *button = qobject_cast(widget); + if (button) + { + connect(button, SIGNAL(pressed()), this, SLOT(erasePaletteButtonPressed())); + connect(button, SIGNAL(released()), this, SLOT(erasePaletteButtonReleased())); + } + } + + connect(UBApplication::mainWindow->actionNewPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); + connect(UBApplication::mainWindow->actionDuplicatePage, SIGNAL(triggered()), mPagePalette, SLOT(close())); + connect(UBApplication::mainWindow->actionImportPage, SIGNAL(triggered()), mPagePalette, SLOT(close())); + connect(mPagePalette, SIGNAL(closed()), this, SLOT(pagePaletteClosed())); + + foreach(QWidget *widget, UBApplication::mainWindow->actionPages->associatedWidgets()) + { + QAbstractButton *button = qobject_cast(widget); + if (button) + { + connect(button, SIGNAL(pressed()), this, SLOT(pagePaletteButtonPressed())); + connect(button, SIGNAL(released()), this, SLOT(pagePaletteButtonReleased())); + } + } + +} + + +bool isFirstResized = true; +void UBBoardPaletteManager::containerResized() +{ + int innerMargin = UBSettings::boardMargin; + + int userLeft = innerMargin; + int userWidth = mContainer->width() - (2 * innerMargin); + int userTop = innerMargin; + int userHeight = mContainer->height() - (2 * innerMargin); + + if(mStylusPalette) + { + mStylusPalette->move(userLeft, userTop); + mStylusPalette->adjustSizeAndPosition(); + mStylusPalette->initPosition(); + } + + if(mZoomPalette) + { + mZoomPalette->move(userLeft + userWidth - mZoomPalette->width() + , userTop + userHeight /*- mPageNumberPalette->height()*/ - innerMargin - mZoomPalette->height()); + mZoomPalette->adjustSizeAndPosition(); + } + + if (isFirstResized && mKeyboardPalette && mKeyboardPalette->parent() == UBApplication::boardController->controlContainer()) + { + isFirstResized = false; + mKeyboardPalette->move(userLeft + (userWidth - mKeyboardPalette->width())/2, + userTop + (userHeight - mKeyboardPalette->height())/2); + mKeyboardPalette->adjustSizeAndPosition(); + } + + if(mLeftPalette) + { + mLeftPalette->resize(mLeftPalette->width()-1, mContainer->height()); + mLeftPalette->resize(mLeftPalette->width(), mContainer->height()); + } + + if(mRightPalette) + { + mRightPalette->resize(mRightPalette->width()-1, mContainer->height()); + mRightPalette->resize(mRightPalette->width(), mContainer->height()); + } +} + + +void UBBoardPaletteManager::changeBackground() +{ + if (UBApplication::mainWindow->actionCrossedLightBackground->isChecked()) + UBApplication::boardController->changeBackground(false, true); + else if (UBApplication::mainWindow->actionPlainDarkBackground->isChecked()) + UBApplication::boardController->changeBackground(true, false); + else if (UBApplication::mainWindow->actionCrossedDarkBackground->isChecked()) + UBApplication::boardController->changeBackground(true, true); + else + UBApplication::boardController->changeBackground(false, false); + + UBApplication::mainWindow->actionBackgrounds->setChecked(false); +} + + +void UBBoardPaletteManager::activeSceneChanged() +{ + UBGraphicsScene *activeScene = UBApplication::boardController->activeScene(); + int pageIndex = UBApplication::boardController->activeSceneIndex(); + + if (mStylusPalette) + connect(mStylusPalette, SIGNAL(mouseEntered()), activeScene, SLOT(hideEraser())); + + if (mpPageNavigWidget) + { + mpPageNavigWidget->setPageNumber(UBDocumentContainer::pageFromSceneIndex(pageIndex), activeScene->document()->pageCount()); + } + + if (mZoomPalette) + connect(mZoomPalette, SIGNAL(mouseEntered()), activeScene, SLOT(hideEraser())); + + if (mBackgroundsPalette) + connect(mBackgroundsPalette, SIGNAL(mouseEntered()), activeScene, SLOT(hideEraser())); +} + + +void UBBoardPaletteManager::toggleBackgroundPalette(bool checked) +{ + mBackgroundsPalette->setVisible(checked); + + if (checked) + { + UBApplication::mainWindow->actionErase->setChecked(false); + UBApplication::mainWindow->actionNewPage->setChecked(false); + + mBackgroundsPalette->adjustSizeAndPosition(); + mBackgroundsPalette->move((mContainer->width() - mBackgroundsPalette->width()) / 2, + (mContainer->height() - mBackgroundsPalette->height()) / 5); + } +} + + +void UBBoardPaletteManager::backgroundPaletteClosed() +{ + UBApplication::mainWindow->actionBackgrounds->setChecked(false); +} + + +void UBBoardPaletteManager::toggleStylusPalette(bool checked) +{ + mStylusPalette->setVisible(checked); +} + + +void UBBoardPaletteManager::toggleErasePalette(bool checked) +{ + mErasePalette->setVisible(checked); + if (checked) + { + UBApplication::mainWindow->actionBackgrounds->setChecked(false); + UBApplication::mainWindow->actionNewPage->setChecked(false); + + mErasePalette->adjustSizeAndPosition(); + mErasePalette->move((mContainer->width() - mErasePalette->width()) / 2, + (mContainer->height() - mErasePalette->height()) / 5); + } +} + + +void UBBoardPaletteManager::erasePaletteClosed() +{ + UBApplication::mainWindow->actionErase->setChecked(false); +} + + +void UBBoardPaletteManager::togglePagePalette(bool checked) +{ + mPagePalette->setVisible(checked); + if (checked) + { + UBApplication::mainWindow->actionBackgrounds->setChecked(false); + UBApplication::mainWindow->actionErase->setChecked(false); + + mPagePalette->adjustSizeAndPosition(); + mPagePalette->move((mContainer->width() - mPagePalette->width()) / 2, + (mContainer->height() - mPagePalette->height()) / 5); + } +} + + +void UBBoardPaletteManager::pagePaletteClosed() +{ + UBApplication::mainWindow->actionPages->setChecked(false); +} + + +void UBBoardPaletteManager::tooglePodcastPalette(bool checked) +{ + UBPodcastController::instance()->toggleRecordingPalette(checked); +} + + +void UBBoardPaletteManager::addItem(const QUrl& pUrl) +{ + mItemUrl = pUrl; + mPixmap = QPixmap(); + mPos = QPointF(0, 0); + mScaleFactor = 1.; + + mAddItemPalette->show(); + mAddItemPalette->adjustSizeAndPosition(); + + mAddItemPalette->move((mContainer->width() - mAddItemPalette->width()) / 2, + (mContainer->height() - mAddItemPalette->height()) / 5); +} + +void UBBoardPaletteManager::changeMode(eUBDockPaletteWidgetMode newMode, bool isInit) +{ + bool rightPaletteVisible = mRightPalette->switchMode(newMode); + bool leftPaletteVisible = mLeftPalette->switchMode(newMode); + + switch( newMode ) + { + case eUBDockPaletteWidget_BOARD: + { + // On Application start up the mAddItemPalette isn't initialized yet + if(mAddItemPalette){ + mAddItemPalette->setParent(UBApplication::boardController->controlContainer()); + } + mLeftPalette->assignParent(mContainer); + mRightPalette->assignParent(mContainer); + mRightPalette->stackUnder(mStylusPalette); + mLeftPalette->stackUnder(mStylusPalette); + if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) + { + + if(mKeyboardPalette->m_isVisible) + { + mKeyboardPalette->hide(); + mKeyboardPalette->setParent(UBApplication::boardController->controlContainer()); + mKeyboardPalette->show(); + } + else + mKeyboardPalette->setParent(UBApplication::boardController->controlContainer()); + } + + mLeftPalette->setVisible(leftPaletteVisible); + mRightPalette->setVisible(rightPaletteVisible); +#ifdef Q_WS_WIN + if (rightPaletteVisible) + mRightPalette->setAdditionalVOffset(0); +#endif + + if( !isInit ) + containerResized(); + if (mWebToolsCurrentPalette) + mWebToolsCurrentPalette->hide(); + } + break; + + case eUBDockPaletteWidget_DESKTOP: + { + mAddItemPalette->setParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); + mLeftPalette->assignParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); + mRightPalette->assignParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); + mStylusPalette->raise(); + + if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) + { + + if(mKeyboardPalette->m_isVisible) + { + mKeyboardPalette->hide(); +#ifndef Q_WS_X11 + mKeyboardPalette->setParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); +#else + mKeyboardPalette->setParent(0); +#endif +#ifdef Q_WS_MAC + mKeyboardPalette->setWindowFlags(Qt::Dialog | Qt::Popup | Qt::FramelessWindowHint); +#endif + mKeyboardPalette->show(); + } + else +// In linux keyboard in desktop mode have to allways be with null parent +#ifdef Q_WS_X11 + mKeyboardPalette->setParent(0); +#else + mKeyboardPalette->setParent((QWidget*)UBApplication::applicationController->uninotesController()->drawingView()); +#endif //Q_WS_X11 +#ifdef Q_WS_MAC + mKeyboardPalette->setWindowFlags(Qt::Dialog | Qt::Popup | Qt::FramelessWindowHint); +#endif + + } + + mLeftPalette->setVisible(leftPaletteVisible); + mRightPalette->setVisible(rightPaletteVisible); +#ifdef Q_WS_WIN + if (rightPaletteVisible && UBSettings::settings()->appToolBarPositionedAtTop->get().toBool()) + mRightPalette->setAdditionalVOffset(30); +#endif + + if(!isInit) + UBApplication::applicationController->uninotesController()->TransparentWidgetResized(); + + if (mWebToolsCurrentPalette) + mWebToolsCurrentPalette->hide(); + } + break; + + case eUBDockPaletteWidget_WEB: + { + mAddItemPalette->setParent(UBApplication::mainWindow); + if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) + { +// tmp variable? +// WBBrowserWindow* brWnd = UBApplication::webController->GetCurrentWebBrowser(); + + if(mKeyboardPalette->m_isVisible) + { + mKeyboardPalette->hide(); + mKeyboardPalette->setParent(UBApplication::mainWindow); + mKeyboardPalette->show(); + } + else + mKeyboardPalette->setParent(UBApplication::mainWindow); + } + + } + break; + + case eUBDockPaletteWidget_DOCUMENT: + { + mLeftPalette->setVisible(leftPaletteVisible); + mRightPalette->setVisible(rightPaletteVisible); + mLeftPalette->assignParent(UBApplication::documentController->controlView()); + mRightPalette->assignParent(UBApplication::documentController->controlView()); + if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) + { + + if(mKeyboardPalette->m_isVisible) + { + mKeyboardPalette->hide(); + mKeyboardPalette->setParent(UBApplication::documentController->controlView()); + mKeyboardPalette->show(); + } + else + mKeyboardPalette->setParent(UBApplication::documentController->controlView()); + } + if (mWebToolsCurrentPalette) + mWebToolsCurrentPalette->hide(); + } + break; + + default: + { + mLeftPalette->setVisible(leftPaletteVisible); + mRightPalette->setVisible(rightPaletteVisible); + mLeftPalette->assignParent(0); + mRightPalette->assignParent(0); + if (UBPlatformUtils::hasVirtualKeyboard() && mKeyboardPalette != NULL) + { + + if(mKeyboardPalette->m_isVisible) + { + mKeyboardPalette->hide(); + mKeyboardPalette->setParent(0); + mKeyboardPalette->show(); + } + else + mKeyboardPalette->setParent(0); + } + } + break; + } + + if( !isInit ) + UBApplication::boardController->notifyPageChanged(); + + emit signal_changeMode(newMode); +} + +void UBBoardPaletteManager::addItem(const QPixmap& pPixmap, const QPointF& pos, qreal scaleFactor, const QUrl& sourceUrl) +{ + mItemUrl = sourceUrl; + mPixmap = pPixmap; + mPos = pos; + mScaleFactor = scaleFactor; + + mAddItemPalette->show(); + mAddItemPalette->adjustSizeAndPosition(); + + mAddItemPalette->move((mContainer->width() - mAddItemPalette->width()) / 2, + (mContainer->height() - mAddItemPalette->height()) / 5); +} + + +void UBBoardPaletteManager::addItemToCurrentPage() +{ + UBApplication::applicationController->showBoard(); + mAddItemPalette->hide(); + if(mPixmap.isNull()) + UBApplication::boardController->downloadURL(mItemUrl); + else + { + UBGraphicsPixmapItem* item = UBApplication::boardController->activeScene()->addPixmap(mPixmap, NULL, mPos, mScaleFactor); + + item->setSourceUrl(mItemUrl); + item->setSelected(true); + + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } +} + + +void UBBoardPaletteManager::addItemToNewPage() +{ + UBApplication::boardController->addScene(); + addItemToCurrentPage(); +} + + +void UBBoardPaletteManager::addItemToLibrary() +{ + if(mPixmap.isNull()) + { + mPixmap = QPixmap(mItemUrl.toLocalFile()); + } + + if(!mPixmap.isNull()) + { + if(mScaleFactor != 1.) + { + mPixmap = mPixmap.scaled(mScaleFactor * mPixmap.width(), mScaleFactor* mPixmap.height() + , Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + QImage image = mPixmap.toImage(); + + QDateTime now = QDateTime::currentDateTime(); + QString capturedName = tr("CapturedImage") + "-" + now.toString("dd-MM-yyyy hh-mm-ss") + ".png"; + mpFeaturesWidget->importImage(image, capturedName); + } + else + { + UBApplication::showMessage(tr("Error Adding Image to Library")); + } + + mAddItemPalette->hide(); +} + +void UBBoardPaletteManager::zoomButtonPressed() +{ + mZoomButtonPressedTime = QTime::currentTime(); + + mPendingZoomButtonPressed = true; + QTimer::singleShot(1000, this, SLOT(zoomButtonReleased())); +} + + +void UBBoardPaletteManager::zoomButtonReleased() +{ + if (mPendingZoomButtonPressed) + { + if(mZoomButtonPressedTime.msecsTo(QTime::currentTime()) > 900) + { + mBoardControler->zoomRestore(); + } + + mPendingZoomButtonPressed = false; + } +} + +void UBBoardPaletteManager::panButtonPressed() +{ + mPanButtonPressedTime = QTime::currentTime(); + + mPendingPanButtonPressed = true; + QTimer::singleShot(1000, this, SLOT(panButtonReleased())); +} + + +void UBBoardPaletteManager::panButtonReleased() +{ + if (mPendingPanButtonPressed) + { + if(mPanButtonPressedTime.msecsTo(QTime::currentTime()) > 900) + { + mBoardControler->centerRestore(); + } + + mPendingPanButtonPressed = false; + } +} + +void UBBoardPaletteManager::showVirtualKeyboard(bool show) +{ + if (mKeyboardPalette) + mKeyboardPalette->setVisible(show); +} + +void UBBoardPaletteManager::changeStylusPaletteOrientation(QVariant var) +{ + bool bVertical = var.toBool(); + bool bVisible = mStylusPalette->isVisible(); + + // Clean the old palette + if(NULL != mStylusPalette) + { + delete mStylusPalette; + mStylusPalette = NULL; + } + + // Create the new palette + if(bVertical) + { + mStylusPalette = new UBStylusPalette(mContainer, Qt::Vertical); + } + else + { + mStylusPalette = new UBStylusPalette(mContainer, Qt::Horizontal); + } + + connect(mStylusPalette, SIGNAL(stylusToolDoubleClicked(int)), UBApplication::boardController, SLOT(stylusToolDoubleClicked(int))); + mStylusPalette->setVisible(bVisible); // always show stylus palette at startup +} + + +void UBBoardPaletteManager::connectToDocumentController() +{ + emit connectToDocController(); +} + +void UBBoardPaletteManager::refreshPalettes() +{ + mRightPalette->update(); + mLeftPalette->update(); +} + +void UBBoardPaletteManager::startDownloads() +{ + if(!mDownloadInProgress) + { + mDownloadInProgress = true; + mpDownloadWidget->setVisibleState(true); + mRightPalette->addTab(mpDownloadWidget); + } +} + +void UBBoardPaletteManager::stopDownloads() +{ + if(mDownloadInProgress) + { + mDownloadInProgress = false; + mpDownloadWidget->setVisibleState(false); + mRightPalette->removeTab(mpDownloadWidget); + } +} diff --git a/src/board/UBBoardPaletteManager.h b/src/board/UBBoardPaletteManager.h index cb38459f..7526e081 100644 --- a/src/board/UBBoardPaletteManager.h +++ b/src/board/UBBoardPaletteManager.h @@ -19,173 +19,173 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBBOARDPALETTEMANAGER_H_ -#define UBBOARDPALETTEMANAGER_H_ - -#include -#include - -#include "gui/UBLeftPalette.h" -#include "gui/UBRightPalette.h" -#include "gui/UBPageNavigationWidget.h" -#include "gui/UBCachePropertiesWidget.h" -#include "gui/UBDockDownloadWidget.h" -#include "core/UBApplicationController.h" -#include "gui/UBFeaturesWidget.h" - - -class UBWebToolsPalette; -class UBStylusPalette; -class UBClockPalette; -class UBPageNumberPalette; -class UBZoomPalette; -class UBActionPalette; -class UBBoardController; -class UBServerXMLHttpRequest; -class UBKeyboardPalette; -class UBMainWindow; -class UBApplicationController; -class UBDockTeacherGuideWidget; - -class UBBoardPaletteManager : public QObject -{ - Q_OBJECT - - public: - UBBoardPaletteManager(QWidget* container, UBBoardController* controller); - virtual ~UBBoardPaletteManager(); - - void setupLayout(); - UBLeftPalette* leftPalette(){return mLeftPalette;} - UBRightPalette* rightPalette(){return mRightPalette;} - UBStylusPalette* stylusPalette(){return mStylusPalette;} - UBActionPalette *addItemPalette() {return mAddItemPalette;} - void showVirtualKeyboard(bool show = true); - void initPalettesPosAtStartup(); - void connectToDocumentController(); - void refreshPalettes(); - - UBKeyboardPalette *mKeyboardPalette; - - void setCurrentWebToolsPalette(UBWebToolsPalette *palette) {mWebToolsCurrentPalette = palette;} - UBWebToolsPalette* mWebToolsCurrentPalette; - - UBDockTeacherGuideWidget* teacherGuideDockWidget() { return mpTeacherGuideWidget;} - - void processPalettersWidget(UBDockPalette *paletter, eUBDockPaletteWidgetMode mode); - void changeMode(eUBDockPaletteWidgetMode newMode, bool isInit = false); - void startDownloads(); - void stopDownloads(); - - signals: - void connectToDocController(); - void signal_changeMode(eUBDockPaletteWidgetMode newMode); - - public slots: - - void activeSceneChanged(); - void containerResized(); - void addItem(const QUrl& pUrl); - void addItem(const QPixmap& pPixmap, const QPointF& p = QPointF(0.0, 0.0), qreal scale = 1.0, const QUrl& sourceUrl = QUrl()); - - void slot_changeMainMode(UBApplicationController::MainMode); - void slot_changeDesktopMode(bool); - - void toggleErasePalette(bool ckecked); - - private: - - void setupPalettes(); - void connectPalettes(); - void positionFreeDisplayPalette(); - void setupDockPaletteWidgets(); - - QWidget* mContainer; - UBBoardController *mBoardControler; - - UBStylusPalette *mStylusPalette; - - UBZoomPalette *mZoomPalette; - - /** The left dock palette */ - UBLeftPalette* mLeftPalette; - /** The right dock palette */ - UBRightPalette* mRightPalette; - - UBActionPalette *mBackgroundsPalette; - UBActionPalette *mToolsPalette; - UBActionPalette* mAddItemPalette; - UBActionPalette* mErasePalette; - UBActionPalette* mPagePalette; - - QUrl mItemUrl; - QPixmap mPixmap; - QPointF mPos; - qreal mScaleFactor; - - QTime mPageButtonPressedTime; - bool mPendingPageButtonPressed; - - QTime mZoomButtonPressedTime; - bool mPendingZoomButtonPressed; - - QTime mPanButtonPressedTime; - bool mPendingPanButtonPressed; - - QTime mEraseButtonPressedTime; - bool mPendingEraseButtonPressed; - - /** The page navigator widget */ - UBPageNavigationWidget* mpPageNavigWidget; - - /** The cache properties widget */ - UBCachePropertiesWidget* mpCachePropWidget; - - UBFeaturesWidget *mpFeaturesWidget; - - /** The download widget */ - UBDockDownloadWidget* mpDownloadWidget; - UBDockTeacherGuideWidget* mpTeacherGuideWidget; - - bool mDownloadInProgress; - - private slots: - - void changeBackground(); - - void toggleBackgroundPalette(bool checked); - void backgroundPaletteClosed(); - - void toggleStylusPalette(bool checked); - void tooglePodcastPalette(bool checked); - - void erasePaletteButtonPressed(); - void erasePaletteButtonReleased(); - - void erasePaletteClosed(); - - void togglePagePalette(bool ckecked); - void pagePaletteClosed(); - - void pagePaletteButtonPressed(); - void pagePaletteButtonReleased(); - - void addItemToCurrentPage(); - void addItemToNewPage(); - void addItemToLibrary(); - - void purchaseLinkActivated(const QString&); - - void linkClicked(const QUrl& url); - - void zoomButtonPressed(); - void zoomButtonReleased(); - void panButtonPressed(); - void panButtonReleased(); - - void changeStylusPaletteOrientation(QVariant var); -}; - -#endif /* UBBOARDPALETTEMANAGER_H_ */ + + +#ifndef UBBOARDPALETTEMANAGER_H_ +#define UBBOARDPALETTEMANAGER_H_ + +#include +#include + +#include "gui/UBLeftPalette.h" +#include "gui/UBRightPalette.h" +#include "gui/UBPageNavigationWidget.h" +#include "gui/UBCachePropertiesWidget.h" +#include "gui/UBDockDownloadWidget.h" +#include "core/UBApplicationController.h" +#include "gui/UBFeaturesWidget.h" + + +class UBWebToolsPalette; +class UBStylusPalette; +class UBClockPalette; +class UBPageNumberPalette; +class UBZoomPalette; +class UBActionPalette; +class UBBoardController; +class UBServerXMLHttpRequest; +class UBKeyboardPalette; +class UBMainWindow; +class UBApplicationController; +class UBDockTeacherGuideWidget; + +class UBBoardPaletteManager : public QObject +{ + Q_OBJECT + + public: + UBBoardPaletteManager(QWidget* container, UBBoardController* controller); + virtual ~UBBoardPaletteManager(); + + void setupLayout(); + UBLeftPalette* leftPalette(){return mLeftPalette;} + UBRightPalette* rightPalette(){return mRightPalette;} + UBStylusPalette* stylusPalette(){return mStylusPalette;} + UBActionPalette *addItemPalette() {return mAddItemPalette;} + void showVirtualKeyboard(bool show = true); + void initPalettesPosAtStartup(); + void connectToDocumentController(); + void refreshPalettes(); + + UBKeyboardPalette *mKeyboardPalette; + + void setCurrentWebToolsPalette(UBWebToolsPalette *palette) {mWebToolsCurrentPalette = palette;} + UBWebToolsPalette* mWebToolsCurrentPalette; + + UBDockTeacherGuideWidget* teacherGuideDockWidget() { return mpTeacherGuideWidget;} + + void processPalettersWidget(UBDockPalette *paletter, eUBDockPaletteWidgetMode mode); + void changeMode(eUBDockPaletteWidgetMode newMode, bool isInit = false); + void startDownloads(); + void stopDownloads(); + + signals: + void connectToDocController(); + void signal_changeMode(eUBDockPaletteWidgetMode newMode); + + public slots: + + void activeSceneChanged(); + void containerResized(); + void addItem(const QUrl& pUrl); + void addItem(const QPixmap& pPixmap, const QPointF& p = QPointF(0.0, 0.0), qreal scale = 1.0, const QUrl& sourceUrl = QUrl()); + + void slot_changeMainMode(UBApplicationController::MainMode); + void slot_changeDesktopMode(bool); + + void toggleErasePalette(bool ckecked); + + private: + + void setupPalettes(); + void connectPalettes(); + void positionFreeDisplayPalette(); + void setupDockPaletteWidgets(); + + QWidget* mContainer; + UBBoardController *mBoardControler; + + UBStylusPalette *mStylusPalette; + + UBZoomPalette *mZoomPalette; + + /** The left dock palette */ + UBLeftPalette* mLeftPalette; + /** The right dock palette */ + UBRightPalette* mRightPalette; + + UBActionPalette *mBackgroundsPalette; + UBActionPalette *mToolsPalette; + UBActionPalette* mAddItemPalette; + UBActionPalette* mErasePalette; + UBActionPalette* mPagePalette; + + QUrl mItemUrl; + QPixmap mPixmap; + QPointF mPos; + qreal mScaleFactor; + + QTime mPageButtonPressedTime; + bool mPendingPageButtonPressed; + + QTime mZoomButtonPressedTime; + bool mPendingZoomButtonPressed; + + QTime mPanButtonPressedTime; + bool mPendingPanButtonPressed; + + QTime mEraseButtonPressedTime; + bool mPendingEraseButtonPressed; + + /** The page navigator widget */ + UBPageNavigationWidget* mpPageNavigWidget; + + /** The cache properties widget */ + UBCachePropertiesWidget* mpCachePropWidget; + + UBFeaturesWidget *mpFeaturesWidget; + + /** The download widget */ + UBDockDownloadWidget* mpDownloadWidget; + UBDockTeacherGuideWidget* mpTeacherGuideWidget; + + bool mDownloadInProgress; + + private slots: + + void changeBackground(); + + void toggleBackgroundPalette(bool checked); + void backgroundPaletteClosed(); + + void toggleStylusPalette(bool checked); + void tooglePodcastPalette(bool checked); + + void erasePaletteButtonPressed(); + void erasePaletteButtonReleased(); + + void erasePaletteClosed(); + + void togglePagePalette(bool ckecked); + void pagePaletteClosed(); + + void pagePaletteButtonPressed(); + void pagePaletteButtonReleased(); + + void addItemToCurrentPage(); + void addItemToNewPage(); + void addItemToLibrary(); + + void purchaseLinkActivated(const QString&); + + void linkClicked(const QUrl& url); + + void zoomButtonPressed(); + void zoomButtonReleased(); + void panButtonPressed(); + void panButtonReleased(); + + void changeStylusPaletteOrientation(QVariant var); +}; + +#endif /* UBBOARDPALETTEMANAGER_H_ */ diff --git a/src/board/UBBoardView.h b/src/board/UBBoardView.h index 01ee8ad9..fe709991 100644 --- a/src/board/UBBoardView.h +++ b/src/board/UBBoardView.h @@ -19,164 +19,164 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBBOARDVIEW_H_ -#define UBBOARDVIEW_H_ - -#include -#include "core/UB.h" -#include "domain/UBGraphicsDelegateFrame.h" - -class UBBoardController; -class UBGraphicsScene; -class UBGraphicsWidgetItem; -class UBRubberBand; - -class UBBoardView : public QGraphicsView -{ - Q_OBJECT - - public: - - UBBoardView(UBBoardController* pController, QWidget* pParent = 0, bool isControl = false, bool isDesktop = false); - UBBoardView(UBBoardController* pController, int pStartLayer, int pEndLayer, QWidget* pParent = 0, bool isControl = false, bool isDesktop = false); - virtual ~UBBoardView(); - - UBGraphicsScene* scene(); - - void forcedTabletRelease(); - - void setToolCursor(int tool); - - void rubberItems(); - void moveRubberedItems(QPointF movingVector); - - void setMultiselection(bool enable); - bool isMultipleSelectionEnabled() { return mMultipleSelectionIsEnabled; } - - signals: - - void resized(QResizeEvent* event); - void hidden(); - void shown(); - void clickOnBoard(); - - protected: - - bool itemIsLocked(QGraphicsItem *item); - bool isUBItem(QGraphicsItem *item); // we should to determine items who is not UB and use general scene behavior for them. - bool isCppTool(QGraphicsItem *item); - void handleItemsSelection(QGraphicsItem *item); - bool itemShouldReceiveMousePressEvent(QGraphicsItem *item); - bool itemShouldReceiveSuspendedMousePressEvent(QGraphicsItem *item); - bool itemHaveParentWithType(QGraphicsItem *item, int type); - bool itemShouldBeMoved(QGraphicsItem *item); - QGraphicsItem* determineItemToPress(QGraphicsItem *item); - QGraphicsItem* determineItemToMove(QGraphicsItem *item); - void handleItemMousePress(QMouseEvent *event); - void handleItemMouseMove(QMouseEvent *event); - - virtual bool event (QEvent * e); - - virtual void keyPressEvent(QKeyEvent *event); - virtual void keyReleaseEvent(QKeyEvent *event); - virtual void tabletEvent(QTabletEvent * event); - virtual void mouseDoubleClickEvent(QMouseEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void wheelEvent(QWheelEvent *event); - virtual void leaveEvent ( QEvent * event); - - virtual void focusOutEvent ( QFocusEvent * event ); - - virtual void drawItems(QPainter *painter, int numItems, - QGraphicsItem *items[], - const QStyleOptionGraphicsItem options[]); - -// virtual void dragEnterEvent(QDragEnterEvent * event); - virtual void dropEvent(QDropEvent *event); - virtual void dragMoveEvent(QDragMoveEvent *event); - - virtual void resizeEvent(QResizeEvent * event); - - virtual void drawBackground(QPainter *painter, const QRectF &rect); - - virtual void showEvent(QShowEvent * event); - virtual void hideEvent(QHideEvent * event); - - private: - - void init(); - - inline bool shouldDisplayItem(QGraphicsItem *item) - { - bool ok; - int itemLayerType = item->data(UBGraphicsItemData::ItemLayerType).toInt(&ok); - return (ok && (itemLayerType >= mStartLayer && itemLayerType <= mEndLayer)); - } - - QList processMimeData(const QMimeData* pMimeData); - - UBBoardController* mController; - - int mStartLayer, mEndLayer; - bool mFilterZIndex; - - bool mTabletStylusIsPressed; - bool mUsingTabletEraser; - - bool mPendingStylusReleaseEvent; - - bool mMouseButtonIsPressed; - QPointF mPreviousPoint; - QPoint mMouseDownPos; - - bool mPenPressureSensitive; - bool mMarkerPressureSensitive; - bool mUseHighResTabletEvent; - - QRubberBand *mRubberBand; - bool mIsCreatingTextZone; - bool mIsCreatingSceneGrabZone; - - bool isAbsurdPoint(QPoint point); - - bool mVirtualKeyboardActive; - bool mOkOnWidget; - - bool mWidgetMoved; - QPointF mLastPressedMousePos; - QGraphicsItem *movingItem; - QMouseEvent *suspendedMousePressEvent; - - bool moveRubberBand; - UBRubberBand *mUBRubberBand; - - QList mRubberedItems; - QSet mJustSelectedItems; - - int mLongPressInterval; - QTimer mLongPressTimer; - - bool mIsDragInProgress; - bool mMultipleSelectionIsEnabled; - bool bIsControl; - bool bIsDesktop; - bool mRubberBandInPlayMode; - - static bool hasSelectedParents(QGraphicsItem * item); - - private slots: - - void settingChanged(QVariant newValue); - - public slots: - - void virtualKeyboardActivated(bool b); - void longPressEvent(); - -}; - -#endif /* UBBOARDVIEW_H_ */ + + +#ifndef UBBOARDVIEW_H_ +#define UBBOARDVIEW_H_ + +#include +#include "core/UB.h" +#include "domain/UBGraphicsDelegateFrame.h" + +class UBBoardController; +class UBGraphicsScene; +class UBGraphicsWidgetItem; +class UBRubberBand; + +class UBBoardView : public QGraphicsView +{ + Q_OBJECT + + public: + + UBBoardView(UBBoardController* pController, QWidget* pParent = 0, bool isControl = false, bool isDesktop = false); + UBBoardView(UBBoardController* pController, int pStartLayer, int pEndLayer, QWidget* pParent = 0, bool isControl = false, bool isDesktop = false); + virtual ~UBBoardView(); + + UBGraphicsScene* scene(); + + void forcedTabletRelease(); + + void setToolCursor(int tool); + + void rubberItems(); + void moveRubberedItems(QPointF movingVector); + + void setMultiselection(bool enable); + bool isMultipleSelectionEnabled() { return mMultipleSelectionIsEnabled; } + + signals: + + void resized(QResizeEvent* event); + void hidden(); + void shown(); + void clickOnBoard(); + + protected: + + bool itemIsLocked(QGraphicsItem *item); + bool isUBItem(QGraphicsItem *item); // we should to determine items who is not UB and use general scene behavior for them. + bool isCppTool(QGraphicsItem *item); + void handleItemsSelection(QGraphicsItem *item); + bool itemShouldReceiveMousePressEvent(QGraphicsItem *item); + bool itemShouldReceiveSuspendedMousePressEvent(QGraphicsItem *item); + bool itemHaveParentWithType(QGraphicsItem *item, int type); + bool itemShouldBeMoved(QGraphicsItem *item); + QGraphicsItem* determineItemToPress(QGraphicsItem *item); + QGraphicsItem* determineItemToMove(QGraphicsItem *item); + void handleItemMousePress(QMouseEvent *event); + void handleItemMouseMove(QMouseEvent *event); + + virtual bool event (QEvent * e); + + virtual void keyPressEvent(QKeyEvent *event); + virtual void keyReleaseEvent(QKeyEvent *event); + virtual void tabletEvent(QTabletEvent * event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + virtual void leaveEvent ( QEvent * event); + + virtual void focusOutEvent ( QFocusEvent * event ); + + virtual void drawItems(QPainter *painter, int numItems, + QGraphicsItem *items[], + const QStyleOptionGraphicsItem options[]); + +// virtual void dragEnterEvent(QDragEnterEvent * event); + virtual void dropEvent(QDropEvent *event); + virtual void dragMoveEvent(QDragMoveEvent *event); + + virtual void resizeEvent(QResizeEvent * event); + + virtual void drawBackground(QPainter *painter, const QRectF &rect); + + virtual void showEvent(QShowEvent * event); + virtual void hideEvent(QHideEvent * event); + + private: + + void init(); + + inline bool shouldDisplayItem(QGraphicsItem *item) + { + bool ok; + int itemLayerType = item->data(UBGraphicsItemData::ItemLayerType).toInt(&ok); + return (ok && (itemLayerType >= mStartLayer && itemLayerType <= mEndLayer)); + } + + QList processMimeData(const QMimeData* pMimeData); + + UBBoardController* mController; + + int mStartLayer, mEndLayer; + bool mFilterZIndex; + + bool mTabletStylusIsPressed; + bool mUsingTabletEraser; + + bool mPendingStylusReleaseEvent; + + bool mMouseButtonIsPressed; + QPointF mPreviousPoint; + QPoint mMouseDownPos; + + bool mPenPressureSensitive; + bool mMarkerPressureSensitive; + bool mUseHighResTabletEvent; + + QRubberBand *mRubberBand; + bool mIsCreatingTextZone; + bool mIsCreatingSceneGrabZone; + + bool isAbsurdPoint(QPoint point); + + bool mVirtualKeyboardActive; + bool mOkOnWidget; + + bool mWidgetMoved; + QPointF mLastPressedMousePos; + QGraphicsItem *movingItem; + QMouseEvent *suspendedMousePressEvent; + + bool moveRubberBand; + UBRubberBand *mUBRubberBand; + + QList mRubberedItems; + QSet mJustSelectedItems; + + int mLongPressInterval; + QTimer mLongPressTimer; + + bool mIsDragInProgress; + bool mMultipleSelectionIsEnabled; + bool bIsControl; + bool bIsDesktop; + bool mRubberBandInPlayMode; + + static bool hasSelectedParents(QGraphicsItem * item); + + private slots: + + void settingChanged(QVariant newValue); + + public slots: + + void virtualKeyboardActivated(bool b); + void longPressEvent(); + +}; + +#endif /* UBBOARDVIEW_H_ */ diff --git a/src/core/UBApplication.h b/src/core/UBApplication.h index b98fe9ce..b3d6aa27 100644 --- a/src/core/UBApplication.h +++ b/src/core/UBApplication.h @@ -19,155 +19,155 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBAPPLICATION_H_ -#define UBAPPLICATION_H_ - -#include - -#include "qtsingleapplication.h" - -#include "transition/UniboardSankoreTransition.h" - -namespace Ui -{ - class MainWindow; -} - - -class UBBoardController; -class UBWebController; -class UBControlView; -class UBPreferencesController; -class UBResources; -class UBSettings; -class UBPersistenceManager; -class UBApplicationController; -class UBDocumentController; -class UBMainWindow; - -class UBApplication : public QtSingleApplication -{ - Q_OBJECT; - - public: - - UBApplication(const QString &id, int &argc, char **argv); - virtual ~UBApplication(); - - int exec(const QString& pFileToImport); - - void cleanup(); - - static QPointer undoStack; - - static UBApplicationController *applicationController; - static UBBoardController* boardController; - static UBWebController* webController; - static UBDocumentController* documentController; - static UniboardSankoreTransition* mUniboardSankoreTransition; - - static UBMainWindow* mainWindow; - - static UBApplication* app() - { - return static_castqApp; - } - - static const QString mimeTypeUniboardDocument; - static const QString mimeTypeUniboardPage; - static const QString mimeTypeUniboardPageItem; - static const QString mimeTypeUniboardPageThumbnail; - - static void showMessage(const QString& message, bool showSpinningWheel = false); - static void setDisabled(bool disable); - - static QObject* staticMemoryCleaner; - - void decorateActionMenu(QAction* action); - void insertSpaceToToolbarBeforeAction(QToolBar* toolbar, QAction* action, int width = -1); - - int toolBarHeight(); - bool eventFilter(QObject *obj, QEvent *event); - - bool isVerbose() { return mIsVerbose;} - void setVerbose(bool verbose){mIsVerbose = verbose;} - static QString urlFromHtml(QString html); - static bool isFromWeb(QString url); - - signals: - - public slots: - - void showBoard(); - void showInternet(); - void showDocument(); - void startScript(); - void stopScript(); - - void toolBarPositionChanged(QVariant topOrBottom); - void toolBarDisplayTextChanged(QVariant display); - - void closeEvent(QCloseEvent *event); - - /** - * Used on Windows platform to open file in running application. On MacOS X opening file is done through the - * FileOpen event that is handle in eventFilter method. - */ - bool handleOpenMessage(const QString& pMessage); - - private slots: - - void closing(); -#ifdef Q_WS_MAC - void showMinimized(); -#endif - void importUniboardFiles(); - - void onScreenCountChanged(int newCount); - - private: - void updateProtoActionsState(); - void setupTranslators(QStringList args); - QList mProtoMenus; - bool mIsVerbose; - QString checkLanguageAvailabilityForSankore(QString& language); - protected: - -#if defined(Q_WS_MACX) && !defined(QT_MAC_USE_COCOA) - bool macEventFilter(EventHandlerCallRef caller, EventRef event); -#endif - - UBPreferencesController* mPreferencesController; - QTranslator* mApplicationTranslator; - QTranslator* mQtGuiTranslator; - -}; - - -class UBStyle : public QPlastiqueStyle -{ - public: - - UBStyle() - : QPlastiqueStyle() - { - // NOOP - } - - virtual ~UBStyle() - { - // NOOP - } - - /* - * redefined to be more cocoa like on texts - */ - virtual void drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal, - bool enabled, const QString& text, QPalette::ColorRole textRole) const; - - -}; - -#endif /* UBAPPLICATION_H_ */ + + +#ifndef UBAPPLICATION_H_ +#define UBAPPLICATION_H_ + +#include + +#include "qtsingleapplication.h" + +#include "transition/UniboardSankoreTransition.h" + +namespace Ui +{ + class MainWindow; +} + + +class UBBoardController; +class UBWebController; +class UBControlView; +class UBPreferencesController; +class UBResources; +class UBSettings; +class UBPersistenceManager; +class UBApplicationController; +class UBDocumentController; +class UBMainWindow; + +class UBApplication : public QtSingleApplication +{ + Q_OBJECT; + + public: + + UBApplication(const QString &id, int &argc, char **argv); + virtual ~UBApplication(); + + int exec(const QString& pFileToImport); + + void cleanup(); + + static QPointer undoStack; + + static UBApplicationController *applicationController; + static UBBoardController* boardController; + static UBWebController* webController; + static UBDocumentController* documentController; + static UniboardSankoreTransition* mUniboardSankoreTransition; + + static UBMainWindow* mainWindow; + + static UBApplication* app() + { + return static_castqApp; + } + + static const QString mimeTypeUniboardDocument; + static const QString mimeTypeUniboardPage; + static const QString mimeTypeUniboardPageItem; + static const QString mimeTypeUniboardPageThumbnail; + + static void showMessage(const QString& message, bool showSpinningWheel = false); + static void setDisabled(bool disable); + + static QObject* staticMemoryCleaner; + + void decorateActionMenu(QAction* action); + void insertSpaceToToolbarBeforeAction(QToolBar* toolbar, QAction* action, int width = -1); + + int toolBarHeight(); + bool eventFilter(QObject *obj, QEvent *event); + + bool isVerbose() { return mIsVerbose;} + void setVerbose(bool verbose){mIsVerbose = verbose;} + static QString urlFromHtml(QString html); + static bool isFromWeb(QString url); + + signals: + + public slots: + + void showBoard(); + void showInternet(); + void showDocument(); + void startScript(); + void stopScript(); + + void toolBarPositionChanged(QVariant topOrBottom); + void toolBarDisplayTextChanged(QVariant display); + + void closeEvent(QCloseEvent *event); + + /** + * Used on Windows platform to open file in running application. On MacOS X opening file is done through the + * FileOpen event that is handle in eventFilter method. + */ + bool handleOpenMessage(const QString& pMessage); + + private slots: + + void closing(); +#ifdef Q_WS_MAC + void showMinimized(); +#endif + void importUniboardFiles(); + + void onScreenCountChanged(int newCount); + + private: + void updateProtoActionsState(); + void setupTranslators(QStringList args); + QList mProtoMenus; + bool mIsVerbose; + QString checkLanguageAvailabilityForSankore(QString& language); + protected: + +#if defined(Q_WS_MACX) && !defined(QT_MAC_USE_COCOA) + bool macEventFilter(EventHandlerCallRef caller, EventRef event); +#endif + + UBPreferencesController* mPreferencesController; + QTranslator* mApplicationTranslator; + QTranslator* mQtGuiTranslator; + +}; + + +class UBStyle : public QPlastiqueStyle +{ + public: + + UBStyle() + : QPlastiqueStyle() + { + // NOOP + } + + virtual ~UBStyle() + { + // NOOP + } + + /* + * redefined to be more cocoa like on texts + */ + virtual void drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal, + bool enabled, const QString& text, QPalette::ColorRole textRole) const; + + +}; + +#endif /* UBAPPLICATION_H_ */ diff --git a/src/core/UBApplicationController.cpp b/src/core/UBApplicationController.cpp index 865fca76..3922a385 100644 --- a/src/core/UBApplicationController.cpp +++ b/src/core/UBApplicationController.cpp @@ -19,820 +19,820 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBApplicationController.h" - -#include "frameworks/UBPlatformUtils.h" -#include "frameworks/UBVersion.h" - -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBSettings.h" -#include "core/UBSetting.h" -#include "core/UBDocumentManager.h" -#include "core/UBDisplayManager.h" - -#include "board/UBBoardView.h" -#include "board/UBBoardController.h" -#include "board/UBBoardPaletteManager.h" -#include "board/UBDrawingController.h" - - -#include "document/UBDocumentProxy.h" -#include "document/UBDocumentController.h" - -#include "domain/UBGraphicsWidgetItem.h" - -#include "desktop/UBDesktopPalette.h" -#include "desktop/UBDesktopAnnotationController.h" - -#include "web/UBWebController.h" - -#include "gui/UBScreenMirror.h" -#include "gui/UBMainWindow.h" -#include "gui/UBDockTeacherGuideWidget.h" -#include "gui/UBTeacherGuideWidget.h" - -#include "domain/UBGraphicsPixmapItem.h" - -#include "podcast/UBPodcastController.h" - -#include "network/UBNetworkAccessManager.h" - -#include "ui_mainWindow.h" - -#ifdef Q_WS_MAC -#include -#endif - -#include "core/memcheck.h" - -UBApplicationController::UBApplicationController(UBBoardView *pControlView, - UBBoardView *pDisplayView, - UBMainWindow* pMainWindow, - QObject* parent, - UBRightPalette* rightPalette) - : QObject(parent) - , mMainWindow(pMainWindow) - , mControlView(pControlView) - , mDisplayView(pDisplayView) - , mMirror(0) - , mMainMode(Board) - , mDisplayManager(0) - , mAutomaticCheckForUpdates(false) - , mCheckingForUpdates(false) - , mIsShowingDesktop(false) - , mHttp(0) -{ - mDisplayManager = new UBDisplayManager(this); - - mUninoteController = new UBDesktopAnnotationController(this, rightPalette); - - connect(mDisplayManager, SIGNAL(screenLayoutChanged()), this, SLOT(screenLayoutChanged())); - connect(mDisplayManager, SIGNAL(screenLayoutChanged()), mUninoteController, SLOT(screenLayoutChanged())); - connect(mDisplayManager, SIGNAL(screenLayoutChanged()), UBApplication::webController, SLOT(screenLayoutChanged())); - - connect(mUninoteController, SIGNAL(imageCaptured(const QPixmap &, bool)), this, SLOT(addCapturedPixmap(const QPixmap &, bool))); - connect(mUninoteController, SIGNAL(restoreUniboard()), this, SLOT(hideDesktop())); - - for(int i = 0; i < mDisplayManager->numPreviousViews(); i++) - { - UBBoardView *previousView = new UBBoardView(UBApplication::boardController, UBItemLayerType::FixedBackground, UBItemLayerType::Tool, 0); - previousView->setInteractive(false); - mPreviousViews.append(previousView); - } - - mBlackScene = new UBGraphicsScene(0); // deleted by UBApplicationController::destructor - mBlackScene->setBackground(true, false); - - if (mDisplayManager->numScreens() >= 2) - { - mMirror = new UBScreenMirror(); - } - - connect(UBApplication::webController, SIGNAL(imageCaptured(const QPixmap &, bool, const QUrl&)) - , this, SLOT(addCapturedPixmap(const QPixmap &, bool, const QUrl&))); - - networkAccessManager = new QNetworkAccessManager (this); - QTimer::singleShot (1000, this, SLOT (checkUpdateAtLaunch())); - -#ifdef Q_WS_X11 - mMainWindow->setStyleSheet("QToolButton { font-size: 11px}"); -#endif - -} - - -UBApplicationController::~UBApplicationController() -{ - foreach(UBBoardView* view, mPreviousViews) - { - delete view; - } - - delete mBlackScene; - delete mMirror; - if (mHttp) delete mHttp; -} - - -void UBApplicationController::initViewState(int horizontalPosition, int verticalPostition) -{ - mInitialHScroll = horizontalPosition; - mInitialVScroll = verticalPostition; -} - - -void UBApplicationController::initScreenLayout(bool useMultiscreen) -{ - mDisplayManager->setControlWidget(mMainWindow); - mDisplayManager->setDisplayWidget(mDisplayView); - - mDisplayManager->setPreviousDisplaysWidgets(mPreviousViews); - mDisplayManager->setDesktopWidget(mUninoteController->drawingView()); - - mDisplayManager->setUseMultiScreen(useMultiscreen); - mDisplayManager->adjustScreens(-1); -} - - -void UBApplicationController::screenLayoutChanged() -{ - initViewState(mControlView->horizontalScrollBar()->value(), - mControlView->verticalScrollBar()->value()); - - adaptToolBar(); - - adjustDisplayView(); - - if (mDisplayManager->hasDisplay()) - { - UBApplication::boardController->setBoxing(mDisplayView->geometry()); - } - else - { - UBApplication::boardController->setBoxing(QRect()); - } - - adjustPreviousViews(0, 0); -} - - -void UBApplicationController::adaptToolBar() -{ - bool highResolution = mMainWindow->width() > 1024; - - mMainWindow->actionClearPage->setVisible(Board == mMainMode && highResolution); - mMainWindow->actionBoard->setVisible(Board != mMainMode || highResolution); - mMainWindow->actionDocument->setVisible(Document != mMainMode || highResolution); - mMainWindow->actionWeb->setVisible(Internet != mMainMode || highResolution); - mMainWindow->boardToolBar->setIconSize(QSize(highResolution ? 48 : 42, mMainWindow->boardToolBar->iconSize().height())); - - mMainWindow->actionBoard->setEnabled(mMainMode != Board); - mMainWindow->actionWeb->setEnabled(mMainMode != Internet); - mMainWindow->actionDocument->setEnabled(mMainMode != Document); - - if (Document == mMainMode) - { - connect(UBApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)), UBApplication::documentController, SLOT(focusChanged(QWidget *, QWidget *))); - } - else - { - disconnect(UBApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)), UBApplication::documentController, SLOT(focusChanged(QWidget *, QWidget *))); - if (Board == mMainMode) - mMainWindow->actionDuplicate->setEnabled(true); - } - - UBApplication::boardController->setToolbarTexts(); - - UBApplication::webController->adaptToolBar(); - -} - - -void UBApplicationController::adjustDisplayView() -{ - if (mDisplayView) - { - qreal systemDisplayViewScaleFactor = 1.0; - - QSize pageSize = UBApplication::boardController->activeScene()->nominalSize(); - QSize displaySize = mDisplayView->size(); - - qreal hFactor = ((qreal)displaySize.width()) / ((qreal)pageSize.width()); - qreal vFactor = ((qreal)displaySize.height()) / ((qreal)pageSize.height()); - - systemDisplayViewScaleFactor = qMin(hFactor, vFactor); - - QTransform tr; - qreal scaleFactor = systemDisplayViewScaleFactor * UBApplication::boardController->currentZoom(); - - tr.scale(scaleFactor, scaleFactor); - - QRect rect = mControlView->rect(); - QPoint center(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); - - QTransform recentTransform = mDisplayView->transform(); - - if (recentTransform != tr) - mDisplayView->setTransform(tr); - - mDisplayView->centerOn(mControlView->mapToScene(center)); - } -} - - -void UBApplicationController::adjustPreviousViews(int pActiveSceneIndex, UBDocumentProxy *pActiveDocument) -{ - int viewIndex = pActiveSceneIndex; - - foreach(UBBoardView* previousView, mPreviousViews) - { - if (viewIndex > 0) - { - viewIndex--; - - UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pActiveDocument, viewIndex); - - if (scene) - { - previousView->setScene(scene); - - qreal ratio = ((qreal)previousView->geometry().width()) / ((qreal)previousView->geometry().height()); - QRectF sceneRect = scene->normalizedSceneRect(ratio); - qreal scaleRatio = previousView->geometry().width() / sceneRect.width(); - - previousView->resetTransform(); - - previousView->scale(scaleRatio, scaleRatio); - - previousView->centerOn(sceneRect.center()); - } - } - else - { - previousView->setScene(mBlackScene); - } - } -} - - -void UBApplicationController::blackout() -{ - mDisplayManager->blackout(); -} - - -void UBApplicationController::addCapturedPixmap(const QPixmap &pPixmap, bool pageMode, const QUrl& sourceUrl) -{ - if (!pPixmap.isNull()) - { - qreal sf = UBApplication::boardController->systemScaleFactor(); - qreal scaledWidth = ((qreal)pPixmap.width()) / sf; - qreal scaledHeight = ((qreal)pPixmap.height()) / sf; - - QSize pageNominalSize = UBApplication::boardController->activeScene()->nominalSize(); - - int newWidth = qMin((int)scaledWidth, pageNominalSize.width()); - int newHeight = qMin((int)scaledHeight, pageNominalSize.height()); - - if (pageMode) - { - newHeight = pPixmap.height(); - } - - QSizeF scaledSize(scaledWidth, scaledHeight); - scaledSize.scale(newWidth, newHeight, Qt::KeepAspectRatio); - - qreal scaleFactor = qMin(scaledSize.width() / (qreal)pPixmap.width(), scaledSize.height() / (qreal)pPixmap.height()); - - QPointF pos(0.0, 0.0); - - if (pageMode) - { - pos.setY(pageNominalSize.height() / -2 + scaledSize.height() / 2); - } - - UBApplication::boardController->paletteManager()->addItem(pPixmap, pos, scaleFactor, sourceUrl); - } -} - - -void UBApplicationController::addCapturedEmbedCode(const QString& embedCode) -{ - if (!embedCode.isEmpty()) - { - showBoard(); - - const QString userWidgetPath = UBSettings::settings()->userInteractiveDirectory() + "/" + tr("Web"); // TODO UB 4.x synch with w3cWidget - QDir userWidgetDir(userWidgetPath); - - int width = 300; - int height = 150; - - QString widgetPath = UBGraphicsW3CWidgetItem::createHtmlWrapperInDir(embedCode, userWidgetDir, - QSize(width, height), UBStringUtils::toCanonicalUuid(QUuid::createUuid())); - - if (widgetPath.length() > 0) - UBApplication::boardController->downloadURL(QUrl::fromLocalFile(widgetPath)); - } -} - - -void UBApplicationController::showBoard() -{ - mMainWindow->webToolBar->hide(); - mMainWindow->documentToolBar->hide(); - mMainWindow->tutorialToolBar->hide(); - mMainWindow->boardToolBar->show(); - - if (mMainMode == Document) - { - int selectedSceneIndex = UBApplication::documentController->getSelectedItemIndex(); - if (selectedSceneIndex != -1) - { - UBApplication::boardController->setActiveDocumentScene(UBApplication::documentController->selectedDocument(), selectedSceneIndex, true); - } - } - - mMainMode = Board; - - adaptToolBar(); - - mirroringEnabled(false); - - mMainWindow->switchToBoardWidget(); - - if (UBApplication::boardController) - UBApplication::boardController->show(); - - mIsShowingDesktop = false; - UBPlatformUtils::setDesktopMode(false); - - mUninoteController->hideWindow(); - - mMainWindow->show(); - - emit mainModeChanged(Board); - - UBApplication::boardController->freezeW3CWidgets(false); - UBApplication::boardController->activeScene()->updateGroupButtonState(); -} - - -void UBApplicationController::showInternet() -{ - - if (UBApplication::boardController) - { - UBApplication::boardController->persistCurrentScene(); - UBApplication::boardController->hide(); - } - - if (UBSettings::settings()->webUseExternalBrowser->get().toBool()) - { - showDesktop(true); - UBApplication::webController->show(UBWebController::WebBrowser); - // really no have emit mainModeChanged here ? potential problem with virtual keyboard ? - } - else - { - mMainWindow->boardToolBar->hide(); - mMainWindow->documentToolBar->hide(); - mMainWindow->tutorialToolBar->hide(); - mMainWindow->webToolBar->show(); - - mMainMode = Internet; - - adaptToolBar(); - - mMainWindow->show(); - mUninoteController->hideWindow(); - - UBApplication::webController->show(UBWebController::WebBrowser); - - emit mainModeChanged(Internet); - } -} - - -void UBApplicationController::showDocument() -{ - mMainWindow->webToolBar->hide(); - mMainWindow->boardToolBar->hide(); - mMainWindow->tutorialToolBar->hide(); - mMainWindow->documentToolBar->show(); - - mMainMode = Document; - - adaptToolBar(); - - mirroringEnabled(false); - - mMainWindow->switchToDocumentsWidget(); - - if (UBApplication::boardController) - { - if (UBApplication::boardController->activeScene()->isModified() || (UBApplication::boardController->paletteManager()->teacherGuideDockWidget() && UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified())) - UBApplication::boardController->persistCurrentScene(); - UBApplication::boardController->hide(); - } - - if (UBApplication::documentController) - UBApplication::documentController->show(); - - mMainWindow->show(); - - mUninoteController->hideWindow(); - - emit mainModeChanged(Document); -} - -void UBApplicationController::showDesktop(bool dontSwitchFrontProcess) -{ - int desktopWidgetIndex = qApp->desktop()->screenNumber(mMainWindow); - - if (UBApplication::boardController) - UBApplication::boardController->hide(); - - mMainWindow->hide(); - mUninoteController->showWindow(); - - if (mMirror) - { - QRect rect = qApp->desktop()->screenGeometry(desktopWidgetIndex); - mMirror->setSourceRect(rect); - } - - mIsShowingDesktop = true; - emit desktopMode(true); - - if (!dontSwitchFrontProcess) { - UBPlatformUtils::bringPreviousProcessToFront(); - } - - UBDrawingController::drawingController()->setInDestopMode(true); - UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); -} - - -void UBApplicationController::showTutorial() -{ - - if (UBApplication::boardController) - { - UBApplication::boardController->persistCurrentScene(); - UBApplication::boardController->hide(); - } - - if (UBSettings::settings()->webUseExternalBrowser->get().toBool()) - { - showDesktop(true); - UBApplication::webController->show(UBWebController::Tutorial); - - } - else{ - mMainWindow->webToolBar->hide(); - mMainWindow->boardToolBar->hide(); - mMainWindow->documentToolBar->hide(); - mMainWindow->tutorialToolBar->show(); - - - mMainMode = Tutorial; - - adaptToolBar(); - - mUninoteController->hideWindow(); - - UBApplication::webController->show(UBWebController::Tutorial); - - mirroringEnabled(false); - emit mainModeChanged(mMainMode); - } -} - - -void UBApplicationController::showSankoreEditor() -{ - - if (UBApplication::boardController) - { - UBApplication::boardController->persistCurrentScene(); - UBApplication::boardController->hide(); - } - -// it's needed not to duplicate webbrowser search in web mode. If I've breaked smbd's code let Ivan know - UBApplication::webController->show(UBWebController::Paraschool); - - mMainWindow->webToolBar->hide(); - mMainWindow->boardToolBar->hide(); - mMainWindow->documentToolBar->hide(); - mMainWindow->tutorialToolBar->show(); - - - mMainMode = ParaschoolEditor; - - adaptToolBar(); - - mUninoteController->hideWindow(); - - mirroringEnabled(false); - emit mainModeChanged(mMainMode); -} - -void UBApplicationController::checkUpdate() -{ - if(mHttp) - delete mHttp; - QUrl url("http://ftp.open-sankore.org/update.json"); - mHttp = new QHttp(url.host()); - connect(mHttp, SIGNAL(requestFinished(int,bool)), this, SLOT(updateRequestFinished(int,bool))); - mHttp->get(url.path()); -} - -void UBApplicationController::updateRequestFinished(int id, bool error) -{ - if (error){ - qWarning() << "http command id" << id << "return the error: " << mHttp->errorString(); - mHttp->close(); - } - else{ - QString responseString = QString(mHttp->readAll()); - if (!responseString.isEmpty() && responseString.contains("version") && responseString.contains("url")){ - mHttp->close(); - downloadJsonFinished(responseString); - } - } -} - - - -void UBApplicationController::downloadJsonFinished(QString currentJson) -{ - QScriptValue scriptValue; - QScriptEngine scriptEngine; - scriptValue = scriptEngine.evaluate ("(" + currentJson + ")"); - - UBVersion installedVersion (qApp->applicationVersion().left(4)); - UBVersion jsonVersion (scriptValue.property("version").toString().left(4)); - - if (installedVersion.isValid() && jsonVersion.isValid() && jsonVersion > installedVersion) { - if (UBApplication::mainWindow->yesNoQuestion(tr("Update available"), tr ("New update available, would you go to the web page ?"))){ - QUrl url(scriptValue.property ("url").toString()); - QDesktopServices::openUrl (url); - } - } - else { - if (isNoUpdateDisplayed) { - mMainWindow->information(tr("Update"), tr("No update available")); - } - } -} - -void UBApplicationController::checkUpdateAtLaunch() -{ - if(UBSettings::settings()->appEnableAutomaticSoftwareUpdates->get().toBool()){ - isNoUpdateDisplayed = false; - checkUpdate (); - } -} - -void UBApplicationController::checkUpdateRequest() -{ - isNoUpdateDisplayed = true; - checkUpdate (); -} - -void UBApplicationController::hideDesktop() -{ - if (mMainMode == Board) - { - showBoard(); - } - else if (mMainMode == Internet) - { - showInternet(); - } - else if (mMainMode == Document) - { - showDocument(); - } - else if (mMainMode == Tutorial) - { - showTutorial(); - } - else if (mMainMode == ParaschoolEditor) - { - showSankoreEditor(); - } - - mIsShowingDesktop = false; - - mDisplayManager->adjustScreens(-1); - - emit desktopMode(false); -} - -void UBApplicationController::setMirrorSourceWidget(QWidget* pWidget) -{ - if (mMirror) - { - mMirror->setSourceWidget(pWidget); - } -} - - -void UBApplicationController::mirroringEnabled(bool enabled) -{ - if (mMirror) - { - if (enabled) - { - mMirror->start(); - mDisplayManager->setDisplayWidget(mMirror); - - } - else - { - mDisplayManager->setDisplayWidget(mDisplayView); - mMirror->stop(); - } - - mMirror->setVisible(enabled && mDisplayManager->numScreens() > 1); - mUninoteController->updateShowHideState(enabled); - UBApplication::mainWindow->actionWebShowHideOnDisplay->setChecked(enabled); - } - else - { - mDisplayManager->setDisplayWidget(mDisplayView); - } -} - - -void UBApplicationController::closing() -{ - if (mMirror) - mMirror->stop(); - - if (mUninoteController) - { - mUninoteController->hideWindow(); - mUninoteController->close(); - } - - if (UBApplication::documentController) - UBApplication::documentController->closing(); -} - - -void UBApplicationController::showMessage(const QString& message, bool showSpinningWheel) -{ - if (!UBApplication::closingDown()) - { - if (mMainMode == Document) - { - UBApplication::boardController->hideMessage(); - UBApplication::documentController->showMessage(message, showSpinningWheel); - } - else - { - UBApplication::documentController->hideMessage(); - UBApplication::boardController->showMessage(message, showSpinningWheel); - } - } -} - - -void UBApplicationController::importFile(const QString& pFilePath) -{ - const QFile fileToOpen(pFilePath); - - if (!fileToOpen.exists()) - return; - - UBDocumentProxy* document = 0; - - bool success = false; - - document = UBDocumentManager::documentManager()->importFile(fileToOpen, ""); - - success = (document != 0); - - if (success && document) - { - if (mMainMode == Board || mMainMode == Internet) - { - if (UBApplication::boardController) - { - UBApplication::boardController->setActiveDocumentScene(document, 0); - showBoard(); - } - } - else if (mMainMode == Document) - { - if (UBApplication::documentController) - UBApplication::documentController->selectDocument(document); - } - } -} - -void UBApplicationController::useMultiScreen(bool use) -{ - mDisplayManager->setUseMultiScreen(use); - mDisplayManager->adjustScreens(0); - UBSettings::settings()->appUseMultiscreen->set(use); - -} - - -QStringList UBApplicationController::widgetInlineJavaScripts() -{ - QString scriptDirPath = UBPlatformUtils::applicationResourcesDirectory() + "/widget-inline-js"; - QDir scriptDir(scriptDirPath); - - QStringList scripts; - - if (scriptDir.exists()) - { - QStringList files = scriptDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name); - - foreach(QString file, files) - { - QFile scriptFile(scriptDirPath + "/" + file); - if (file.endsWith(".js") && scriptFile.open(QIODevice::ReadOnly)) - { - QString s = QString::fromUtf8(scriptFile.readAll()); - - if (s.length() > 0) - scripts << s; - - } - } - } - - qSort(scripts); - - return scripts; -} - - - -void UBApplicationController::actionCut() -{ - if (!UBApplication::closingDown()) - { - if (mMainMode == Board) - { - UBApplication::boardController->cut(); - } - else if(mMainMode == Document) - { - UBApplication::documentController->cut(); - } - else if(mMainMode == Internet) - { - UBApplication::webController->cut(); - } - } -} - - -void UBApplicationController::actionCopy() -{ - if (!UBApplication::closingDown()) - { - if (mMainMode == Board) - { - UBApplication::boardController->copy(); - } - else if(mMainMode == Document) - { - UBApplication::documentController->copy(); - } - else if(mMainMode == Internet) - { - UBApplication::webController->copy(); - } - } -} - - -void UBApplicationController::actionPaste() -{ - if (!UBApplication::closingDown()) - { - if (mMainMode == Board) - { - UBApplication::boardController->paste(); - } - else if (mMainMode == Document) - { - UBApplication::documentController->paste(); - } - else if(mMainMode == Internet) - { - UBApplication::webController->paste(); - } - } -} + + +#include "UBApplicationController.h" + +#include "frameworks/UBPlatformUtils.h" +#include "frameworks/UBVersion.h" + +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBSettings.h" +#include "core/UBSetting.h" +#include "core/UBDocumentManager.h" +#include "core/UBDisplayManager.h" + +#include "board/UBBoardView.h" +#include "board/UBBoardController.h" +#include "board/UBBoardPaletteManager.h" +#include "board/UBDrawingController.h" + + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentController.h" + +#include "domain/UBGraphicsWidgetItem.h" + +#include "desktop/UBDesktopPalette.h" +#include "desktop/UBDesktopAnnotationController.h" + +#include "web/UBWebController.h" + +#include "gui/UBScreenMirror.h" +#include "gui/UBMainWindow.h" +#include "gui/UBDockTeacherGuideWidget.h" +#include "gui/UBTeacherGuideWidget.h" + +#include "domain/UBGraphicsPixmapItem.h" + +#include "podcast/UBPodcastController.h" + +#include "network/UBNetworkAccessManager.h" + +#include "ui_mainWindow.h" + +#ifdef Q_WS_MAC +#include +#endif + +#include "core/memcheck.h" + +UBApplicationController::UBApplicationController(UBBoardView *pControlView, + UBBoardView *pDisplayView, + UBMainWindow* pMainWindow, + QObject* parent, + UBRightPalette* rightPalette) + : QObject(parent) + , mMainWindow(pMainWindow) + , mControlView(pControlView) + , mDisplayView(pDisplayView) + , mMirror(0) + , mMainMode(Board) + , mDisplayManager(0) + , mAutomaticCheckForUpdates(false) + , mCheckingForUpdates(false) + , mIsShowingDesktop(false) + , mHttp(0) +{ + mDisplayManager = new UBDisplayManager(this); + + mUninoteController = new UBDesktopAnnotationController(this, rightPalette); + + connect(mDisplayManager, SIGNAL(screenLayoutChanged()), this, SLOT(screenLayoutChanged())); + connect(mDisplayManager, SIGNAL(screenLayoutChanged()), mUninoteController, SLOT(screenLayoutChanged())); + connect(mDisplayManager, SIGNAL(screenLayoutChanged()), UBApplication::webController, SLOT(screenLayoutChanged())); + + connect(mUninoteController, SIGNAL(imageCaptured(const QPixmap &, bool)), this, SLOT(addCapturedPixmap(const QPixmap &, bool))); + connect(mUninoteController, SIGNAL(restoreUniboard()), this, SLOT(hideDesktop())); + + for(int i = 0; i < mDisplayManager->numPreviousViews(); i++) + { + UBBoardView *previousView = new UBBoardView(UBApplication::boardController, UBItemLayerType::FixedBackground, UBItemLayerType::Tool, 0); + previousView->setInteractive(false); + mPreviousViews.append(previousView); + } + + mBlackScene = new UBGraphicsScene(0); // deleted by UBApplicationController::destructor + mBlackScene->setBackground(true, false); + + if (mDisplayManager->numScreens() >= 2) + { + mMirror = new UBScreenMirror(); + } + + connect(UBApplication::webController, SIGNAL(imageCaptured(const QPixmap &, bool, const QUrl&)) + , this, SLOT(addCapturedPixmap(const QPixmap &, bool, const QUrl&))); + + networkAccessManager = new QNetworkAccessManager (this); + QTimer::singleShot (1000, this, SLOT (checkUpdateAtLaunch())); + +#ifdef Q_WS_X11 + mMainWindow->setStyleSheet("QToolButton { font-size: 11px}"); +#endif + +} + + +UBApplicationController::~UBApplicationController() +{ + foreach(UBBoardView* view, mPreviousViews) + { + delete view; + } + + delete mBlackScene; + delete mMirror; + if (mHttp) delete mHttp; +} + + +void UBApplicationController::initViewState(int horizontalPosition, int verticalPostition) +{ + mInitialHScroll = horizontalPosition; + mInitialVScroll = verticalPostition; +} + + +void UBApplicationController::initScreenLayout(bool useMultiscreen) +{ + mDisplayManager->setControlWidget(mMainWindow); + mDisplayManager->setDisplayWidget(mDisplayView); + + mDisplayManager->setPreviousDisplaysWidgets(mPreviousViews); + mDisplayManager->setDesktopWidget(mUninoteController->drawingView()); + + mDisplayManager->setUseMultiScreen(useMultiscreen); + mDisplayManager->adjustScreens(-1); +} + + +void UBApplicationController::screenLayoutChanged() +{ + initViewState(mControlView->horizontalScrollBar()->value(), + mControlView->verticalScrollBar()->value()); + + adaptToolBar(); + + adjustDisplayView(); + + if (mDisplayManager->hasDisplay()) + { + UBApplication::boardController->setBoxing(mDisplayView->geometry()); + } + else + { + UBApplication::boardController->setBoxing(QRect()); + } + + adjustPreviousViews(0, 0); +} + + +void UBApplicationController::adaptToolBar() +{ + bool highResolution = mMainWindow->width() > 1024; + + mMainWindow->actionClearPage->setVisible(Board == mMainMode && highResolution); + mMainWindow->actionBoard->setVisible(Board != mMainMode || highResolution); + mMainWindow->actionDocument->setVisible(Document != mMainMode || highResolution); + mMainWindow->actionWeb->setVisible(Internet != mMainMode || highResolution); + mMainWindow->boardToolBar->setIconSize(QSize(highResolution ? 48 : 42, mMainWindow->boardToolBar->iconSize().height())); + + mMainWindow->actionBoard->setEnabled(mMainMode != Board); + mMainWindow->actionWeb->setEnabled(mMainMode != Internet); + mMainWindow->actionDocument->setEnabled(mMainMode != Document); + + if (Document == mMainMode) + { + connect(UBApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)), UBApplication::documentController, SLOT(focusChanged(QWidget *, QWidget *))); + } + else + { + disconnect(UBApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)), UBApplication::documentController, SLOT(focusChanged(QWidget *, QWidget *))); + if (Board == mMainMode) + mMainWindow->actionDuplicate->setEnabled(true); + } + + UBApplication::boardController->setToolbarTexts(); + + UBApplication::webController->adaptToolBar(); + +} + + +void UBApplicationController::adjustDisplayView() +{ + if (mDisplayView) + { + qreal systemDisplayViewScaleFactor = 1.0; + + QSize pageSize = UBApplication::boardController->activeScene()->nominalSize(); + QSize displaySize = mDisplayView->size(); + + qreal hFactor = ((qreal)displaySize.width()) / ((qreal)pageSize.width()); + qreal vFactor = ((qreal)displaySize.height()) / ((qreal)pageSize.height()); + + systemDisplayViewScaleFactor = qMin(hFactor, vFactor); + + QTransform tr; + qreal scaleFactor = systemDisplayViewScaleFactor * UBApplication::boardController->currentZoom(); + + tr.scale(scaleFactor, scaleFactor); + + QRect rect = mControlView->rect(); + QPoint center(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); + + QTransform recentTransform = mDisplayView->transform(); + + if (recentTransform != tr) + mDisplayView->setTransform(tr); + + mDisplayView->centerOn(mControlView->mapToScene(center)); + } +} + + +void UBApplicationController::adjustPreviousViews(int pActiveSceneIndex, UBDocumentProxy *pActiveDocument) +{ + int viewIndex = pActiveSceneIndex; + + foreach(UBBoardView* previousView, mPreviousViews) + { + if (viewIndex > 0) + { + viewIndex--; + + UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pActiveDocument, viewIndex); + + if (scene) + { + previousView->setScene(scene); + + qreal ratio = ((qreal)previousView->geometry().width()) / ((qreal)previousView->geometry().height()); + QRectF sceneRect = scene->normalizedSceneRect(ratio); + qreal scaleRatio = previousView->geometry().width() / sceneRect.width(); + + previousView->resetTransform(); + + previousView->scale(scaleRatio, scaleRatio); + + previousView->centerOn(sceneRect.center()); + } + } + else + { + previousView->setScene(mBlackScene); + } + } +} + + +void UBApplicationController::blackout() +{ + mDisplayManager->blackout(); +} + + +void UBApplicationController::addCapturedPixmap(const QPixmap &pPixmap, bool pageMode, const QUrl& sourceUrl) +{ + if (!pPixmap.isNull()) + { + qreal sf = UBApplication::boardController->systemScaleFactor(); + qreal scaledWidth = ((qreal)pPixmap.width()) / sf; + qreal scaledHeight = ((qreal)pPixmap.height()) / sf; + + QSize pageNominalSize = UBApplication::boardController->activeScene()->nominalSize(); + + int newWidth = qMin((int)scaledWidth, pageNominalSize.width()); + int newHeight = qMin((int)scaledHeight, pageNominalSize.height()); + + if (pageMode) + { + newHeight = pPixmap.height(); + } + + QSizeF scaledSize(scaledWidth, scaledHeight); + scaledSize.scale(newWidth, newHeight, Qt::KeepAspectRatio); + + qreal scaleFactor = qMin(scaledSize.width() / (qreal)pPixmap.width(), scaledSize.height() / (qreal)pPixmap.height()); + + QPointF pos(0.0, 0.0); + + if (pageMode) + { + pos.setY(pageNominalSize.height() / -2 + scaledSize.height() / 2); + } + + UBApplication::boardController->paletteManager()->addItem(pPixmap, pos, scaleFactor, sourceUrl); + } +} + + +void UBApplicationController::addCapturedEmbedCode(const QString& embedCode) +{ + if (!embedCode.isEmpty()) + { + showBoard(); + + const QString userWidgetPath = UBSettings::settings()->userInteractiveDirectory() + "/" + tr("Web"); // TODO UB 4.x synch with w3cWidget + QDir userWidgetDir(userWidgetPath); + + int width = 300; + int height = 150; + + QString widgetPath = UBGraphicsW3CWidgetItem::createHtmlWrapperInDir(embedCode, userWidgetDir, + QSize(width, height), UBStringUtils::toCanonicalUuid(QUuid::createUuid())); + + if (widgetPath.length() > 0) + UBApplication::boardController->downloadURL(QUrl::fromLocalFile(widgetPath)); + } +} + + +void UBApplicationController::showBoard() +{ + mMainWindow->webToolBar->hide(); + mMainWindow->documentToolBar->hide(); + mMainWindow->tutorialToolBar->hide(); + mMainWindow->boardToolBar->show(); + + if (mMainMode == Document) + { + int selectedSceneIndex = UBApplication::documentController->getSelectedItemIndex(); + if (selectedSceneIndex != -1) + { + UBApplication::boardController->setActiveDocumentScene(UBApplication::documentController->selectedDocument(), selectedSceneIndex, true); + } + } + + mMainMode = Board; + + adaptToolBar(); + + mirroringEnabled(false); + + mMainWindow->switchToBoardWidget(); + + if (UBApplication::boardController) + UBApplication::boardController->show(); + + mIsShowingDesktop = false; + UBPlatformUtils::setDesktopMode(false); + + mUninoteController->hideWindow(); + + mMainWindow->show(); + + emit mainModeChanged(Board); + + UBApplication::boardController->freezeW3CWidgets(false); + UBApplication::boardController->activeScene()->updateGroupButtonState(); +} + + +void UBApplicationController::showInternet() +{ + + if (UBApplication::boardController) + { + UBApplication::boardController->persistCurrentScene(); + UBApplication::boardController->hide(); + } + + if (UBSettings::settings()->webUseExternalBrowser->get().toBool()) + { + showDesktop(true); + UBApplication::webController->show(UBWebController::WebBrowser); + // really no have emit mainModeChanged here ? potential problem with virtual keyboard ? + } + else + { + mMainWindow->boardToolBar->hide(); + mMainWindow->documentToolBar->hide(); + mMainWindow->tutorialToolBar->hide(); + mMainWindow->webToolBar->show(); + + mMainMode = Internet; + + adaptToolBar(); + + mMainWindow->show(); + mUninoteController->hideWindow(); + + UBApplication::webController->show(UBWebController::WebBrowser); + + emit mainModeChanged(Internet); + } +} + + +void UBApplicationController::showDocument() +{ + mMainWindow->webToolBar->hide(); + mMainWindow->boardToolBar->hide(); + mMainWindow->tutorialToolBar->hide(); + mMainWindow->documentToolBar->show(); + + mMainMode = Document; + + adaptToolBar(); + + mirroringEnabled(false); + + mMainWindow->switchToDocumentsWidget(); + + if (UBApplication::boardController) + { + if (UBApplication::boardController->activeScene()->isModified() || (UBApplication::boardController->paletteManager()->teacherGuideDockWidget() && UBApplication::boardController->paletteManager()->teacherGuideDockWidget()->teacherGuideWidget()->isModified())) + UBApplication::boardController->persistCurrentScene(); + UBApplication::boardController->hide(); + } + + if (UBApplication::documentController) + UBApplication::documentController->show(); + + mMainWindow->show(); + + mUninoteController->hideWindow(); + + emit mainModeChanged(Document); +} + +void UBApplicationController::showDesktop(bool dontSwitchFrontProcess) +{ + int desktopWidgetIndex = qApp->desktop()->screenNumber(mMainWindow); + + if (UBApplication::boardController) + UBApplication::boardController->hide(); + + mMainWindow->hide(); + mUninoteController->showWindow(); + + if (mMirror) + { + QRect rect = qApp->desktop()->screenGeometry(desktopWidgetIndex); + mMirror->setSourceRect(rect); + } + + mIsShowingDesktop = true; + emit desktopMode(true); + + if (!dontSwitchFrontProcess) { + UBPlatformUtils::bringPreviousProcessToFront(); + } + + UBDrawingController::drawingController()->setInDestopMode(true); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); +} + + +void UBApplicationController::showTutorial() +{ + + if (UBApplication::boardController) + { + UBApplication::boardController->persistCurrentScene(); + UBApplication::boardController->hide(); + } + + if (UBSettings::settings()->webUseExternalBrowser->get().toBool()) + { + showDesktop(true); + UBApplication::webController->show(UBWebController::Tutorial); + + } + else{ + mMainWindow->webToolBar->hide(); + mMainWindow->boardToolBar->hide(); + mMainWindow->documentToolBar->hide(); + mMainWindow->tutorialToolBar->show(); + + + mMainMode = Tutorial; + + adaptToolBar(); + + mUninoteController->hideWindow(); + + UBApplication::webController->show(UBWebController::Tutorial); + + mirroringEnabled(false); + emit mainModeChanged(mMainMode); + } +} + + +void UBApplicationController::showSankoreEditor() +{ + + if (UBApplication::boardController) + { + UBApplication::boardController->persistCurrentScene(); + UBApplication::boardController->hide(); + } + +// it's needed not to duplicate webbrowser search in web mode. If I've breaked smbd's code let Ivan know + UBApplication::webController->show(UBWebController::Paraschool); + + mMainWindow->webToolBar->hide(); + mMainWindow->boardToolBar->hide(); + mMainWindow->documentToolBar->hide(); + mMainWindow->tutorialToolBar->show(); + + + mMainMode = ParaschoolEditor; + + adaptToolBar(); + + mUninoteController->hideWindow(); + + mirroringEnabled(false); + emit mainModeChanged(mMainMode); +} + +void UBApplicationController::checkUpdate() +{ + if(mHttp) + delete mHttp; + QUrl url("http://ftp.open-sankore.org/update.json"); + mHttp = new QHttp(url.host()); + connect(mHttp, SIGNAL(requestFinished(int,bool)), this, SLOT(updateRequestFinished(int,bool))); + mHttp->get(url.path()); +} + +void UBApplicationController::updateRequestFinished(int id, bool error) +{ + if (error){ + qWarning() << "http command id" << id << "return the error: " << mHttp->errorString(); + mHttp->close(); + } + else{ + QString responseString = QString(mHttp->readAll()); + if (!responseString.isEmpty() && responseString.contains("version") && responseString.contains("url")){ + mHttp->close(); + downloadJsonFinished(responseString); + } + } +} + + + +void UBApplicationController::downloadJsonFinished(QString currentJson) +{ + QScriptValue scriptValue; + QScriptEngine scriptEngine; + scriptValue = scriptEngine.evaluate ("(" + currentJson + ")"); + + UBVersion installedVersion (qApp->applicationVersion().left(4)); + UBVersion jsonVersion (scriptValue.property("version").toString().left(4)); + + if (installedVersion.isValid() && jsonVersion.isValid() && jsonVersion > installedVersion) { + if (UBApplication::mainWindow->yesNoQuestion(tr("Update available"), tr ("New update available, would you go to the web page ?"))){ + QUrl url(scriptValue.property ("url").toString()); + QDesktopServices::openUrl (url); + } + } + else { + if (isNoUpdateDisplayed) { + mMainWindow->information(tr("Update"), tr("No update available")); + } + } +} + +void UBApplicationController::checkUpdateAtLaunch() +{ + if(UBSettings::settings()->appEnableAutomaticSoftwareUpdates->get().toBool()){ + isNoUpdateDisplayed = false; + checkUpdate (); + } +} + +void UBApplicationController::checkUpdateRequest() +{ + isNoUpdateDisplayed = true; + checkUpdate (); +} + +void UBApplicationController::hideDesktop() +{ + if (mMainMode == Board) + { + showBoard(); + } + else if (mMainMode == Internet) + { + showInternet(); + } + else if (mMainMode == Document) + { + showDocument(); + } + else if (mMainMode == Tutorial) + { + showTutorial(); + } + else if (mMainMode == ParaschoolEditor) + { + showSankoreEditor(); + } + + mIsShowingDesktop = false; + + mDisplayManager->adjustScreens(-1); + + emit desktopMode(false); +} + +void UBApplicationController::setMirrorSourceWidget(QWidget* pWidget) +{ + if (mMirror) + { + mMirror->setSourceWidget(pWidget); + } +} + + +void UBApplicationController::mirroringEnabled(bool enabled) +{ + if (mMirror) + { + if (enabled) + { + mMirror->start(); + mDisplayManager->setDisplayWidget(mMirror); + + } + else + { + mDisplayManager->setDisplayWidget(mDisplayView); + mMirror->stop(); + } + + mMirror->setVisible(enabled && mDisplayManager->numScreens() > 1); + mUninoteController->updateShowHideState(enabled); + UBApplication::mainWindow->actionWebShowHideOnDisplay->setChecked(enabled); + } + else + { + mDisplayManager->setDisplayWidget(mDisplayView); + } +} + + +void UBApplicationController::closing() +{ + if (mMirror) + mMirror->stop(); + + if (mUninoteController) + { + mUninoteController->hideWindow(); + mUninoteController->close(); + } + + if (UBApplication::documentController) + UBApplication::documentController->closing(); +} + + +void UBApplicationController::showMessage(const QString& message, bool showSpinningWheel) +{ + if (!UBApplication::closingDown()) + { + if (mMainMode == Document) + { + UBApplication::boardController->hideMessage(); + UBApplication::documentController->showMessage(message, showSpinningWheel); + } + else + { + UBApplication::documentController->hideMessage(); + UBApplication::boardController->showMessage(message, showSpinningWheel); + } + } +} + + +void UBApplicationController::importFile(const QString& pFilePath) +{ + const QFile fileToOpen(pFilePath); + + if (!fileToOpen.exists()) + return; + + UBDocumentProxy* document = 0; + + bool success = false; + + document = UBDocumentManager::documentManager()->importFile(fileToOpen, ""); + + success = (document != 0); + + if (success && document) + { + if (mMainMode == Board || mMainMode == Internet) + { + if (UBApplication::boardController) + { + UBApplication::boardController->setActiveDocumentScene(document, 0); + showBoard(); + } + } + else if (mMainMode == Document) + { + if (UBApplication::documentController) + UBApplication::documentController->selectDocument(document); + } + } +} + +void UBApplicationController::useMultiScreen(bool use) +{ + mDisplayManager->setUseMultiScreen(use); + mDisplayManager->adjustScreens(0); + UBSettings::settings()->appUseMultiscreen->set(use); + +} + + +QStringList UBApplicationController::widgetInlineJavaScripts() +{ + QString scriptDirPath = UBPlatformUtils::applicationResourcesDirectory() + "/widget-inline-js"; + QDir scriptDir(scriptDirPath); + + QStringList scripts; + + if (scriptDir.exists()) + { + QStringList files = scriptDir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name); + + foreach(QString file, files) + { + QFile scriptFile(scriptDirPath + "/" + file); + if (file.endsWith(".js") && scriptFile.open(QIODevice::ReadOnly)) + { + QString s = QString::fromUtf8(scriptFile.readAll()); + + if (s.length() > 0) + scripts << s; + + } + } + } + + qSort(scripts); + + return scripts; +} + + + +void UBApplicationController::actionCut() +{ + if (!UBApplication::closingDown()) + { + if (mMainMode == Board) + { + UBApplication::boardController->cut(); + } + else if(mMainMode == Document) + { + UBApplication::documentController->cut(); + } + else if(mMainMode == Internet) + { + UBApplication::webController->cut(); + } + } +} + + +void UBApplicationController::actionCopy() +{ + if (!UBApplication::closingDown()) + { + if (mMainMode == Board) + { + UBApplication::boardController->copy(); + } + else if(mMainMode == Document) + { + UBApplication::documentController->copy(); + } + else if(mMainMode == Internet) + { + UBApplication::webController->copy(); + } + } +} + + +void UBApplicationController::actionPaste() +{ + if (!UBApplication::closingDown()) + { + if (mMainMode == Board) + { + UBApplication::boardController->paste(); + } + else if (mMainMode == Document) + { + UBApplication::documentController->paste(); + } + else if(mMainMode == Internet) + { + UBApplication::webController->paste(); + } + } +} diff --git a/src/core/UBDocumentManager.cpp b/src/core/UBDocumentManager.cpp index ffc1bd47..b7566eed 100644 --- a/src/core/UBDocumentManager.cpp +++ b/src/core/UBDocumentManager.cpp @@ -21,297 +21,297 @@ -#include "UBDocumentManager.h" - -#include "frameworks/UBStringUtils.h" - -#include "adaptors/UBExportFullPDF.h" -#include "adaptors/UBExportDocument.h" -#include "adaptors/UBExportWeb.h" -#include "adaptors/UBExportCFF.h" -#include "adaptors/UBWebPublisher.h" -#include "adaptors/UBImportDocument.h" -#include "adaptors/UBImportPDF.h" -#include "adaptors/UBImportImage.h" -#include "adaptors/UBImportCFF.h" - -#include "domain/UBGraphicsScene.h" -#include "domain/UBGraphicsSvgItem.h" -#include "domain/UBGraphicsPixmapItem.h" - -#include "document/UBDocumentProxy.h" -#include "document/UBDocumentController.h" -#include "board/UBBoardController.h" - -#include "UBApplication.h" -#include "UBSettings.h" -#include "UBPersistenceManager.h" - -#include "../adaptors/UBExportWeb.h" - -#include "core/memcheck.h" - -UBDocumentManager* UBDocumentManager::sDocumentManager = 0; - -UBDocumentManager* UBDocumentManager::documentManager() -{ - if (!sDocumentManager) - { - sDocumentManager = new UBDocumentManager(qApp); - } - return sDocumentManager; -} - - -UBDocumentManager::UBDocumentManager(QObject *parent) - :QObject(parent) -{ - // TODO UB 4.7 string used in document persistence (folder names) - QString dummyImages = tr("images"); - QString dummyVideos = tr("videos"); - QString dummyObjects = tr("objects"); - QString dummyWidgets = tr("widgets"); - - UBExportCFF* cffExporter = new UBExportCFF(this); - UBExportFullPDF* exportFullPdf = new UBExportFullPDF(this); - UBExportDocument* exportDocument = new UBExportDocument(this); - UBWebPublisher* webPublished = new UBWebPublisher(this); - mExportAdaptors.append(exportDocument); - mExportAdaptors.append(webPublished); - mExportAdaptors.append(exportFullPdf); - mExportAdaptors.append(cffExporter); -// UBExportWeb* exportWeb = new UBExportWeb(this); -// mExportAdaptors.append(exportWeb); - - UBImportDocument* documentImport = new UBImportDocument(this); - mImportAdaptors.append(documentImport); - UBImportPDF* pdfImport = new UBImportPDF(this); - mImportAdaptors.append(pdfImport); - UBImportImage* imageImport = new UBImportImage(this); - mImportAdaptors.append(imageImport); - UBImportCFF* cffImport = new UBImportCFF(this); - mImportAdaptors.append(cffImport); -} - - -UBDocumentManager::~UBDocumentManager() -{ - // NOOP -} - - -QStringList UBDocumentManager::importFileExtensions() -{ - QStringList result; - - foreach (UBImportAdaptor *importAdaptor, mImportAdaptors) - { - result << importAdaptor->supportedExtentions(); - } - return result; -} - - -QString UBDocumentManager::importFileFilter() -{ - QString result; - - result += tr("All supported files (*.%1)").arg(importFileExtensions().join(" *.")); - foreach (UBImportAdaptor *importAdaptor, mImportAdaptors) - { - if (importAdaptor->importFileFilter().length() > 0) - { - if (result.length()) - { - result += ";;"; - } - result += importAdaptor->importFileFilter(); - } - } - qDebug() << "import file filter" << result; - return result; -} - - -UBDocumentProxy* UBDocumentManager::importFile(const QFile& pFile, const QString& pGroup) -{ - QFileInfo fileInfo(pFile); - - foreach (UBImportAdaptor *adaptor, mImportAdaptors) - { - if (adaptor->supportedExtentions().lastIndexOf(fileInfo.suffix().toLower()) != -1) - { - UBDocumentProxy* document; - UBApplication::setDisabled(true); - - if (adaptor->isDocumentBased()) - { - UBDocumentBasedImportAdaptor* importAdaptor = (UBDocumentBasedImportAdaptor*)adaptor; - - document = importAdaptor->importFile(pFile, pGroup); - - } - else - { - UBPageBasedImportAdaptor* importAdaptor = (UBPageBasedImportAdaptor*)adaptor; - - // Document import procedure..... - QString documentName = QFileInfo(pFile.fileName()).completeBaseName(); - document = UBPersistenceManager::persistenceManager()->createDocument(pGroup, documentName); - - QUuid uuid = QUuid::createUuid(); - QString filepath = pFile.fileName(); - if (importAdaptor->folderToCopy() != "") - { - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(document, pFile.fileName(), importAdaptor->folderToCopy() , uuid, filepath); - if (!b) - { - UBPersistenceManager::persistenceManager()->deleteDocument(document); - UBApplication::setDisabled(false); - return NULL; - } - } - - QList pages = importAdaptor->import(uuid, filepath); - int nPage = 0; - foreach(UBGraphicsItem* page, pages) - { - UBApplication::showMessage(tr("Inserting page %1 of %2").arg(++nPage).arg(pages.size()), true); -#ifdef Q_WS_MACX - //Workaround for issue 912 - QApplication::processEvents(); -#endif - int pageIndex = document->pageCount(); - UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(document, pageIndex); - importAdaptor->placeImportedItemToScene(scene, page); - UBPersistenceManager::persistenceManager()->persistDocumentScene(document, scene, pageIndex); - } - - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(document); - UBApplication::showMessage(tr("Import successful.")); - } - - UBApplication::setDisabled(false); - return document; - } - - } - return NULL; -} - - -int UBDocumentManager::addFilesToDocument(UBDocumentProxy* document, QStringList fileNames) -{ - int nImportedDocuments = 0; - foreach(const QString& fileName, fileNames) - { - UBApplication::showMessage(tr("Importing file %1").arg(fileName)); - - QFile file(fileName); - QFileInfo fileInfo(file); - - foreach (UBImportAdaptor *adaptor, mImportAdaptors) - { - if (adaptor->supportedExtentions().lastIndexOf(fileInfo.suffix().toLower()) != -1) - { - UBApplication::setDisabled(true); - - if (adaptor->isDocumentBased()) - { - UBDocumentBasedImportAdaptor* importAdaptor = (UBDocumentBasedImportAdaptor*)adaptor; - - if (importAdaptor->addFileToDocument(document, file)) - nImportedDocuments++; - } - else - { - UBPageBasedImportAdaptor* importAdaptor = (UBPageBasedImportAdaptor*)adaptor; - - QUuid uuid = QUuid::createUuid(); - QString filepath = file.fileName(); - if (importAdaptor->folderToCopy() != "") - { - bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(document, file.fileName(), importAdaptor->folderToCopy() , uuid, filepath); - if (!b) - { - continue; - } - } - - QList pages = importAdaptor->import(uuid, filepath); - int nPage = 0; - foreach(UBGraphicsItem* page, pages) - { - UBApplication::showMessage(tr("Inserting page %1 of %2").arg(++nPage).arg(pages.size()), true); - int pageIndex = document->pageCount(); - UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(document, pageIndex); - importAdaptor->placeImportedItemToScene(scene, page); - UBPersistenceManager::persistenceManager()->persistDocumentScene(document, scene, pageIndex); - UBApplication::boardController->addEmptyThumbPage(); - } - - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(document); - UBApplication::showMessage(tr("Import of file %1 successful.").arg(file.fileName())); - nImportedDocuments++; - } - - UBApplication::setDisabled(false); - } - } - } - return nImportedDocuments; -} - - -int UBDocumentManager::addImageDirToDocument(const QDir& pDir, UBDocumentProxy* pDocument) -{ - QStringList filenames = pDir.entryList(QDir::Files | QDir::NoDotAndDotDot); - - filenames = UBStringUtils::sortByLastDigit(filenames); - - QStringList fileNames; - - foreach(QString f, filenames) - { - fileNames << pDir.absolutePath() + "/" + f; - } - - return addFilesToDocument(pDocument, fileNames); - -} - - -UBDocumentProxy* UBDocumentManager::importDir(const QDir& pDir, const QString& pGroup) -{ - UBDocumentProxy* doc = UBPersistenceManager::persistenceManager()->createDocument(pGroup, pDir.dirName()); - - int result = addImageDirToDocument(pDir, doc); - - if (result > 0) - { - doc->setMetaData(UBSettings::documentGroupName, pGroup); - doc->setMetaData(UBSettings::documentName, pDir.dirName()); - - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(doc); - - UBApplication::showMessage(tr("File %1 saved").arg(pDir.dirName())); - - } - else - { - UBPersistenceManager::persistenceManager()->deleteDocument(doc); - } - - return doc; -} - - -QList UBDocumentManager::supportedExportAdaptors() -{ - return mExportAdaptors; -} - -void UBDocumentManager::emitDocumentUpdated(UBDocumentProxy* pDocument) -{ - emit documentUpdated(pDocument); -} +#include "UBDocumentManager.h" + +#include "frameworks/UBStringUtils.h" + +#include "adaptors/UBExportFullPDF.h" +#include "adaptors/UBExportDocument.h" +#include "adaptors/UBExportWeb.h" +#include "adaptors/UBExportCFF.h" +#include "adaptors/UBWebPublisher.h" +#include "adaptors/UBImportDocument.h" +#include "adaptors/UBImportPDF.h" +#include "adaptors/UBImportImage.h" +#include "adaptors/UBImportCFF.h" + +#include "domain/UBGraphicsScene.h" +#include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsPixmapItem.h" + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentController.h" +#include "board/UBBoardController.h" + +#include "UBApplication.h" +#include "UBSettings.h" +#include "UBPersistenceManager.h" + +#include "../adaptors/UBExportWeb.h" + +#include "core/memcheck.h" + +UBDocumentManager* UBDocumentManager::sDocumentManager = 0; + +UBDocumentManager* UBDocumentManager::documentManager() +{ + if (!sDocumentManager) + { + sDocumentManager = new UBDocumentManager(qApp); + } + return sDocumentManager; +} + + +UBDocumentManager::UBDocumentManager(QObject *parent) + :QObject(parent) +{ + // TODO UB 4.7 string used in document persistence (folder names) + QString dummyImages = tr("images"); + QString dummyVideos = tr("videos"); + QString dummyObjects = tr("objects"); + QString dummyWidgets = tr("widgets"); + + UBExportCFF* cffExporter = new UBExportCFF(this); + UBExportFullPDF* exportFullPdf = new UBExportFullPDF(this); + UBExportDocument* exportDocument = new UBExportDocument(this); + UBWebPublisher* webPublished = new UBWebPublisher(this); + mExportAdaptors.append(exportDocument); + mExportAdaptors.append(webPublished); + mExportAdaptors.append(exportFullPdf); + mExportAdaptors.append(cffExporter); +// UBExportWeb* exportWeb = new UBExportWeb(this); +// mExportAdaptors.append(exportWeb); + + UBImportDocument* documentImport = new UBImportDocument(this); + mImportAdaptors.append(documentImport); + UBImportPDF* pdfImport = new UBImportPDF(this); + mImportAdaptors.append(pdfImport); + UBImportImage* imageImport = new UBImportImage(this); + mImportAdaptors.append(imageImport); + UBImportCFF* cffImport = new UBImportCFF(this); + mImportAdaptors.append(cffImport); +} + + +UBDocumentManager::~UBDocumentManager() +{ + // NOOP +} + + +QStringList UBDocumentManager::importFileExtensions() +{ + QStringList result; + + foreach (UBImportAdaptor *importAdaptor, mImportAdaptors) + { + result << importAdaptor->supportedExtentions(); + } + return result; +} + + +QString UBDocumentManager::importFileFilter() +{ + QString result; + + result += tr("All supported files (*.%1)").arg(importFileExtensions().join(" *.")); + foreach (UBImportAdaptor *importAdaptor, mImportAdaptors) + { + if (importAdaptor->importFileFilter().length() > 0) + { + if (result.length()) + { + result += ";;"; + } + result += importAdaptor->importFileFilter(); + } + } + qDebug() << "import file filter" << result; + return result; +} + + +UBDocumentProxy* UBDocumentManager::importFile(const QFile& pFile, const QString& pGroup) +{ + QFileInfo fileInfo(pFile); + + foreach (UBImportAdaptor *adaptor, mImportAdaptors) + { + if (adaptor->supportedExtentions().lastIndexOf(fileInfo.suffix().toLower()) != -1) + { + UBDocumentProxy* document; + UBApplication::setDisabled(true); + + if (adaptor->isDocumentBased()) + { + UBDocumentBasedImportAdaptor* importAdaptor = (UBDocumentBasedImportAdaptor*)adaptor; + + document = importAdaptor->importFile(pFile, pGroup); + + } + else + { + UBPageBasedImportAdaptor* importAdaptor = (UBPageBasedImportAdaptor*)adaptor; + + // Document import procedure..... + QString documentName = QFileInfo(pFile.fileName()).completeBaseName(); + document = UBPersistenceManager::persistenceManager()->createDocument(pGroup, documentName); + + QUuid uuid = QUuid::createUuid(); + QString filepath = pFile.fileName(); + if (importAdaptor->folderToCopy() != "") + { + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(document, pFile.fileName(), importAdaptor->folderToCopy() , uuid, filepath); + if (!b) + { + UBPersistenceManager::persistenceManager()->deleteDocument(document); + UBApplication::setDisabled(false); + return NULL; + } + } + + QList pages = importAdaptor->import(uuid, filepath); + int nPage = 0; + foreach(UBGraphicsItem* page, pages) + { + UBApplication::showMessage(tr("Inserting page %1 of %2").arg(++nPage).arg(pages.size()), true); +#ifdef Q_WS_MACX + //Workaround for issue 912 + QApplication::processEvents(); +#endif + int pageIndex = document->pageCount(); + UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(document, pageIndex); + importAdaptor->placeImportedItemToScene(scene, page); + UBPersistenceManager::persistenceManager()->persistDocumentScene(document, scene, pageIndex); + } + + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(document); + UBApplication::showMessage(tr("Import successful.")); + } + + UBApplication::setDisabled(false); + return document; + } + + } + return NULL; +} + + +int UBDocumentManager::addFilesToDocument(UBDocumentProxy* document, QStringList fileNames) +{ + int nImportedDocuments = 0; + foreach(const QString& fileName, fileNames) + { + UBApplication::showMessage(tr("Importing file %1").arg(fileName)); + + QFile file(fileName); + QFileInfo fileInfo(file); + + foreach (UBImportAdaptor *adaptor, mImportAdaptors) + { + if (adaptor->supportedExtentions().lastIndexOf(fileInfo.suffix().toLower()) != -1) + { + UBApplication::setDisabled(true); + + if (adaptor->isDocumentBased()) + { + UBDocumentBasedImportAdaptor* importAdaptor = (UBDocumentBasedImportAdaptor*)adaptor; + + if (importAdaptor->addFileToDocument(document, file)) + nImportedDocuments++; + } + else + { + UBPageBasedImportAdaptor* importAdaptor = (UBPageBasedImportAdaptor*)adaptor; + + QUuid uuid = QUuid::createUuid(); + QString filepath = file.fileName(); + if (importAdaptor->folderToCopy() != "") + { + bool b = UBPersistenceManager::persistenceManager()->addFileToDocument(document, file.fileName(), importAdaptor->folderToCopy() , uuid, filepath); + if (!b) + { + continue; + } + } + + QList pages = importAdaptor->import(uuid, filepath); + int nPage = 0; + foreach(UBGraphicsItem* page, pages) + { + UBApplication::showMessage(tr("Inserting page %1 of %2").arg(++nPage).arg(pages.size()), true); + int pageIndex = document->pageCount(); + UBGraphicsScene* scene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(document, pageIndex); + importAdaptor->placeImportedItemToScene(scene, page); + UBPersistenceManager::persistenceManager()->persistDocumentScene(document, scene, pageIndex); + UBApplication::boardController->addEmptyThumbPage(); + } + + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(document); + UBApplication::showMessage(tr("Import of file %1 successful.").arg(file.fileName())); + nImportedDocuments++; + } + + UBApplication::setDisabled(false); + } + } + } + return nImportedDocuments; +} + + +int UBDocumentManager::addImageDirToDocument(const QDir& pDir, UBDocumentProxy* pDocument) +{ + QStringList filenames = pDir.entryList(QDir::Files | QDir::NoDotAndDotDot); + + filenames = UBStringUtils::sortByLastDigit(filenames); + + QStringList fileNames; + + foreach(QString f, filenames) + { + fileNames << pDir.absolutePath() + "/" + f; + } + + return addFilesToDocument(pDocument, fileNames); + +} + + +UBDocumentProxy* UBDocumentManager::importDir(const QDir& pDir, const QString& pGroup) +{ + UBDocumentProxy* doc = UBPersistenceManager::persistenceManager()->createDocument(pGroup, pDir.dirName()); + + int result = addImageDirToDocument(pDir, doc); + + if (result > 0) + { + doc->setMetaData(UBSettings::documentGroupName, pGroup); + doc->setMetaData(UBSettings::documentName, pDir.dirName()); + + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(doc); + + UBApplication::showMessage(tr("File %1 saved").arg(pDir.dirName())); + + } + else + { + UBPersistenceManager::persistenceManager()->deleteDocument(doc); + } + + return doc; +} + + +QList UBDocumentManager::supportedExportAdaptors() +{ + return mExportAdaptors; +} + +void UBDocumentManager::emitDocumentUpdated(UBDocumentProxy* pDocument) +{ + emit documentUpdated(pDocument); +} diff --git a/src/desktop/UBWindowCapture_mac.mm b/src/desktop/UBWindowCapture_mac.mm index e7592b96..62a60b40 100644 --- a/src/desktop/UBWindowCapture_mac.mm +++ b/src/desktop/UBWindowCapture_mac.mm @@ -28,22 +28,22 @@ UBWindowCapture::UBWindowCapture(UBDesktopAnnotationController *parent) - : QObject(parent) - , mParent(parent) + : QObject(parent) + , mParent(parent) { - // NOOP + // NOOP } UBWindowCapture::~UBWindowCapture() { - // NOOP + // NOOP } const QPixmap UBWindowCapture::getCapturedWindow() { - return mWindowPixmap; + return mWindowPixmap; } @@ -51,20 +51,20 @@ int UBWindowCapture::execute() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *path = [NSString pathWithComponents: [NSArray arrayWithObjects: NSTemporaryDirectory(), - [[NSString stringWithFormat:@"%d",[NSDate timeIntervalSinceReferenceDate]] stringByAppendingPathExtension:@"uninote"], - nil]]; - + [[NSString stringWithFormat:@"%d",[NSDate timeIntervalSinceReferenceDate]] stringByAppendingPathExtension:@"uninote"], + nil]]; + NSTask *task = [[NSTask alloc] init]; - NSArray *arguments = [NSArray arrayWithObjects: @"-i", @"-W", @"-m", @"-tpng", path, nil]; + NSArray *arguments = [NSArray arrayWithObjects: @"-i", @"-W", @"-m", @"-tpng", path, nil]; [task setLaunchPath: @"/usr/sbin/screencapture"]; [task setArguments: arguments]; - + [task launch]; [task waitUntilExit]; [task release]; - + QString resultPath = QString::fromUtf8([path UTF8String], strlen([path UTF8String])); - + mWindowPixmap.load(resultPath); QFile::remove(resultPath); diff --git a/src/document/UBDocumentContainer.cpp b/src/document/UBDocumentContainer.cpp index df2ee341..cb92fb67 100644 --- a/src/document/UBDocumentContainer.cpp +++ b/src/document/UBDocumentContainer.cpp @@ -19,128 +19,128 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBDocumentContainer.h" -#include "adaptors/UBThumbnailAdaptor.h" -#include "core/UBPersistenceManager.h" -#include "core/memcheck.h" - - -UBDocumentContainer::UBDocumentContainer(QObject * parent) - :QObject(parent) - ,mCurrentDocument(NULL) -{} - -UBDocumentContainer::~UBDocumentContainer() -{ - foreach(const QPixmap* pm, mDocumentThumbs){ - delete pm; - pm = NULL; - } -} - -void UBDocumentContainer::setDocument(UBDocumentProxy* document, bool forceReload) -{ - if (mCurrentDocument != document || forceReload) - { - mCurrentDocument = document; - reloadThumbnails(); - emit documentSet(mCurrentDocument); - } -} - -void UBDocumentContainer::duplicatePages(QList& pageIndexes) -{ - int offset = 0; - foreach(int sceneIndex, pageIndexes) - { - UBPersistenceManager::persistenceManager()->duplicateDocumentScene(mCurrentDocument, sceneIndex + offset); - offset++; - } -} - -bool UBDocumentContainer::movePageToIndex(int source, int target) -{ - if (source==0) - { - // Title page - cant be moved - return false; - } - UBPersistenceManager::persistenceManager()->moveSceneToIndex(mCurrentDocument, source, target); - deleteThumbPage(source); - insertThumbPage(target); - emit documentThumbnailsUpdated(this); - return true; -} - -void UBDocumentContainer::deletePages(QList& pageIndexes) -{ - UBPersistenceManager::persistenceManager()->deleteDocumentScenes(mCurrentDocument, pageIndexes); - int offset = 0; - foreach(int index, pageIndexes) - { - deleteThumbPage(index - offset); - offset++; - } - emit documentThumbnailsUpdated(this); -} - -void UBDocumentContainer::addPage(int index) -{ - UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mCurrentDocument, index); - insertThumbPage(index); - emit documentThumbnailsUpdated(this); -} - -void UBDocumentContainer::updatePage(int index) -{ - updateThumbPage(index); - emit documentThumbnailsUpdated(this); -} - -void UBDocumentContainer::deleteThumbPage(int index) -{ - mDocumentThumbs.removeAt(index); -} - -void UBDocumentContainer::updateThumbPage(int index) -{ - mDocumentThumbs[index] = UBThumbnailAdaptor::get(mCurrentDocument, index); - emit documentPageUpdated(index); -} - -void UBDocumentContainer::insertThumbPage(int index) -{ - mDocumentThumbs.insert(index, UBThumbnailAdaptor::get(mCurrentDocument, index)); -} - -void UBDocumentContainer::reloadThumbnails() -{ - if (mCurrentDocument) - { - UBThumbnailAdaptor::load(mCurrentDocument, mDocumentThumbs); - qDebug() << "Reloading Thumbnails. new mDocumentThumbs size: " << mDocumentThumbs.size(); - emit documentThumbnailsUpdated(this); - } -} - -int UBDocumentContainer::pageFromSceneIndex(int sceneIndex) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return sceneIndex; - return sceneIndex+1; -} - -int UBDocumentContainer::sceneIndexFromPage(int page) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return page; - return page-1; -} - -void UBDocumentContainer::addEmptyThumbPage() -{ - const QPixmap* pThumb = new QPixmap(); - mDocumentThumbs.append(pThumb); -} + + +#include "UBDocumentContainer.h" +#include "adaptors/UBThumbnailAdaptor.h" +#include "core/UBPersistenceManager.h" +#include "core/memcheck.h" + + +UBDocumentContainer::UBDocumentContainer(QObject * parent) + :QObject(parent) + ,mCurrentDocument(NULL) +{} + +UBDocumentContainer::~UBDocumentContainer() +{ + foreach(const QPixmap* pm, mDocumentThumbs){ + delete pm; + pm = NULL; + } +} + +void UBDocumentContainer::setDocument(UBDocumentProxy* document, bool forceReload) +{ + if (mCurrentDocument != document || forceReload) + { + mCurrentDocument = document; + reloadThumbnails(); + emit documentSet(mCurrentDocument); + } +} + +void UBDocumentContainer::duplicatePages(QList& pageIndexes) +{ + int offset = 0; + foreach(int sceneIndex, pageIndexes) + { + UBPersistenceManager::persistenceManager()->duplicateDocumentScene(mCurrentDocument, sceneIndex + offset); + offset++; + } +} + +bool UBDocumentContainer::movePageToIndex(int source, int target) +{ + if (source==0) + { + // Title page - cant be moved + return false; + } + UBPersistenceManager::persistenceManager()->moveSceneToIndex(mCurrentDocument, source, target); + deleteThumbPage(source); + insertThumbPage(target); + emit documentThumbnailsUpdated(this); + return true; +} + +void UBDocumentContainer::deletePages(QList& pageIndexes) +{ + UBPersistenceManager::persistenceManager()->deleteDocumentScenes(mCurrentDocument, pageIndexes); + int offset = 0; + foreach(int index, pageIndexes) + { + deleteThumbPage(index - offset); + offset++; + } + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::addPage(int index) +{ + UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mCurrentDocument, index); + insertThumbPage(index); + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::updatePage(int index) +{ + updateThumbPage(index); + emit documentThumbnailsUpdated(this); +} + +void UBDocumentContainer::deleteThumbPage(int index) +{ + mDocumentThumbs.removeAt(index); +} + +void UBDocumentContainer::updateThumbPage(int index) +{ + mDocumentThumbs[index] = UBThumbnailAdaptor::get(mCurrentDocument, index); + emit documentPageUpdated(index); +} + +void UBDocumentContainer::insertThumbPage(int index) +{ + mDocumentThumbs.insert(index, UBThumbnailAdaptor::get(mCurrentDocument, index)); +} + +void UBDocumentContainer::reloadThumbnails() +{ + if (mCurrentDocument) + { + UBThumbnailAdaptor::load(mCurrentDocument, mDocumentThumbs); + qDebug() << "Reloading Thumbnails. new mDocumentThumbs size: " << mDocumentThumbs.size(); + emit documentThumbnailsUpdated(this); + } +} + +int UBDocumentContainer::pageFromSceneIndex(int sceneIndex) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return sceneIndex; + return sceneIndex+1; +} + +int UBDocumentContainer::sceneIndexFromPage(int page) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return page; + return page-1; +} + +void UBDocumentContainer::addEmptyThumbPage() +{ + const QPixmap* pThumb = new QPixmap(); + mDocumentThumbs.append(pThumb); +} diff --git a/src/document/UBDocumentContainer.h b/src/document/UBDocumentContainer.h index 92555514..d2b7b045 100644 --- a/src/document/UBDocumentContainer.h +++ b/src/document/UBDocumentContainer.h @@ -19,54 +19,54 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBDOCUMENTCONTAINER_H_ -#define UBDOCUMENTCONTAINER_H_ - -#include -#include "UBDocumentProxy.h" - -class UBDocumentContainer : public QObject -{ - Q_OBJECT - - public: - UBDocumentContainer(QObject * parent = 0); - virtual ~UBDocumentContainer(); - - void setDocument(UBDocumentProxy* document, bool forceReload = false); - - UBDocumentProxy* selectedDocument(){return mCurrentDocument;} - int pageCount(){return mDocumentThumbs.size();} - const QPixmap* pageAt(int index){return mDocumentThumbs[index];} - - static int pageFromSceneIndex(int sceneIndex); - static int sceneIndexFromPage(int sceneIndex); - - void duplicatePages(QList& pageIndexes); - bool movePageToIndex(int source, int target); - void deletePages(QList& pageIndexes); - void addPage(int index); - void updatePage(int index); - void addEmptyThumbPage(); - - private: - UBDocumentProxy* mCurrentDocument; - QList mDocumentThumbs; - - - protected: - void deleteThumbPage(int index); - void updateThumbPage(int index); - void insertThumbPage(int index); - void reloadThumbnails(); - - signals: - void documentSet(UBDocumentProxy* document); - void documentPageUpdated(int index); - void documentThumbnailsUpdated(UBDocumentContainer* source); -}; - - -#endif /* UBDOCUMENTPROXY_H_ */ + + +#ifndef UBDOCUMENTCONTAINER_H_ +#define UBDOCUMENTCONTAINER_H_ + +#include +#include "UBDocumentProxy.h" + +class UBDocumentContainer : public QObject +{ + Q_OBJECT + + public: + UBDocumentContainer(QObject * parent = 0); + virtual ~UBDocumentContainer(); + + void setDocument(UBDocumentProxy* document, bool forceReload = false); + + UBDocumentProxy* selectedDocument(){return mCurrentDocument;} + int pageCount(){return mDocumentThumbs.size();} + const QPixmap* pageAt(int index){return mDocumentThumbs[index];} + + static int pageFromSceneIndex(int sceneIndex); + static int sceneIndexFromPage(int sceneIndex); + + void duplicatePages(QList& pageIndexes); + bool movePageToIndex(int source, int target); + void deletePages(QList& pageIndexes); + void addPage(int index); + void updatePage(int index); + void addEmptyThumbPage(); + + private: + UBDocumentProxy* mCurrentDocument; + QList mDocumentThumbs; + + + protected: + void deleteThumbPage(int index); + void updateThumbPage(int index); + void insertThumbPage(int index); + void reloadThumbnails(); + + signals: + void documentSet(UBDocumentProxy* document); + void documentPageUpdated(int index); + void documentThumbnailsUpdated(UBDocumentContainer* source); +}; + + +#endif /* UBDOCUMENTPROXY_H_ */ diff --git a/src/document/UBDocumentController.cpp b/src/document/UBDocumentController.cpp index 30cd7eed..d06c11cc 100644 --- a/src/document/UBDocumentController.cpp +++ b/src/document/UBDocumentController.cpp @@ -19,1697 +19,1697 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBDocumentController.h" - -#include -#include - -#include "frameworks/UBFileSystemUtils.h" -#include "frameworks/UBStringUtils.h" -#include "frameworks/UBPlatformUtils.h" - -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBDocumentManager.h" -#include "core/UBApplicationController.h" -#include "core/UBSettings.h" -#include "core/UBSetting.h" - -#include "adaptors/UBExportPDF.h" -#include "adaptors/UBThumbnailAdaptor.h" - -#include "adaptors/UBMetadataDcSubsetAdaptor.h" - -#include "board/UBBoardController.h" -#include "board/UBBoardPaletteManager.h" -#include "board/UBDrawingController.h" - - -#include "gui/UBThumbnailView.h" -#include "gui/UBDocumentTreeWidget.h" -#include "gui/UBMousePressFilter.h" -#include "gui/UBMessageWindow.h" -#include "gui/UBMainWindow.h" -#include "gui/UBDocumentToolsPalette.h" - -#include "domain/UBGraphicsScene.h" -#include "domain/UBGraphicsSvgItem.h" -#include "domain/UBGraphicsPixmapItem.h" - -#include "document/UBDocumentProxy.h" - -#include "ui_documents.h" -#include "ui_mainWindow.h" - -#include "core/memcheck.h" - -UBDocumentController::UBDocumentController(UBMainWindow* mainWindow) - : UBDocumentContainer(mainWindow->centralWidget()) - , mSelectionType(None) - , mParentWidget(mainWindow->centralWidget()) - , mBoardController(UBApplication::boardController) - , mDocumentUI(0) - , mMainWindow(mainWindow) - , mDocumentWidget(0) - , mIsClosing(false) - , mToolsPalette(0) - , mToolsPalettePositionned(false) - , mTrashTi(0) - , mDocumentTrashGroupName(tr("Trash")) - , mDefaultDocumentGroupName(tr("Untitled Documents")) -{ - setupViews(); - setupToolbar(); - this->selectDocument(UBApplication::boardController->selectedDocument()); - connect(this, SIGNAL(exportDone()), mMainWindow, SLOT(onExportDone())); - connect(this, SIGNAL(documentThumbnailsUpdated(UBDocumentContainer*)), this, SLOT(refreshDocumentThumbnailsView(UBDocumentContainer*))); -} - -UBDocumentController::~UBDocumentController() -{ - if (mDocumentUI) - delete mDocumentUI; -} - - -void UBDocumentController::createNewDocument() -{ - UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); - - if (group) - { - UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(group->groupName()); - - selectDocument(document); - } -} - - -UBDocumentProxyTreeItem* UBDocumentController::findDocument(UBDocumentProxy* proxy) -{ - QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); - - while (*it) - { - UBDocumentProxyTreeItem *treeItem = dynamic_cast((*it)); - - if (treeItem && treeItem->proxy() == proxy) - return treeItem; - - ++it; - } - - return 0; -} - - -void UBDocumentController::selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument) -{ - if (proxy==NULL) - { - setDocument(NULL); - return; - } - - QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); - - mDocumentUI->documentTreeWidget->clearSelection(); - mDocumentUI->documentTreeWidget->setCurrentItem(0); - - UBDocumentProxyTreeItem* selected = 0; - - while (*it) - { - UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); - - if (pi) - { - if (setAsCurrentDocument) - pi->setIcon(0, QIcon("")); - - pi->setSelected(false); - - if (pi->proxy() == proxy) - { - selected = pi; - } - } - - ++it; - } - - if (selected) - { - setDocument(proxy); - - selected->setSelected(true); - - selected->parent()->setExpanded(true); - selected->setText(0, proxy->name()); - - if (setAsCurrentDocument) - { - selected->setIcon(0, QIcon(":/images/currentDocument.png")); - if (proxy != mBoardController->selectedDocument()) - mBoardController->setActiveDocumentScene(proxy); - } - - mDocumentUI->documentTreeWidget->setCurrentItem(selected); - - mDocumentUI->documentTreeWidget->scrollToItem(selected); - - mSelectionType = Document; - } -} - - -void UBDocumentController::createNewDocumentGroup() -{ - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - int i = 1; - QString newFolderName = tr("New Folder"); - while (allGroupNames().contains(newFolderName)) - { - newFolderName = tr("New Folder") + " " + QVariant(i++).toString(); - } - docGroupItem->setGroupName(newFolderName); - - int trashIndex = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(mTrashTi); - - mDocumentUI->documentTreeWidget->insertTopLevelItem(trashIndex, docGroupItem); - mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); - mDocumentUI->documentTreeWidget->expandItem(docGroupItem); -} - - -UBDocumentProxy* UBDocumentController::selectedDocumentProxy() -{ - UBDocumentProxyTreeItem* proxyItem = selectedDocumentProxyTreeItem(); - return proxyItem ? proxyItem->proxy() : 0; -} - - -UBDocumentProxyTreeItem* UBDocumentController::selectedDocumentProxyTreeItem() -{ - if (mDocumentUI && mDocumentUI->documentTreeWidget) - { - QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); - - foreach (QTreeWidgetItem * item, selectedItems) - { - UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); - - if (proxyItem) - { - return proxyItem; - } - } - } - - return 0; -} - - -UBDocumentGroupTreeItem* UBDocumentController::selectedDocumentGroupTreeItem() -{ - QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); - - foreach (QTreeWidgetItem * item, selectedItems) - { - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - - if (groupItem) - { - return groupItem; - } - else - { - UBDocumentGroupTreeItem* parent = dynamic_cast(item->parent()); - if (parent) - { - return parent; - } - } - } - - return 0; -} - - -void UBDocumentController::itemSelectionChanged() -{ - reloadThumbnails(); - - if (selectedDocumentProxy()) - mSelectionType = Document; - else if (selectedDocumentGroupTreeItem()) - mSelectionType = Folder; - else - mSelectionType = None; - - selectionChanged(); -} - - -void UBDocumentController::setupViews() -{ - - if (!mDocumentWidget) - { - mDocumentWidget = new QWidget(mMainWindow->centralWidget()); - mMainWindow->addDocumentsWidget(mDocumentWidget); - - mDocumentUI = new Ui::documents(); - - mDocumentUI->setupUi(mDocumentWidget); - - int thumbWidth = UBSettings::settings()->documentThumbnailWidth->get().toInt(); - - mDocumentUI->documentZoomSlider->setValue(thumbWidth); - mDocumentUI->thumbnailWidget->setThumbnailWidth(thumbWidth); - - connect(mDocumentUI->documentZoomSlider, SIGNAL(valueChanged(int)), this, - SLOT(documentZoomSliderValueChanged(int))); - - connect(mMainWindow->actionOpen, SIGNAL(triggered()), this, SLOT(openSelectedItem())); - connect(mMainWindow->actionNewFolder, SIGNAL(triggered()), this, SLOT(createNewDocumentGroup())); - connect(mMainWindow->actionNewDocument, SIGNAL(triggered()), this, SLOT(createNewDocument())); - - connect(mMainWindow->actionImport, SIGNAL(triggered(bool)), this, SLOT(importFile())); - - QMenu* addMenu = new QMenu(mDocumentWidget); - mAddFolderOfImagesAction = addMenu->addAction(tr("Add Folder of Images")); - mAddImagesAction = addMenu->addAction(tr("Add Images")); - mAddFileToDocumentAction = addMenu->addAction(tr("Add Pages from File")); - - connect(mAddFolderOfImagesAction, SIGNAL(triggered(bool)), this, SLOT(addFolderOfImages())); - connect(mAddFileToDocumentAction, SIGNAL(triggered(bool)), this, SLOT(addFileToDocument())); - connect(mAddImagesAction, SIGNAL(triggered(bool)), this, SLOT(addImages())); - - foreach (QWidget* menuWidget, mMainWindow->actionDocumentAdd->associatedWidgets()) - { - QToolButton *tb = qobject_cast(menuWidget); - - if (tb && !tb->menu()) - { - tb->setObjectName("ubButtonMenu"); - tb->setPopupMode(QToolButton::InstantPopup); - - QMenu* menu = new QMenu(mDocumentWidget); - - menu->addAction(mAddFolderOfImagesAction); - menu->addAction(mAddImagesAction); - menu->addAction(mAddFileToDocumentAction); - - tb->setMenu(menu); - } - } - - QMenu* exportMenu = new QMenu(mDocumentWidget); - - UBDocumentManager *documentManager = UBDocumentManager::documentManager(); - for (int i = 0; i < documentManager->supportedExportAdaptors().length(); i++) - { - UBExportAdaptor* adaptor = documentManager->supportedExportAdaptors()[i]; - QAction *currentExportAction = exportMenu->addAction(adaptor->exportName()); - currentExportAction->setData(i); - connect(currentExportAction, SIGNAL(triggered (bool)), this, SLOT(exportDocument())); - exportMenu->addAction(currentExportAction); - } - - foreach (QWidget* menuWidget, mMainWindow->actionExport->associatedWidgets()) - { - QToolButton *tb = qobject_cast(menuWidget); - - if (tb && !tb->menu()) - { - tb->setObjectName("ubButtonMenu"); - tb->setPopupMode(QToolButton::InstantPopup); - - tb->setMenu(exportMenu); - } - } - -#ifdef Q_WS_MAC - mMainWindow->actionDelete->setShortcut(QKeySequence(Qt::Key_Backspace)); -#endif - - connect(mMainWindow->actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedItem())); - connect(mMainWindow->actionDuplicate, SIGNAL(triggered()), this, SLOT(duplicateSelectedItem())); - connect(mMainWindow->actionRename, SIGNAL(triggered()), this, SLOT(renameSelectedItem())); - connect(mMainWindow->actionAddToWorkingDocument, SIGNAL(triggered()), this, SLOT(addToDocument())); - - loadDocumentProxies(); - - mDocumentUI->documentTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); - mDocumentUI->documentTreeWidget->setDragEnabled(true); - mDocumentUI->documentTreeWidget->viewport()->setAcceptDrops(true); - mDocumentUI->documentTreeWidget->setDropIndicatorShown(true); - mDocumentUI->documentTreeWidget->setIndentation(18); // 1.5 * /resources/style/treeview-branch-closed.png width - mDocumentUI->documentTreeWidget->setDragDropMode(QAbstractItemView::InternalMove); - - connect(mDocumentUI->documentTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); - connect(mDocumentUI->documentTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int))); - connect(mDocumentUI->documentTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *, int))); - - connect(mDocumentUI->thumbnailWidget, SIGNAL(sceneDropped(UBDocumentProxy*, int, int)), this, SLOT(moveSceneToIndex ( UBDocumentProxy*, int, int))); - connect(mDocumentUI->thumbnailWidget, SIGNAL(resized()), this, SLOT(thumbnailViewResized())); - connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseDoubleClick(QGraphicsItem*, int)), this, SLOT(pageDoubleClicked(QGraphicsItem*, int))); - connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseClick(QGraphicsItem*, int)), this, SLOT(pageClicked(QGraphicsItem*, int))); - - connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentCreated(UBDocumentProxy*)), this, SLOT(addDocumentInTree(UBDocumentProxy*))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), this, SLOT(updateDocumentInTree(UBDocumentProxy*))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneCreated(UBDocumentProxy*, int)), this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneWillBeDeleted(UBDocumentProxy*, int)), this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); - - mDocumentUI->thumbnailWidget->setBackgroundBrush(UBSettings::documentViewLightColor); - - #ifdef Q_WS_MACX - mMessageWindow = new UBMessageWindow(NULL); - #else - mMessageWindow = new UBMessageWindow(mDocumentUI->thumbnailWidget); - #endif - - mMessageWindow->hide(); - - } -} - - -QWidget* UBDocumentController::controlView() -{ - return mDocumentWidget; -} - - -void UBDocumentController::setupToolbar() -{ - UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->documentToolBar, mMainWindow->actionBoard); - connect(mMainWindow->actionDocumentTools, SIGNAL(triggered()), this, SLOT(toggleDocumentToolsPalette())); -} - -void UBDocumentController::setupPalettes() -{ - - mToolsPalette = new UBDocumentToolsPalette(controlView()); - - mToolsPalette->hide(); - - bool showToolsPalette = !mToolsPalette->isEmpty(); - mMainWindow->actionDocumentTools->setVisible(showToolsPalette); - - if (showToolsPalette) - { - mMainWindow->actionDocumentTools->trigger(); - } -} - - -void UBDocumentController::show() -{ - selectDocument(mBoardController->selectedDocument()); - - selectionChanged(); - - if(!mToolsPalette) - setupPalettes(); -} - - -void UBDocumentController::hide() -{ - // NOOP -} - - -void UBDocumentController::openSelectedItem() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - if (selectedItems.count() > 0) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); - - if (thumb) - { - UBDocumentProxy* proxy = thumb->proxy(); - - if (proxy && isOKToOpenDocument(proxy)) - { - UBApplication::applicationController->showBoard(); - } - } - } - else - { - UBDocumentProxy* proxy = selectedDocumentProxy(); - - if (proxy && isOKToOpenDocument(proxy)) - { - mBoardController->setActiveDocumentScene(proxy); - UBApplication::applicationController->showBoard(); - } - } - - QApplication::restoreOverrideCursor(); -} - -void UBDocumentController::duplicateSelectedItem() -{ - if (UBApplication::applicationController->displayMode() != UBApplicationController::Document) - return; - - if (mSelectionType == Page) - { - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - QList selectedSceneIndexes; - foreach (QGraphicsItem *item, selectedItems) - { - UBSceneThumbnailPixmap *thumb = dynamic_cast(item); - if (thumb) - { - UBDocumentProxy *proxy = thumb->proxy(); - - if (proxy) - { - int sceneIndex = thumb->sceneIndex(); - selectedSceneIndexes << sceneIndex; - } - } - } - if (selectedSceneIndexes.count() > 0) - { - duplicatePages(selectedSceneIndexes); - emit documentThumbnailsUpdated(this); - selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(selectedDocument()); - mDocumentUI->thumbnailWidget->selectItemAt(selectedSceneIndexes.last() + selectedSceneIndexes.size()); - } - } - else - { - UBDocumentProxy* source = selectedDocumentProxy(); - UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); - - if (source && group) - { - QString docName = source->metaData(UBSettings::documentName).toString(); - - showMessage(tr("Duplicating Document %1").arg(docName), true); - - UBDocumentProxy* duplicatedDoc = UBPersistenceManager::persistenceManager()->duplicateDocument(source); - duplicatedDoc->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(duplicatedDoc); - - selectDocument(duplicatedDoc, false); - - showMessage(tr("Document %1 copied").arg(docName), false); - } - } -} - -void UBDocumentController::moveDocumentToTrash(UBDocumentGroupTreeItem* groupTi, UBDocumentProxyTreeItem *proxyTi) -{ - int index = proxyTi->parent()->indexOfChild(proxyTi); - index --; - - if (index >= 0) - { - if (proxyTi->proxy() == mBoardController->selectedDocument()) - { - selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(index))->proxy(), true); - } - else - proxyTi->parent()->child(index)->setSelected(true); - } - else if (proxyTi->parent()->childCount() > 1) - { - if (proxyTi->proxy() == mBoardController->selectedDocument()) - { - selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(1))->proxy(), true); - } - else - proxyTi->parent()->child(1)->setSelected(true); - } - else - { - if (proxyTi->proxy() == mBoardController->selectedDocument()) - { - bool documentFound = false; - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (!groupItem->isTrashFolder()) - { - for(int j=0; jchildCount(); j++) - { - if (((UBDocumentProxyTreeItem*)groupItem->child(j))->proxy() != mBoardController->selectedDocument()) - { - selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy(), true); - documentFound = true; - break; - } - } - } - if (documentFound) - break; - } - if (!documentFound) - { - UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(groupTi->groupName()); - selectDocument(document, true); - } - } - else - proxyTi->parent()->setSelected(true); - } - - QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); - proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); - - proxyTi->parent()->removeChild(proxyTi); - mTrashTi->addChild(proxyTi); - proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); -} - -void UBDocumentController::moveFolderToTrash(UBDocumentGroupTreeItem* groupTi) -{ - bool changeCurrentDocument = false; - for (int i = 0; i < groupTi->childCount(); i++) - { - UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); - if (proxyTi && proxyTi->proxy() && proxyTi->proxy() == mBoardController->selectedDocument()) - { - changeCurrentDocument = true; - break; - } - } - - QList toBeDeleted; - - for (int i = 0; i < groupTi->childCount(); i++) - { - UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); - if (proxyTi && proxyTi->proxy()) - toBeDeleted << proxyTi; - } - - for (int i = 0; i < toBeDeleted.count(); i++) - { - UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); - - showMessage(QString("Deleting %1").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString())); - // Move document to trash - QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); - proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); - - groupTi->removeChild(proxyTi); - mTrashTi->addChild(proxyTi); - proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); - - showMessage(QString("%1 deleted").arg(groupTi->groupName())); - } - - // dont remove default group - if (!groupTi->isDefaultFolder()) - { - int index = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(groupTi); - - if (index >= 0) - { - mDocumentUI->documentTreeWidget->takeTopLevelItem(index); - } - } - - if (changeCurrentDocument) - { - bool documentFound = false; - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (!groupItem->isTrashFolder() && groupItem != groupTi) - { - for(int j=0; jchildCount(); j++) - { - if (((UBDocumentProxyTreeItem*)groupItem->child(j))->proxy() != mBoardController->selectedDocument()) - { - selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy(), true); - documentFound = true; - break; - } - } - } - if (documentFound) - break; - } - if (!documentFound) - { - UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument( mDefaultDocumentGroupName ); - selectDocument(document, true); - } - } - - reloadThumbnails(); -} - -void UBDocumentController::deleteSelectedItem() -{ - if (mSelectionType == Page) - { - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - deletePages(selectedItems); - } - else - { - - UBDocumentProxyTreeItem *proxyTi = selectedDocumentProxyTreeItem(); - - UBDocumentGroupTreeItem* groupTi = selectedDocumentGroupTreeItem(); - - if (proxyTi && proxyTi->proxy() && proxyTi->parent()) - { - if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Document"), tr("Are you sure you want to remove the document '%1'?").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString()))) - { - if (proxyTi->parent() != mTrashTi) - { - moveDocumentToTrash(groupTi, proxyTi); - } - else - { - // We have to physically delete document - proxyTi->parent()->removeChild(proxyTi); - UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); - - if (mTrashTi->childCount()==0) - selectDocument(NULL); - else - selectDocument(((UBDocumentProxyTreeItem*)mTrashTi->child(0))->proxy()); - reloadThumbnails(); - } - } - } - else if (groupTi) - { - if (groupTi == mTrashTi) - { - if(UBApplication::mainWindow->yesNoQuestion(tr("Empty Trash"), tr("Are you sure you want to empty trash?"))) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QList toBeDeleted; - - for (int i = 0; i < groupTi->childCount(); i++) - { - UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); - if (proxyTi && proxyTi->proxy()) - toBeDeleted << proxyTi; - } - - showMessage(tr("Emptying trash")); - - for (int i = 0; i < toBeDeleted.count(); i++) - { - UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); - - proxyTi->parent()->removeChild(proxyTi); - UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); - } - - showMessage(tr("Emptied trash")); - - QApplication::restoreOverrideCursor(); - mMainWindow->actionDelete->setEnabled(false); - } - } - else - { - if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Folder"), tr("Are you sure you want to remove the folder '%1' and all its content?").arg(groupTi->groupName()))) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - moveFolderToTrash(groupTi); - QApplication::restoreOverrideCursor(); - } - } - } - } -} - - -void UBDocumentController::exportDocument() -{ - QAction *currentExportAction = qobject_cast(sender()); - QVariant actionData = currentExportAction->data(); - UBExportAdaptor* selectedExportAdaptor = UBDocumentManager::documentManager()->supportedExportAdaptors()[actionData.toInt()]; - - UBDocumentProxy* proxy = selectedDocumentProxy(); - - if (proxy) - { - selectedExportAdaptor->persist(proxy); - emit exportDone(); - } - else - { - showMessage(tr("No document selected!")); - } -} - - -void UBDocumentController::documentZoomSliderValueChanged (int value) -{ - mDocumentUI->thumbnailWidget->setThumbnailWidth(value); - - UBSettings::settings()->documentThumbnailWidth->set(value); -} - - -void UBDocumentController::loadDocumentProxies() -{ - QList > proxies = UBPersistenceManager::persistenceManager()->documentProxies; - - QStringList emptyGroupNames = UBSettings::settings()->value("Document/EmptyGroupNames", QStringList()).toStringList(); - - mDocumentUI->documentTreeWidget->clear(); - - QMap groupNamesMap; - - UBDocumentGroupTreeItem* emptyGroupNameTi = 0; - - mTrashTi = new UBDocumentGroupTreeItem(0, false); // deleted by the tree widget - mTrashTi->setGroupName(mDocumentTrashGroupName); - mTrashTi->setIcon(0, QIcon(":/images/trash.png")); - - foreach (QPointer proxy, proxies) - { - if (proxy) - { - QString docGroup = proxy->metaData(UBSettings::documentGroupName).toString(); - - bool isEmptyGroupName = false; - bool isInTrash = false; - - if (docGroup.isEmpty()) // #see https://trac.assembla.com/uniboard/ticket/426 - { - docGroup = mDefaultDocumentGroupName; - isEmptyGroupName = true; - } - else if (docGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) - { - isInTrash = true; - } - - QString docName = proxy->metaData(UBSettings::documentName).toString(); - - if (emptyGroupNames.contains(docGroup)) - emptyGroupNames.removeAll(docGroup); - - if (!groupNamesMap.contains(docGroup) && !isInTrash) - { - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0, !isEmptyGroupName); // deleted by the tree widget - groupNamesMap.insert(docGroup, docGroupItem); - docGroupItem->setGroupName(docGroup); - - if (isEmptyGroupName) - emptyGroupNameTi = docGroupItem; - } - - UBDocumentGroupTreeItem* docGroupItem; - if (isInTrash) - docGroupItem = mTrashTi; - else - docGroupItem = groupNamesMap.value(docGroup); - - QTreeWidgetItem* docItem = new UBDocumentProxyTreeItem(docGroupItem, proxy, !isInTrash); - docItem->setText(0, docName); - - if (mBoardController->selectedDocument() == proxy) - { - mDocumentUI->documentTreeWidget->expandItem(docGroupItem); - mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); - } - } - } - - foreach (const QString emptyGroupName, emptyGroupNames) - { - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - groupNamesMap.insert(emptyGroupName, docGroupItem); - docGroupItem->setGroupName(emptyGroupName); - } - - QList groupNamesList = groupNamesMap.keys(); - qSort(groupNamesList); - - foreach (const QString groupName, groupNamesList) - { - UBDocumentGroupTreeItem* ti = groupNamesMap.value(groupName); - - if (ti != emptyGroupNameTi) - mDocumentUI->documentTreeWidget->addTopLevelItem(ti); - } - - if (emptyGroupNameTi) - mDocumentUI->documentTreeWidget->addTopLevelItem(emptyGroupNameTi); - - mDocumentUI->documentTreeWidget->addTopLevelItem(mTrashTi); -} - - -void UBDocumentController::itemClicked(QTreeWidgetItem * item, int column ) -{ - Q_UNUSED(item); - Q_UNUSED(column); - - selectDocument(selectedDocumentProxy(), false); - itemSelectionChanged(); -} - - -void UBDocumentController::itemChanged(QTreeWidgetItem * item, int column) -{ - UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); - - disconnect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)) - , this, SLOT(updateDocumentInTree(UBDocumentProxy*))); - - if (proxyItem) - { - if (proxyItem->proxy()->metaData(UBSettings::documentName).toString() != item->text(column)) - { - proxyItem->proxy()->setMetaData(UBSettings::documentName, item->text(column)); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyItem->proxy()); - } - } - else - { - // it is a group - UBDocumentGroupTreeItem* editedGroup = dynamic_cast(item); - if (editedGroup) - { - for (int i = 0; i < item->childCount(); i++) - { - UBDocumentProxyTreeItem* childItem = dynamic_cast(item->child(i)); - - if (childItem) - { - QString groupName; - if (0 != (item->flags() & Qt::ItemIsEditable)) - { - childItem->proxy()->setMetaData(UBSettings::documentGroupName, item->text(column)); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(childItem->proxy()); - } - } - } - } - } - - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), - this, SLOT(updateDocumentInTree(UBDocumentProxy*))); -} - - -void UBDocumentController::importFile() -{ - UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); - UBDocumentManager *docManager = UBDocumentManager::documentManager(); - - if (group) - { - QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); - QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File"), - defaultPath, docManager->importFileFilter()); - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QApplication::processEvents(); - QFileInfo fileInfo(filePath); - UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); - - if (filePath.length() > 0) - { - UBDocumentProxy* createdDocument = 0; - QApplication::processEvents(); - QFile selectedFile(filePath); - - QString groupName = group->groupName(); - - if (groupName == mDefaultDocumentGroupName || fileInfo.suffix() != "ubz") - groupName = ""; - - showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); - - createdDocument = docManager->importFile(selectedFile, groupName); - - if (createdDocument) - { - selectDocument(createdDocument, false); - } - else - { - showMessage(tr("Failed to import file ... ")); - } - } - - QApplication::restoreOverrideCursor(); - } -} - -void UBDocumentController::addFolderOfImages() -{ - UBDocumentProxy* document = selectedDocumentProxy(); - - if (document) - { - QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); - - QString imagesDir = QFileDialog::getExistingDirectory(mParentWidget, tr("Import all Images from Folder"), defaultPath); - QDir parentImageDir(imagesDir); - parentImageDir.cdUp(); - - UBSettings::settings()->lastImportFolderPath->set(QVariant(parentImageDir.absolutePath())); - - if (imagesDir.length() > 0) - { - QDir dir(imagesDir); - - int importedImageNumber - = UBDocumentManager::documentManager()->addImageDirToDocument(dir, document); - - if (importedImageNumber == 0) - { - showMessage(tr("Folder does not contain any image files")); - UBApplication::applicationController->showDocument(); - } - else - { - document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(document); - reloadThumbnails(); - } - } - } -} - - -void UBDocumentController::addFileToDocument() -{ - UBDocumentProxy* document = selectedDocumentProxy(); - - if (document) - { - addFileToDocument(document); - reloadThumbnails(); - } -} - - -bool UBDocumentController::addFileToDocument(UBDocumentProxy* document) -{ - QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); - QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File"), defaultPath, UBDocumentManager::documentManager()->importFileFilter()); - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QApplication::processEvents(); - - QFileInfo fileInfo(filePath); - UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); - - bool success = false; - - if (filePath.length() > 0) - { - QApplication::processEvents(); // NOTE: We performed this just a few lines before. Is it really necessary to do it again here?? - QFile selectedFile(filePath); - - showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); - - QStringList fileNames; - fileNames << filePath; - success = UBDocumentManager::documentManager()->addFilesToDocument(document, fileNames); - - if (success) - { - document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(document); - } - else - { - showMessage(tr("Failed to import file ... ")); - } - } - - QApplication::restoreOverrideCursor(); - - return success; -} - - -void UBDocumentController::moveSceneToIndex(UBDocumentProxy* proxy, int source, int target) -{ - if (UBDocumentContainer::movePageToIndex(source, target)) - { - proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(proxy); - - mDocumentUI->thumbnailWidget->hightlightItem(target); - } -} - - -void UBDocumentController::thumbnailViewResized() -{ - int maxWidth = qMin(UBSettings::maxThumbnailWidth, mDocumentUI->thumbnailWidget->width()); - - mDocumentUI->documentZoomSlider->setMaximum(maxWidth); -} - - -void UBDocumentController::pageSelectionChanged() -{ - if (mIsClosing) - return; - - bool pageSelected = mDocumentUI->thumbnailWidget->selectedItems().count() > 0; - - if (pageSelected) - mSelectionType = Page; - else - mSelectionType = None; - - selectionChanged(); -} - - -void UBDocumentController::selectionChanged() -{ - if (mIsClosing) - return; - - int pageCount = -1; - - UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); - - if (proxyTi && proxyTi->proxy()) - pageCount = proxyTi->proxy()->pageCount(); - - bool pageSelected = (mSelectionType == Page); - bool groupSelected = (mSelectionType == Folder); - bool docSelected = (mSelectionType == Document); - - bool trashSelected = false; - if (groupSelected && selectedDocumentGroupTreeItem()) - trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); - - if ((docSelected || pageSelected) && proxyTi) - trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); - - bool defaultGroupSelected = false; - if (groupSelected && selectedDocumentGroupTreeItem()) - defaultGroupSelected = selectedDocumentGroupTreeItem()->isDefaultFolder(); - - mMainWindow->actionNewDocument->setEnabled((groupSelected || docSelected || pageSelected) && !trashSelected); - mMainWindow->actionExport->setEnabled((docSelected || pageSelected) && !trashSelected); - bool firstSceneSelected = false; - if(docSelected) - mMainWindow->actionDuplicate->setEnabled(!trashSelected); - else if(pageSelected){ - QList selection = mDocumentUI->thumbnailWidget->selectedItems(); - if(pageCount == 1) - mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(0))); - else{ - for(int i = 0; i < selection.count() && !firstSceneSelected; i += 1){ - if(dynamic_cast(selection.at(i))->sceneIndex() == 0){ - mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(0))); - firstSceneSelected = true; - } - } - if(!firstSceneSelected) - mMainWindow->actionDuplicate->setEnabled(!trashSelected); - } - } - else - mMainWindow->actionDuplicate->setEnabled(false); - - mMainWindow->actionOpen->setEnabled((docSelected || pageSelected) && !trashSelected); - mMainWindow->actionRename->setEnabled((groupSelected || docSelected) && !trashSelected && !defaultGroupSelected); - - mMainWindow->actionAddToWorkingDocument->setEnabled(pageSelected - && !(selectedDocumentProxy() == mBoardController->selectedDocument()) && !trashSelected); - - bool deleteEnabled = false; - if (trashSelected) - { - if (docSelected) - deleteEnabled = true; - else if (groupSelected && selectedDocumentGroupTreeItem()) - { - if (selectedDocumentGroupTreeItem()->childCount() > 0) - deleteEnabled = true; - } - } - else - { - deleteEnabled = groupSelected || docSelected || pageSelected; - } - - if (pageSelected && (pageCount == mDocumentUI->thumbnailWidget->selectedItems().count())) - { - deleteEnabled = false; - } - - if(pageSelected && firstSceneSelected) - deleteEnabled = false; - - mMainWindow->actionDelete->setEnabled(deleteEnabled); - - if (trashSelected) - { - if (docSelected) - { - mMainWindow->actionDelete->setIcon(QIcon(":/images/toolbar/deleteDocument.png")); - mMainWindow->actionDelete->setText(tr("Delete")); - } - else - { - mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); - mMainWindow->actionDelete->setText(tr("Empty")); - } - } - else - { - mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); - mMainWindow->actionDelete->setText(tr("Trash")); - } - - mMainWindow->actionDocumentAdd->setEnabled((docSelected || pageSelected) && !trashSelected); - mMainWindow->actionImport->setEnabled(!trashSelected); - -} - - -void UBDocumentController::documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex) -{ - Q_UNUSED(pSceneIndex); - - if (proxy == selectedDocumentProxy()) - { - reloadThumbnails(); - } -} - - -void UBDocumentController::pageDoubleClicked(QGraphicsItem* item, int index) -{ - Q_UNUSED(item); - Q_UNUSED(index); - - bool pageSelected = (mSelectionType == Page); - bool groupSelected = (mSelectionType == Folder); - bool docSelected = (mSelectionType == Document); - - bool trashSelected = false; - if (groupSelected && selectedDocumentGroupTreeItem()) - trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); - UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); - if ((docSelected || pageSelected) && proxyTi) - trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); - if (trashSelected) return; - - openSelectedItem(); -} - - -void UBDocumentController::pageClicked(QGraphicsItem* item, int index) -{ - Q_UNUSED(item); - Q_UNUSED(index); - - pageSelectionChanged(); -} - - -void UBDocumentController::closing() -{ - mIsClosing = true; - - QStringList emptyGroups; - - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - - if (item->childCount() == 0) - { - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (groupItem) - { - QString groupName = groupItem->groupName(); - if (!emptyGroups.contains(groupName) && groupName != mDocumentTrashGroupName) - emptyGroups << groupName; - } - } - } - - UBSettings::settings()->setValue("Document/EmptyGroupNames", emptyGroups); - -} - -void UBDocumentController::addToDocument() -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - if (selectedItems.count() > 0) - { - int oldActiveSceneIndex = mBoardController->activeSceneIndex(); - - QList > pageInfoList; - - foreach (QGraphicsItem* item, selectedItems) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (item); - - if (thumb && thumb->proxy()) - { - QPair pageInfo(thumb->proxy(), thumb->sceneIndex()); - pageInfoList << pageInfo; - } - } - - for (int i = 0; i < pageInfoList.length(); i++) - { - mBoardController->addScene(pageInfoList.at(i).first, pageInfoList.at(i).second, true); - } - - int newActiveSceneIndex = selectedItems.count() == mBoardController->selectedDocument()->pageCount() ? 0 : oldActiveSceneIndex + 1; - mDocumentUI->thumbnailWidget->selectItemAt(newActiveSceneIndex, false); - selectDocument(mBoardController->selectedDocument()); - mBoardController->selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(mBoardController->selectedDocument()); - - UBApplication::applicationController->showBoard(); - } - - QApplication::restoreOverrideCursor(); -} - - -void UBDocumentController::addDocumentInTree(UBDocumentProxy* pDocument) -{ - QString documentName = pDocument->name(); - QString documentGroup = pDocument->groupName(); - if (documentGroup.isEmpty()) - { - documentGroup = mDefaultDocumentGroupName; - } - UBDocumentGroupTreeItem* group = 0; - if (documentGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) - { - group = mTrashTi; - } - else - { - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (groupItem->groupName() == documentGroup) - { - group = groupItem; - break; - } - } - } - - if (group == 0) - { - group = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - group->setGroupName(documentGroup); - mDocumentUI->documentTreeWidget->addTopLevelItem(group); - } - - UBDocumentProxyTreeItem *ti = new UBDocumentProxyTreeItem(group, pDocument, !group->isTrashFolder()); - ti->setText(0, documentName); -} - - -void UBDocumentController::updateDocumentInTree(UBDocumentProxy* pDocument) -{ - QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); - while (*it) - { - UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); - - if (pi && pi->proxy() == pDocument) - { - pi->setText(0, pDocument->name()); - break; - } - ++it; - } -} - - -QStringList UBDocumentController::allGroupNames() -{ - QStringList result; - - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - result << groupItem->groupName(); - } - - return result; -} - - -void UBDocumentController::renameSelectedItem() -{ - if (mDocumentUI->documentTreeWidget->selectedItems().count() > 0) - mDocumentUI->documentTreeWidget->editItem(mDocumentUI->documentTreeWidget->selectedItems().at(0)); -} - - -bool UBDocumentController::isOKToOpenDocument(UBDocumentProxy* proxy) -{ - //check version - QString docVersion = proxy->metaData(UBSettings::documentVersion).toString(); - - if (docVersion.isEmpty() || docVersion.startsWith("4.1") || docVersion.startsWith("4.2") - || docVersion.startsWith("4.3") || docVersion.startsWith("4.4") || docVersion.startsWith("4.5") - || docVersion.startsWith("4.6")) // TODO UB 4.7 update if necessary - { - return true; - } - else - { - if (UBApplication::mainWindow->yesNoQuestion(tr("Open Document"), - tr("The document '%1' has been generated with a newer version of Sankore (%2). By opening it, you may lose some information. Do you want to proceed?") - .arg(proxy->metaData(UBSettings::documentName).toString()) - .arg(docVersion))) - { - return true; - } - else - { - return false; - } - } -} - - -void UBDocumentController::showMessage(const QString& message, bool showSpinningWheel) -{ - if (mMessageWindow) - { - int margin = UBSettings::boardMargin; - - QRect newSize = mDocumentUI->thumbnailWidget->geometry(); - - #ifdef Q_WS_MACX - QPoint point(newSize.left() + margin, newSize.bottom() - mMessageWindow->height() - margin); - mMessageWindow->move(mDocumentUI->thumbnailWidget->mapToGlobal(point)); - #else - mMessageWindow->move(margin, newSize.height() - mMessageWindow->height() - margin); - #endif - - mMessageWindow->showMessage(message, showSpinningWheel); - } -} - - -void UBDocumentController::hideMessage() -{ - if (mMessageWindow) - mMessageWindow->hideMessage(); -} - - -void UBDocumentController::addImages() -{ - UBDocumentProxy* document = selectedDocumentProxy(); - - if (document) - { - QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); - - QString extensions; - - foreach (QString ext, UBSettings::settings()->imageFileExtensions) - { - extensions += " *."; - extensions += ext; - } - - QStringList images = QFileDialog::getOpenFileNames(mParentWidget, tr("Add all Images to Document"), - defaultPath, tr("All Images (%1)").arg(extensions)); - - if (images.length() > 0) - { - QFileInfo firstImage(images.at(0)); - - UBSettings::settings()->lastImportFolderPath->set(QVariant(firstImage.absoluteDir().absolutePath())); - - int importedImageNumber - = UBDocumentManager::documentManager()->addFilesToDocument(document, images); - - if (importedImageNumber == 0) - { - UBApplication::showMessage(tr("Selection does not contain any image files!")); - UBApplication::applicationController->showDocument(); - } - else - { - document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(document); - reloadThumbnails(); - } - } - } -} - - -void UBDocumentController::toggleDocumentToolsPalette() -{ - if (!mToolsPalette->isVisible() && !mToolsPalettePositionned) - { - mToolsPalette->adjustSizeAndPosition(); - int left = controlView()->width() - 20 - mToolsPalette->width(); - int top = (controlView()->height() - mToolsPalette->height()) / 2; - - mToolsPalette->setCustomPosition(true); - mToolsPalette->move(left, top); - - mToolsPalettePositionned = true; - } - - bool visible = mToolsPalette->isVisible(); - mToolsPalette->setVisible(!visible); -} - - -void UBDocumentController::cut() -{ - // TODO - implemented me -} - - -void UBDocumentController::copy() -{ - // TODO - implemented me -} - - -void UBDocumentController::paste() -{ - // TODO - implemented me -} - - -void UBDocumentController::focusChanged(QWidget *old, QWidget *current) -{ - Q_UNUSED(old); - - if (current == mDocumentUI->thumbnailWidget) - { - if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) - mSelectionType = Page; - else - mSelectionType = None; - } - else if (current == mDocumentUI->documentTreeWidget) - { - if (selectedDocumentProxy()) - mSelectionType = Document; - else if (selectedDocumentGroupTreeItem()) - mSelectionType = Folder; - else - mSelectionType = None; - } - else if (current == mDocumentUI->documentZoomSlider) - { - if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) - mSelectionType = Page; - else - mSelectionType = None; - } - else - { - if (old != mDocumentUI->thumbnailWidget && - old != mDocumentUI->documentTreeWidget && - old != mDocumentUI->documentZoomSlider) - { - mSelectionType = None; - } - } - - selectionChanged(); -} - -void UBDocumentController::deletePages(QList itemsToDelete) -{ - if (itemsToDelete.count() > 0) - { - QList sceneIndexes; - UBDocumentProxy* proxy = 0; - - foreach (QGraphicsItem* item, itemsToDelete) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (item); - - if (thumb) - { - proxy = thumb->proxy(); - if (proxy) - { - sceneIndexes.append(thumb->sceneIndex()); - } - } - } - - if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Page"), tr("Are you sure you want to remove %n page(s) from the selected document '%1'?", "", sceneIndexes.count()).arg(proxy->metaData(UBSettings::documentName).toString()))) - { - UBDocumentContainer::deletePages(sceneIndexes); - - proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); - UBMetadataDcSubsetAdaptor::persist(proxy); - - int minIndex = proxy->pageCount() - 1; - foreach (int i, sceneIndexes) - minIndex = qMin(i, minIndex); - - mDocumentUI->thumbnailWidget->selectItemAt(minIndex); - } - } -} - -int UBDocumentController::getSelectedItemIndex() -{ - QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); - - if (selectedItems.count() > 0) - { - UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); - return thumb->sceneIndex(); - } - else return -1; -} - -bool UBDocumentController::pageCanBeMovedUp(int page) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return page >= 2; - else - return page >= 1; -} - -bool UBDocumentController::pageCanBeMovedDown(int page) -{ - if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) - return page != 0 && page < selectedDocument()->pageCount() - 1; - else - return page < selectedDocument()->pageCount() - 1; -} - -bool UBDocumentController::pageCanBeDuplicated(int page) -{ - return page != 0; -} - -bool UBDocumentController::pageCanBeDeleted(int page) -{ - return page != 0; -} - -void UBDocumentController::refreshDocumentThumbnailsView(UBDocumentContainer*) -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - QList items; - QList itemsPath; - - UBDocumentProxy *proxy = selectedDocumentProxy(); - QGraphicsPixmapItem *selection = 0; - - QStringList labels; - - if (proxy) - { - setDocument(proxy); - - for (int i = 0; i < selectedDocument()->pageCount(); i++) - { - const QPixmap* pix = pageAt(i); - QGraphicsPixmapItem *pixmapItem = new UBSceneThumbnailPixmap(*pix, proxy, i); // deleted by the tree widget - - if (proxy == mBoardController->selectedDocument() && mBoardController->activeSceneIndex() == i) - { - selection = pixmapItem; - } - - items << pixmapItem; - int pageIndex = pageFromSceneIndex(i); - if(pageIndex) - labels << tr("Page %1").arg(pageIndex); - else - labels << tr("Title page"); - - itemsPath.append(QUrl::fromLocalFile(proxy->persistencePath() + QString("/pages/%1").arg(UBDocumentContainer::pageFromSceneIndex(i)))); - } - } - - mDocumentUI->thumbnailWidget->setGraphicsItems(items, itemsPath, labels, UBApplication::mimeTypeUniboardPage); - - UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); - if (proxyTi && (proxyTi->parent() == mTrashTi)) - mDocumentUI->thumbnailWidget->setDragEnabled(false); - else - mDocumentUI->thumbnailWidget->setDragEnabled(true); - - mDocumentUI->thumbnailWidget->ensureVisible(0, 0, 10, 10); - - if (selection) { - disconnect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); - UBSceneThumbnailPixmap *currentScene = dynamic_cast(selection); - if (currentScene) - mDocumentUI->thumbnailWidget->hightlightItem(currentScene->sceneIndex()); - connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); - } - - QApplication::restoreOverrideCursor(); -} + + +#include "UBDocumentController.h" + +#include +#include + +#include "frameworks/UBFileSystemUtils.h" +#include "frameworks/UBStringUtils.h" +#include "frameworks/UBPlatformUtils.h" + +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBDocumentManager.h" +#include "core/UBApplicationController.h" +#include "core/UBSettings.h" +#include "core/UBSetting.h" + +#include "adaptors/UBExportPDF.h" +#include "adaptors/UBThumbnailAdaptor.h" + +#include "adaptors/UBMetadataDcSubsetAdaptor.h" + +#include "board/UBBoardController.h" +#include "board/UBBoardPaletteManager.h" +#include "board/UBDrawingController.h" + + +#include "gui/UBThumbnailView.h" +#include "gui/UBDocumentTreeWidget.h" +#include "gui/UBMousePressFilter.h" +#include "gui/UBMessageWindow.h" +#include "gui/UBMainWindow.h" +#include "gui/UBDocumentToolsPalette.h" + +#include "domain/UBGraphicsScene.h" +#include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsPixmapItem.h" + +#include "document/UBDocumentProxy.h" + +#include "ui_documents.h" +#include "ui_mainWindow.h" + +#include "core/memcheck.h" + +UBDocumentController::UBDocumentController(UBMainWindow* mainWindow) + : UBDocumentContainer(mainWindow->centralWidget()) + , mSelectionType(None) + , mParentWidget(mainWindow->centralWidget()) + , mBoardController(UBApplication::boardController) + , mDocumentUI(0) + , mMainWindow(mainWindow) + , mDocumentWidget(0) + , mIsClosing(false) + , mToolsPalette(0) + , mToolsPalettePositionned(false) + , mTrashTi(0) + , mDocumentTrashGroupName(tr("Trash")) + , mDefaultDocumentGroupName(tr("Untitled Documents")) +{ + setupViews(); + setupToolbar(); + this->selectDocument(UBApplication::boardController->selectedDocument()); + connect(this, SIGNAL(exportDone()), mMainWindow, SLOT(onExportDone())); + connect(this, SIGNAL(documentThumbnailsUpdated(UBDocumentContainer*)), this, SLOT(refreshDocumentThumbnailsView(UBDocumentContainer*))); +} + +UBDocumentController::~UBDocumentController() +{ + if (mDocumentUI) + delete mDocumentUI; +} + + +void UBDocumentController::createNewDocument() +{ + UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); + + if (group) + { + UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(group->groupName()); + + selectDocument(document); + } +} + + +UBDocumentProxyTreeItem* UBDocumentController::findDocument(UBDocumentProxy* proxy) +{ + QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); + + while (*it) + { + UBDocumentProxyTreeItem *treeItem = dynamic_cast((*it)); + + if (treeItem && treeItem->proxy() == proxy) + return treeItem; + + ++it; + } + + return 0; +} + + +void UBDocumentController::selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument) +{ + if (proxy==NULL) + { + setDocument(NULL); + return; + } + + QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); + + mDocumentUI->documentTreeWidget->clearSelection(); + mDocumentUI->documentTreeWidget->setCurrentItem(0); + + UBDocumentProxyTreeItem* selected = 0; + + while (*it) + { + UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); + + if (pi) + { + if (setAsCurrentDocument) + pi->setIcon(0, QIcon("")); + + pi->setSelected(false); + + if (pi->proxy() == proxy) + { + selected = pi; + } + } + + ++it; + } + + if (selected) + { + setDocument(proxy); + + selected->setSelected(true); + + selected->parent()->setExpanded(true); + selected->setText(0, proxy->name()); + + if (setAsCurrentDocument) + { + selected->setIcon(0, QIcon(":/images/currentDocument.png")); + if (proxy != mBoardController->selectedDocument()) + mBoardController->setActiveDocumentScene(proxy); + } + + mDocumentUI->documentTreeWidget->setCurrentItem(selected); + + mDocumentUI->documentTreeWidget->scrollToItem(selected); + + mSelectionType = Document; + } +} + + +void UBDocumentController::createNewDocumentGroup() +{ + UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget + int i = 1; + QString newFolderName = tr("New Folder"); + while (allGroupNames().contains(newFolderName)) + { + newFolderName = tr("New Folder") + " " + QVariant(i++).toString(); + } + docGroupItem->setGroupName(newFolderName); + + int trashIndex = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(mTrashTi); + + mDocumentUI->documentTreeWidget->insertTopLevelItem(trashIndex, docGroupItem); + mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); + mDocumentUI->documentTreeWidget->expandItem(docGroupItem); +} + + +UBDocumentProxy* UBDocumentController::selectedDocumentProxy() +{ + UBDocumentProxyTreeItem* proxyItem = selectedDocumentProxyTreeItem(); + return proxyItem ? proxyItem->proxy() : 0; +} + + +UBDocumentProxyTreeItem* UBDocumentController::selectedDocumentProxyTreeItem() +{ + if (mDocumentUI && mDocumentUI->documentTreeWidget) + { + QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); + + foreach (QTreeWidgetItem * item, selectedItems) + { + UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); + + if (proxyItem) + { + return proxyItem; + } + } + } + + return 0; +} + + +UBDocumentGroupTreeItem* UBDocumentController::selectedDocumentGroupTreeItem() +{ + QList selectedItems = mDocumentUI->documentTreeWidget->selectedItems(); + + foreach (QTreeWidgetItem * item, selectedItems) + { + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + + if (groupItem) + { + return groupItem; + } + else + { + UBDocumentGroupTreeItem* parent = dynamic_cast(item->parent()); + if (parent) + { + return parent; + } + } + } + + return 0; +} + + +void UBDocumentController::itemSelectionChanged() +{ + reloadThumbnails(); + + if (selectedDocumentProxy()) + mSelectionType = Document; + else if (selectedDocumentGroupTreeItem()) + mSelectionType = Folder; + else + mSelectionType = None; + + selectionChanged(); +} + + +void UBDocumentController::setupViews() +{ + + if (!mDocumentWidget) + { + mDocumentWidget = new QWidget(mMainWindow->centralWidget()); + mMainWindow->addDocumentsWidget(mDocumentWidget); + + mDocumentUI = new Ui::documents(); + + mDocumentUI->setupUi(mDocumentWidget); + + int thumbWidth = UBSettings::settings()->documentThumbnailWidth->get().toInt(); + + mDocumentUI->documentZoomSlider->setValue(thumbWidth); + mDocumentUI->thumbnailWidget->setThumbnailWidth(thumbWidth); + + connect(mDocumentUI->documentZoomSlider, SIGNAL(valueChanged(int)), this, + SLOT(documentZoomSliderValueChanged(int))); + + connect(mMainWindow->actionOpen, SIGNAL(triggered()), this, SLOT(openSelectedItem())); + connect(mMainWindow->actionNewFolder, SIGNAL(triggered()), this, SLOT(createNewDocumentGroup())); + connect(mMainWindow->actionNewDocument, SIGNAL(triggered()), this, SLOT(createNewDocument())); + + connect(mMainWindow->actionImport, SIGNAL(triggered(bool)), this, SLOT(importFile())); + + QMenu* addMenu = new QMenu(mDocumentWidget); + mAddFolderOfImagesAction = addMenu->addAction(tr("Add Folder of Images")); + mAddImagesAction = addMenu->addAction(tr("Add Images")); + mAddFileToDocumentAction = addMenu->addAction(tr("Add Pages from File")); + + connect(mAddFolderOfImagesAction, SIGNAL(triggered(bool)), this, SLOT(addFolderOfImages())); + connect(mAddFileToDocumentAction, SIGNAL(triggered(bool)), this, SLOT(addFileToDocument())); + connect(mAddImagesAction, SIGNAL(triggered(bool)), this, SLOT(addImages())); + + foreach (QWidget* menuWidget, mMainWindow->actionDocumentAdd->associatedWidgets()) + { + QToolButton *tb = qobject_cast(menuWidget); + + if (tb && !tb->menu()) + { + tb->setObjectName("ubButtonMenu"); + tb->setPopupMode(QToolButton::InstantPopup); + + QMenu* menu = new QMenu(mDocumentWidget); + + menu->addAction(mAddFolderOfImagesAction); + menu->addAction(mAddImagesAction); + menu->addAction(mAddFileToDocumentAction); + + tb->setMenu(menu); + } + } + + QMenu* exportMenu = new QMenu(mDocumentWidget); + + UBDocumentManager *documentManager = UBDocumentManager::documentManager(); + for (int i = 0; i < documentManager->supportedExportAdaptors().length(); i++) + { + UBExportAdaptor* adaptor = documentManager->supportedExportAdaptors()[i]; + QAction *currentExportAction = exportMenu->addAction(adaptor->exportName()); + currentExportAction->setData(i); + connect(currentExportAction, SIGNAL(triggered (bool)), this, SLOT(exportDocument())); + exportMenu->addAction(currentExportAction); + } + + foreach (QWidget* menuWidget, mMainWindow->actionExport->associatedWidgets()) + { + QToolButton *tb = qobject_cast(menuWidget); + + if (tb && !tb->menu()) + { + tb->setObjectName("ubButtonMenu"); + tb->setPopupMode(QToolButton::InstantPopup); + + tb->setMenu(exportMenu); + } + } + +#ifdef Q_WS_MAC + mMainWindow->actionDelete->setShortcut(QKeySequence(Qt::Key_Backspace)); +#endif + + connect(mMainWindow->actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedItem())); + connect(mMainWindow->actionDuplicate, SIGNAL(triggered()), this, SLOT(duplicateSelectedItem())); + connect(mMainWindow->actionRename, SIGNAL(triggered()), this, SLOT(renameSelectedItem())); + connect(mMainWindow->actionAddToWorkingDocument, SIGNAL(triggered()), this, SLOT(addToDocument())); + + loadDocumentProxies(); + + mDocumentUI->documentTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); + mDocumentUI->documentTreeWidget->setDragEnabled(true); + mDocumentUI->documentTreeWidget->viewport()->setAcceptDrops(true); + mDocumentUI->documentTreeWidget->setDropIndicatorShown(true); + mDocumentUI->documentTreeWidget->setIndentation(18); // 1.5 * /resources/style/treeview-branch-closed.png width + mDocumentUI->documentTreeWidget->setDragDropMode(QAbstractItemView::InternalMove); + + connect(mDocumentUI->documentTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); + connect(mDocumentUI->documentTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int))); + connect(mDocumentUI->documentTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *, int))); + + connect(mDocumentUI->thumbnailWidget, SIGNAL(sceneDropped(UBDocumentProxy*, int, int)), this, SLOT(moveSceneToIndex ( UBDocumentProxy*, int, int))); + connect(mDocumentUI->thumbnailWidget, SIGNAL(resized()), this, SLOT(thumbnailViewResized())); + connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseDoubleClick(QGraphicsItem*, int)), this, SLOT(pageDoubleClicked(QGraphicsItem*, int))); + connect(mDocumentUI->thumbnailWidget, SIGNAL(mouseClick(QGraphicsItem*, int)), this, SLOT(pageClicked(QGraphicsItem*, int))); + + connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentCreated(UBDocumentProxy*)), this, SLOT(addDocumentInTree(UBDocumentProxy*))); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), this, SLOT(updateDocumentInTree(UBDocumentProxy*))); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneCreated(UBDocumentProxy*, int)), this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentSceneWillBeDeleted(UBDocumentProxy*, int)), this, SLOT(documentSceneChanged(UBDocumentProxy*, int))); + + mDocumentUI->thumbnailWidget->setBackgroundBrush(UBSettings::documentViewLightColor); + + #ifdef Q_WS_MACX + mMessageWindow = new UBMessageWindow(NULL); + #else + mMessageWindow = new UBMessageWindow(mDocumentUI->thumbnailWidget); + #endif + + mMessageWindow->hide(); + + } +} + + +QWidget* UBDocumentController::controlView() +{ + return mDocumentWidget; +} + + +void UBDocumentController::setupToolbar() +{ + UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->documentToolBar, mMainWindow->actionBoard); + connect(mMainWindow->actionDocumentTools, SIGNAL(triggered()), this, SLOT(toggleDocumentToolsPalette())); +} + +void UBDocumentController::setupPalettes() +{ + + mToolsPalette = new UBDocumentToolsPalette(controlView()); + + mToolsPalette->hide(); + + bool showToolsPalette = !mToolsPalette->isEmpty(); + mMainWindow->actionDocumentTools->setVisible(showToolsPalette); + + if (showToolsPalette) + { + mMainWindow->actionDocumentTools->trigger(); + } +} + + +void UBDocumentController::show() +{ + selectDocument(mBoardController->selectedDocument()); + + selectionChanged(); + + if(!mToolsPalette) + setupPalettes(); +} + + +void UBDocumentController::hide() +{ + // NOOP +} + + +void UBDocumentController::openSelectedItem() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + if (selectedItems.count() > 0) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); + + if (thumb) + { + UBDocumentProxy* proxy = thumb->proxy(); + + if (proxy && isOKToOpenDocument(proxy)) + { + UBApplication::applicationController->showBoard(); + } + } + } + else + { + UBDocumentProxy* proxy = selectedDocumentProxy(); + + if (proxy && isOKToOpenDocument(proxy)) + { + mBoardController->setActiveDocumentScene(proxy); + UBApplication::applicationController->showBoard(); + } + } + + QApplication::restoreOverrideCursor(); +} + +void UBDocumentController::duplicateSelectedItem() +{ + if (UBApplication::applicationController->displayMode() != UBApplicationController::Document) + return; + + if (mSelectionType == Page) + { + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + QList selectedSceneIndexes; + foreach (QGraphicsItem *item, selectedItems) + { + UBSceneThumbnailPixmap *thumb = dynamic_cast(item); + if (thumb) + { + UBDocumentProxy *proxy = thumb->proxy(); + + if (proxy) + { + int sceneIndex = thumb->sceneIndex(); + selectedSceneIndexes << sceneIndex; + } + } + } + if (selectedSceneIndexes.count() > 0) + { + duplicatePages(selectedSceneIndexes); + emit documentThumbnailsUpdated(this); + selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(selectedDocument()); + mDocumentUI->thumbnailWidget->selectItemAt(selectedSceneIndexes.last() + selectedSceneIndexes.size()); + } + } + else + { + UBDocumentProxy* source = selectedDocumentProxy(); + UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); + + if (source && group) + { + QString docName = source->metaData(UBSettings::documentName).toString(); + + showMessage(tr("Duplicating Document %1").arg(docName), true); + + UBDocumentProxy* duplicatedDoc = UBPersistenceManager::persistenceManager()->duplicateDocument(source); + duplicatedDoc->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(duplicatedDoc); + + selectDocument(duplicatedDoc, false); + + showMessage(tr("Document %1 copied").arg(docName), false); + } + } +} + +void UBDocumentController::moveDocumentToTrash(UBDocumentGroupTreeItem* groupTi, UBDocumentProxyTreeItem *proxyTi) +{ + int index = proxyTi->parent()->indexOfChild(proxyTi); + index --; + + if (index >= 0) + { + if (proxyTi->proxy() == mBoardController->selectedDocument()) + { + selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(index))->proxy(), true); + } + else + proxyTi->parent()->child(index)->setSelected(true); + } + else if (proxyTi->parent()->childCount() > 1) + { + if (proxyTi->proxy() == mBoardController->selectedDocument()) + { + selectDocument(((UBDocumentProxyTreeItem*)proxyTi->parent()->child(1))->proxy(), true); + } + else + proxyTi->parent()->child(1)->setSelected(true); + } + else + { + if (proxyTi->proxy() == mBoardController->selectedDocument()) + { + bool documentFound = false; + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (!groupItem->isTrashFolder()) + { + for(int j=0; jchildCount(); j++) + { + if (((UBDocumentProxyTreeItem*)groupItem->child(j))->proxy() != mBoardController->selectedDocument()) + { + selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy(), true); + documentFound = true; + break; + } + } + } + if (documentFound) + break; + } + if (!documentFound) + { + UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(groupTi->groupName()); + selectDocument(document, true); + } + } + else + proxyTi->parent()->setSelected(true); + } + + QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); + proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); + + proxyTi->parent()->removeChild(proxyTi); + mTrashTi->addChild(proxyTi); + proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); +} + +void UBDocumentController::moveFolderToTrash(UBDocumentGroupTreeItem* groupTi) +{ + bool changeCurrentDocument = false; + for (int i = 0; i < groupTi->childCount(); i++) + { + UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); + if (proxyTi && proxyTi->proxy() && proxyTi->proxy() == mBoardController->selectedDocument()) + { + changeCurrentDocument = true; + break; + } + } + + QList toBeDeleted; + + for (int i = 0; i < groupTi->childCount(); i++) + { + UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); + if (proxyTi && proxyTi->proxy()) + toBeDeleted << proxyTi; + } + + for (int i = 0; i < toBeDeleted.count(); i++) + { + UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); + + showMessage(QString("Deleting %1").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString())); + // Move document to trash + QString oldGroupName = proxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); + proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); + + groupTi->removeChild(proxyTi); + mTrashTi->addChild(proxyTi); + proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); + + showMessage(QString("%1 deleted").arg(groupTi->groupName())); + } + + // dont remove default group + if (!groupTi->isDefaultFolder()) + { + int index = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(groupTi); + + if (index >= 0) + { + mDocumentUI->documentTreeWidget->takeTopLevelItem(index); + } + } + + if (changeCurrentDocument) + { + bool documentFound = false; + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (!groupItem->isTrashFolder() && groupItem != groupTi) + { + for(int j=0; jchildCount(); j++) + { + if (((UBDocumentProxyTreeItem*)groupItem->child(j))->proxy() != mBoardController->selectedDocument()) + { + selectDocument(((UBDocumentProxyTreeItem*)groupItem->child(0))->proxy(), true); + documentFound = true; + break; + } + } + } + if (documentFound) + break; + } + if (!documentFound) + { + UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument( mDefaultDocumentGroupName ); + selectDocument(document, true); + } + } + + reloadThumbnails(); +} + +void UBDocumentController::deleteSelectedItem() +{ + if (mSelectionType == Page) + { + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + deletePages(selectedItems); + } + else + { + + UBDocumentProxyTreeItem *proxyTi = selectedDocumentProxyTreeItem(); + + UBDocumentGroupTreeItem* groupTi = selectedDocumentGroupTreeItem(); + + if (proxyTi && proxyTi->proxy() && proxyTi->parent()) + { + if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Document"), tr("Are you sure you want to remove the document '%1'?").arg(proxyTi->proxy()->metaData(UBSettings::documentName).toString()))) + { + if (proxyTi->parent() != mTrashTi) + { + moveDocumentToTrash(groupTi, proxyTi); + } + else + { + // We have to physically delete document + proxyTi->parent()->removeChild(proxyTi); + UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); + + if (mTrashTi->childCount()==0) + selectDocument(NULL); + else + selectDocument(((UBDocumentProxyTreeItem*)mTrashTi->child(0))->proxy()); + reloadThumbnails(); + } + } + } + else if (groupTi) + { + if (groupTi == mTrashTi) + { + if(UBApplication::mainWindow->yesNoQuestion(tr("Empty Trash"), tr("Are you sure you want to empty trash?"))) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QList toBeDeleted; + + for (int i = 0; i < groupTi->childCount(); i++) + { + UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); + if (proxyTi && proxyTi->proxy()) + toBeDeleted << proxyTi; + } + + showMessage(tr("Emptying trash")); + + for (int i = 0; i < toBeDeleted.count(); i++) + { + UBDocumentProxyTreeItem* proxyTi = toBeDeleted.at(i); + + proxyTi->parent()->removeChild(proxyTi); + UBPersistenceManager::persistenceManager()->deleteDocument(proxyTi->proxy()); + } + + showMessage(tr("Emptied trash")); + + QApplication::restoreOverrideCursor(); + mMainWindow->actionDelete->setEnabled(false); + } + } + else + { + if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Folder"), tr("Are you sure you want to remove the folder '%1' and all its content?").arg(groupTi->groupName()))) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + moveFolderToTrash(groupTi); + QApplication::restoreOverrideCursor(); + } + } + } + } +} + + +void UBDocumentController::exportDocument() +{ + QAction *currentExportAction = qobject_cast(sender()); + QVariant actionData = currentExportAction->data(); + UBExportAdaptor* selectedExportAdaptor = UBDocumentManager::documentManager()->supportedExportAdaptors()[actionData.toInt()]; + + UBDocumentProxy* proxy = selectedDocumentProxy(); + + if (proxy) + { + selectedExportAdaptor->persist(proxy); + emit exportDone(); + } + else + { + showMessage(tr("No document selected!")); + } +} + + +void UBDocumentController::documentZoomSliderValueChanged (int value) +{ + mDocumentUI->thumbnailWidget->setThumbnailWidth(value); + + UBSettings::settings()->documentThumbnailWidth->set(value); +} + + +void UBDocumentController::loadDocumentProxies() +{ + QList > proxies = UBPersistenceManager::persistenceManager()->documentProxies; + + QStringList emptyGroupNames = UBSettings::settings()->value("Document/EmptyGroupNames", QStringList()).toStringList(); + + mDocumentUI->documentTreeWidget->clear(); + + QMap groupNamesMap; + + UBDocumentGroupTreeItem* emptyGroupNameTi = 0; + + mTrashTi = new UBDocumentGroupTreeItem(0, false); // deleted by the tree widget + mTrashTi->setGroupName(mDocumentTrashGroupName); + mTrashTi->setIcon(0, QIcon(":/images/trash.png")); + + foreach (QPointer proxy, proxies) + { + if (proxy) + { + QString docGroup = proxy->metaData(UBSettings::documentGroupName).toString(); + + bool isEmptyGroupName = false; + bool isInTrash = false; + + if (docGroup.isEmpty()) // #see https://trac.assembla.com/uniboard/ticket/426 + { + docGroup = mDefaultDocumentGroupName; + isEmptyGroupName = true; + } + else if (docGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) + { + isInTrash = true; + } + + QString docName = proxy->metaData(UBSettings::documentName).toString(); + + if (emptyGroupNames.contains(docGroup)) + emptyGroupNames.removeAll(docGroup); + + if (!groupNamesMap.contains(docGroup) && !isInTrash) + { + UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0, !isEmptyGroupName); // deleted by the tree widget + groupNamesMap.insert(docGroup, docGroupItem); + docGroupItem->setGroupName(docGroup); + + if (isEmptyGroupName) + emptyGroupNameTi = docGroupItem; + } + + UBDocumentGroupTreeItem* docGroupItem; + if (isInTrash) + docGroupItem = mTrashTi; + else + docGroupItem = groupNamesMap.value(docGroup); + + QTreeWidgetItem* docItem = new UBDocumentProxyTreeItem(docGroupItem, proxy, !isInTrash); + docItem->setText(0, docName); + + if (mBoardController->selectedDocument() == proxy) + { + mDocumentUI->documentTreeWidget->expandItem(docGroupItem); + mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); + } + } + } + + foreach (const QString emptyGroupName, emptyGroupNames) + { + UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget + groupNamesMap.insert(emptyGroupName, docGroupItem); + docGroupItem->setGroupName(emptyGroupName); + } + + QList groupNamesList = groupNamesMap.keys(); + qSort(groupNamesList); + + foreach (const QString groupName, groupNamesList) + { + UBDocumentGroupTreeItem* ti = groupNamesMap.value(groupName); + + if (ti != emptyGroupNameTi) + mDocumentUI->documentTreeWidget->addTopLevelItem(ti); + } + + if (emptyGroupNameTi) + mDocumentUI->documentTreeWidget->addTopLevelItem(emptyGroupNameTi); + + mDocumentUI->documentTreeWidget->addTopLevelItem(mTrashTi); +} + + +void UBDocumentController::itemClicked(QTreeWidgetItem * item, int column ) +{ + Q_UNUSED(item); + Q_UNUSED(column); + + selectDocument(selectedDocumentProxy(), false); + itemSelectionChanged(); +} + + +void UBDocumentController::itemChanged(QTreeWidgetItem * item, int column) +{ + UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); + + disconnect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)) + , this, SLOT(updateDocumentInTree(UBDocumentProxy*))); + + if (proxyItem) + { + if (proxyItem->proxy()->metaData(UBSettings::documentName).toString() != item->text(column)) + { + proxyItem->proxy()->setMetaData(UBSettings::documentName, item->text(column)); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyItem->proxy()); + } + } + else + { + // it is a group + UBDocumentGroupTreeItem* editedGroup = dynamic_cast(item); + if (editedGroup) + { + for (int i = 0; i < item->childCount(); i++) + { + UBDocumentProxyTreeItem* childItem = dynamic_cast(item->child(i)); + + if (childItem) + { + QString groupName; + if (0 != (item->flags() & Qt::ItemIsEditable)) + { + childItem->proxy()->setMetaData(UBSettings::documentGroupName, item->text(column)); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(childItem->proxy()); + } + } + } + } + } + + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), + this, SLOT(updateDocumentInTree(UBDocumentProxy*))); +} + + +void UBDocumentController::importFile() +{ + UBDocumentGroupTreeItem* group = selectedDocumentGroupTreeItem(); + UBDocumentManager *docManager = UBDocumentManager::documentManager(); + + if (group) + { + QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); + QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File"), + defaultPath, docManager->importFileFilter()); + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QApplication::processEvents(); + QFileInfo fileInfo(filePath); + UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); + + if (filePath.length() > 0) + { + UBDocumentProxy* createdDocument = 0; + QApplication::processEvents(); + QFile selectedFile(filePath); + + QString groupName = group->groupName(); + + if (groupName == mDefaultDocumentGroupName || fileInfo.suffix() != "ubz") + groupName = ""; + + showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); + + createdDocument = docManager->importFile(selectedFile, groupName); + + if (createdDocument) + { + selectDocument(createdDocument, false); + } + else + { + showMessage(tr("Failed to import file ... ")); + } + } + + QApplication::restoreOverrideCursor(); + } +} + +void UBDocumentController::addFolderOfImages() +{ + UBDocumentProxy* document = selectedDocumentProxy(); + + if (document) + { + QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); + + QString imagesDir = QFileDialog::getExistingDirectory(mParentWidget, tr("Import all Images from Folder"), defaultPath); + QDir parentImageDir(imagesDir); + parentImageDir.cdUp(); + + UBSettings::settings()->lastImportFolderPath->set(QVariant(parentImageDir.absolutePath())); + + if (imagesDir.length() > 0) + { + QDir dir(imagesDir); + + int importedImageNumber + = UBDocumentManager::documentManager()->addImageDirToDocument(dir, document); + + if (importedImageNumber == 0) + { + showMessage(tr("Folder does not contain any image files")); + UBApplication::applicationController->showDocument(); + } + else + { + document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(document); + reloadThumbnails(); + } + } + } +} + + +void UBDocumentController::addFileToDocument() +{ + UBDocumentProxy* document = selectedDocumentProxy(); + + if (document) + { + addFileToDocument(document); + reloadThumbnails(); + } +} + + +bool UBDocumentController::addFileToDocument(UBDocumentProxy* document) +{ + QString defaultPath = UBSettings::settings()->lastImportFilePath->get().toString(); + QString filePath = QFileDialog::getOpenFileName(mParentWidget, tr("Open Supported File"), defaultPath, UBDocumentManager::documentManager()->importFileFilter()); + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QApplication::processEvents(); + + QFileInfo fileInfo(filePath); + UBSettings::settings()->lastImportFilePath->set(QVariant(fileInfo.absolutePath())); + + bool success = false; + + if (filePath.length() > 0) + { + QApplication::processEvents(); // NOTE: We performed this just a few lines before. Is it really necessary to do it again here?? + QFile selectedFile(filePath); + + showMessage(tr("Importing file %1...").arg(fileInfo.baseName()), true); + + QStringList fileNames; + fileNames << filePath; + success = UBDocumentManager::documentManager()->addFilesToDocument(document, fileNames); + + if (success) + { + document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(document); + } + else + { + showMessage(tr("Failed to import file ... ")); + } + } + + QApplication::restoreOverrideCursor(); + + return success; +} + + +void UBDocumentController::moveSceneToIndex(UBDocumentProxy* proxy, int source, int target) +{ + if (UBDocumentContainer::movePageToIndex(source, target)) + { + proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(proxy); + + mDocumentUI->thumbnailWidget->hightlightItem(target); + } +} + + +void UBDocumentController::thumbnailViewResized() +{ + int maxWidth = qMin(UBSettings::maxThumbnailWidth, mDocumentUI->thumbnailWidget->width()); + + mDocumentUI->documentZoomSlider->setMaximum(maxWidth); +} + + +void UBDocumentController::pageSelectionChanged() +{ + if (mIsClosing) + return; + + bool pageSelected = mDocumentUI->thumbnailWidget->selectedItems().count() > 0; + + if (pageSelected) + mSelectionType = Page; + else + mSelectionType = None; + + selectionChanged(); +} + + +void UBDocumentController::selectionChanged() +{ + if (mIsClosing) + return; + + int pageCount = -1; + + UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); + + if (proxyTi && proxyTi->proxy()) + pageCount = proxyTi->proxy()->pageCount(); + + bool pageSelected = (mSelectionType == Page); + bool groupSelected = (mSelectionType == Folder); + bool docSelected = (mSelectionType == Document); + + bool trashSelected = false; + if (groupSelected && selectedDocumentGroupTreeItem()) + trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); + + if ((docSelected || pageSelected) && proxyTi) + trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); + + bool defaultGroupSelected = false; + if (groupSelected && selectedDocumentGroupTreeItem()) + defaultGroupSelected = selectedDocumentGroupTreeItem()->isDefaultFolder(); + + mMainWindow->actionNewDocument->setEnabled((groupSelected || docSelected || pageSelected) && !trashSelected); + mMainWindow->actionExport->setEnabled((docSelected || pageSelected) && !trashSelected); + bool firstSceneSelected = false; + if(docSelected) + mMainWindow->actionDuplicate->setEnabled(!trashSelected); + else if(pageSelected){ + QList selection = mDocumentUI->thumbnailWidget->selectedItems(); + if(pageCount == 1) + mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(0))); + else{ + for(int i = 0; i < selection.count() && !firstSceneSelected; i += 1){ + if(dynamic_cast(selection.at(i))->sceneIndex() == 0){ + mMainWindow->actionDuplicate->setEnabled(!trashSelected && pageCanBeDuplicated(UBDocumentContainer::pageFromSceneIndex(0))); + firstSceneSelected = true; + } + } + if(!firstSceneSelected) + mMainWindow->actionDuplicate->setEnabled(!trashSelected); + } + } + else + mMainWindow->actionDuplicate->setEnabled(false); + + mMainWindow->actionOpen->setEnabled((docSelected || pageSelected) && !trashSelected); + mMainWindow->actionRename->setEnabled((groupSelected || docSelected) && !trashSelected && !defaultGroupSelected); + + mMainWindow->actionAddToWorkingDocument->setEnabled(pageSelected + && !(selectedDocumentProxy() == mBoardController->selectedDocument()) && !trashSelected); + + bool deleteEnabled = false; + if (trashSelected) + { + if (docSelected) + deleteEnabled = true; + else if (groupSelected && selectedDocumentGroupTreeItem()) + { + if (selectedDocumentGroupTreeItem()->childCount() > 0) + deleteEnabled = true; + } + } + else + { + deleteEnabled = groupSelected || docSelected || pageSelected; + } + + if (pageSelected && (pageCount == mDocumentUI->thumbnailWidget->selectedItems().count())) + { + deleteEnabled = false; + } + + if(pageSelected && firstSceneSelected) + deleteEnabled = false; + + mMainWindow->actionDelete->setEnabled(deleteEnabled); + + if (trashSelected) + { + if (docSelected) + { + mMainWindow->actionDelete->setIcon(QIcon(":/images/toolbar/deleteDocument.png")); + mMainWindow->actionDelete->setText(tr("Delete")); + } + else + { + mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); + mMainWindow->actionDelete->setText(tr("Empty")); + } + } + else + { + mMainWindow->actionDelete->setIcon(QIcon(":/images/trash.png")); + mMainWindow->actionDelete->setText(tr("Trash")); + } + + mMainWindow->actionDocumentAdd->setEnabled((docSelected || pageSelected) && !trashSelected); + mMainWindow->actionImport->setEnabled(!trashSelected); + +} + + +void UBDocumentController::documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex) +{ + Q_UNUSED(pSceneIndex); + + if (proxy == selectedDocumentProxy()) + { + reloadThumbnails(); + } +} + + +void UBDocumentController::pageDoubleClicked(QGraphicsItem* item, int index) +{ + Q_UNUSED(item); + Q_UNUSED(index); + + bool pageSelected = (mSelectionType == Page); + bool groupSelected = (mSelectionType == Folder); + bool docSelected = (mSelectionType == Document); + + bool trashSelected = false; + if (groupSelected && selectedDocumentGroupTreeItem()) + trashSelected = selectedDocumentGroupTreeItem()->isTrashFolder(); + UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); + if ((docSelected || pageSelected) && proxyTi) + trashSelected = dynamic_cast(proxyTi->parent())->isTrashFolder(); + if (trashSelected) return; + + openSelectedItem(); +} + + +void UBDocumentController::pageClicked(QGraphicsItem* item, int index) +{ + Q_UNUSED(item); + Q_UNUSED(index); + + pageSelectionChanged(); +} + + +void UBDocumentController::closing() +{ + mIsClosing = true; + + QStringList emptyGroups; + + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + + if (item->childCount() == 0) + { + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (groupItem) + { + QString groupName = groupItem->groupName(); + if (!emptyGroups.contains(groupName) && groupName != mDocumentTrashGroupName) + emptyGroups << groupName; + } + } + } + + UBSettings::settings()->setValue("Document/EmptyGroupNames", emptyGroups); + +} + +void UBDocumentController::addToDocument() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + if (selectedItems.count() > 0) + { + int oldActiveSceneIndex = mBoardController->activeSceneIndex(); + + QList > pageInfoList; + + foreach (QGraphicsItem* item, selectedItems) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (item); + + if (thumb && thumb->proxy()) + { + QPair pageInfo(thumb->proxy(), thumb->sceneIndex()); + pageInfoList << pageInfo; + } + } + + for (int i = 0; i < pageInfoList.length(); i++) + { + mBoardController->addScene(pageInfoList.at(i).first, pageInfoList.at(i).second, true); + } + + int newActiveSceneIndex = selectedItems.count() == mBoardController->selectedDocument()->pageCount() ? 0 : oldActiveSceneIndex + 1; + mDocumentUI->thumbnailWidget->selectItemAt(newActiveSceneIndex, false); + selectDocument(mBoardController->selectedDocument()); + mBoardController->selectedDocument()->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(mBoardController->selectedDocument()); + + UBApplication::applicationController->showBoard(); + } + + QApplication::restoreOverrideCursor(); +} + + +void UBDocumentController::addDocumentInTree(UBDocumentProxy* pDocument) +{ + QString documentName = pDocument->name(); + QString documentGroup = pDocument->groupName(); + if (documentGroup.isEmpty()) + { + documentGroup = mDefaultDocumentGroupName; + } + UBDocumentGroupTreeItem* group = 0; + if (documentGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) + { + group = mTrashTi; + } + else + { + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if (groupItem->groupName() == documentGroup) + { + group = groupItem; + break; + } + } + } + + if (group == 0) + { + group = new UBDocumentGroupTreeItem(0); // deleted by the tree widget + group->setGroupName(documentGroup); + mDocumentUI->documentTreeWidget->addTopLevelItem(group); + } + + UBDocumentProxyTreeItem *ti = new UBDocumentProxyTreeItem(group, pDocument, !group->isTrashFolder()); + ti->setText(0, documentName); +} + + +void UBDocumentController::updateDocumentInTree(UBDocumentProxy* pDocument) +{ + QTreeWidgetItemIterator it(mDocumentUI->documentTreeWidget); + while (*it) + { + UBDocumentProxyTreeItem* pi = dynamic_cast((*it)); + + if (pi && pi->proxy() == pDocument) + { + pi->setText(0, pDocument->name()); + break; + } + ++it; + } +} + + +QStringList UBDocumentController::allGroupNames() +{ + QStringList result; + + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + result << groupItem->groupName(); + } + + return result; +} + + +void UBDocumentController::renameSelectedItem() +{ + if (mDocumentUI->documentTreeWidget->selectedItems().count() > 0) + mDocumentUI->documentTreeWidget->editItem(mDocumentUI->documentTreeWidget->selectedItems().at(0)); +} + + +bool UBDocumentController::isOKToOpenDocument(UBDocumentProxy* proxy) +{ + //check version + QString docVersion = proxy->metaData(UBSettings::documentVersion).toString(); + + if (docVersion.isEmpty() || docVersion.startsWith("4.1") || docVersion.startsWith("4.2") + || docVersion.startsWith("4.3") || docVersion.startsWith("4.4") || docVersion.startsWith("4.5") + || docVersion.startsWith("4.6")) // TODO UB 4.7 update if necessary + { + return true; + } + else + { + if (UBApplication::mainWindow->yesNoQuestion(tr("Open Document"), + tr("The document '%1' has been generated with a newer version of Sankore (%2). By opening it, you may lose some information. Do you want to proceed?") + .arg(proxy->metaData(UBSettings::documentName).toString()) + .arg(docVersion))) + { + return true; + } + else + { + return false; + } + } +} + + +void UBDocumentController::showMessage(const QString& message, bool showSpinningWheel) +{ + if (mMessageWindow) + { + int margin = UBSettings::boardMargin; + + QRect newSize = mDocumentUI->thumbnailWidget->geometry(); + + #ifdef Q_WS_MACX + QPoint point(newSize.left() + margin, newSize.bottom() - mMessageWindow->height() - margin); + mMessageWindow->move(mDocumentUI->thumbnailWidget->mapToGlobal(point)); + #else + mMessageWindow->move(margin, newSize.height() - mMessageWindow->height() - margin); + #endif + + mMessageWindow->showMessage(message, showSpinningWheel); + } +} + + +void UBDocumentController::hideMessage() +{ + if (mMessageWindow) + mMessageWindow->hideMessage(); +} + + +void UBDocumentController::addImages() +{ + UBDocumentProxy* document = selectedDocumentProxy(); + + if (document) + { + QString defaultPath = UBSettings::settings()->lastImportFolderPath->get().toString(); + + QString extensions; + + foreach (QString ext, UBSettings::settings()->imageFileExtensions) + { + extensions += " *."; + extensions += ext; + } + + QStringList images = QFileDialog::getOpenFileNames(mParentWidget, tr("Add all Images to Document"), + defaultPath, tr("All Images (%1)").arg(extensions)); + + if (images.length() > 0) + { + QFileInfo firstImage(images.at(0)); + + UBSettings::settings()->lastImportFolderPath->set(QVariant(firstImage.absoluteDir().absolutePath())); + + int importedImageNumber + = UBDocumentManager::documentManager()->addFilesToDocument(document, images); + + if (importedImageNumber == 0) + { + UBApplication::showMessage(tr("Selection does not contain any image files!")); + UBApplication::applicationController->showDocument(); + } + else + { + document->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(document); + reloadThumbnails(); + } + } + } +} + + +void UBDocumentController::toggleDocumentToolsPalette() +{ + if (!mToolsPalette->isVisible() && !mToolsPalettePositionned) + { + mToolsPalette->adjustSizeAndPosition(); + int left = controlView()->width() - 20 - mToolsPalette->width(); + int top = (controlView()->height() - mToolsPalette->height()) / 2; + + mToolsPalette->setCustomPosition(true); + mToolsPalette->move(left, top); + + mToolsPalettePositionned = true; + } + + bool visible = mToolsPalette->isVisible(); + mToolsPalette->setVisible(!visible); +} + + +void UBDocumentController::cut() +{ + // TODO - implemented me +} + + +void UBDocumentController::copy() +{ + // TODO - implemented me +} + + +void UBDocumentController::paste() +{ + // TODO - implemented me +} + + +void UBDocumentController::focusChanged(QWidget *old, QWidget *current) +{ + Q_UNUSED(old); + + if (current == mDocumentUI->thumbnailWidget) + { + if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) + mSelectionType = Page; + else + mSelectionType = None; + } + else if (current == mDocumentUI->documentTreeWidget) + { + if (selectedDocumentProxy()) + mSelectionType = Document; + else if (selectedDocumentGroupTreeItem()) + mSelectionType = Folder; + else + mSelectionType = None; + } + else if (current == mDocumentUI->documentZoomSlider) + { + if (mDocumentUI->thumbnailWidget->selectedItems().count() > 0) + mSelectionType = Page; + else + mSelectionType = None; + } + else + { + if (old != mDocumentUI->thumbnailWidget && + old != mDocumentUI->documentTreeWidget && + old != mDocumentUI->documentZoomSlider) + { + mSelectionType = None; + } + } + + selectionChanged(); +} + +void UBDocumentController::deletePages(QList itemsToDelete) +{ + if (itemsToDelete.count() > 0) + { + QList sceneIndexes; + UBDocumentProxy* proxy = 0; + + foreach (QGraphicsItem* item, itemsToDelete) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (item); + + if (thumb) + { + proxy = thumb->proxy(); + if (proxy) + { + sceneIndexes.append(thumb->sceneIndex()); + } + } + } + + if(UBApplication::mainWindow->yesNoQuestion(tr("Remove Page"), tr("Are you sure you want to remove %n page(s) from the selected document '%1'?", "", sceneIndexes.count()).arg(proxy->metaData(UBSettings::documentName).toString()))) + { + UBDocumentContainer::deletePages(sceneIndexes); + + proxy->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); + UBMetadataDcSubsetAdaptor::persist(proxy); + + int minIndex = proxy->pageCount() - 1; + foreach (int i, sceneIndexes) + minIndex = qMin(i, minIndex); + + mDocumentUI->thumbnailWidget->selectItemAt(minIndex); + } + } +} + +int UBDocumentController::getSelectedItemIndex() +{ + QList selectedItems = mDocumentUI->thumbnailWidget->selectedItems(); + + if (selectedItems.count() > 0) + { + UBSceneThumbnailPixmap* thumb = dynamic_cast (selectedItems.last()); + return thumb->sceneIndex(); + } + else return -1; +} + +bool UBDocumentController::pageCanBeMovedUp(int page) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return page >= 2; + else + return page >= 1; +} + +bool UBDocumentController::pageCanBeMovedDown(int page) +{ + if(UBSettings::settings()->teacherGuidePageZeroActivated->get().toBool()) + return page != 0 && page < selectedDocument()->pageCount() - 1; + else + return page < selectedDocument()->pageCount() - 1; +} + +bool UBDocumentController::pageCanBeDuplicated(int page) +{ + return page != 0; +} + +bool UBDocumentController::pageCanBeDeleted(int page) +{ + return page != 0; +} + +void UBDocumentController::refreshDocumentThumbnailsView(UBDocumentContainer*) +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + QList items; + QList itemsPath; + + UBDocumentProxy *proxy = selectedDocumentProxy(); + QGraphicsPixmapItem *selection = 0; + + QStringList labels; + + if (proxy) + { + setDocument(proxy); + + for (int i = 0; i < selectedDocument()->pageCount(); i++) + { + const QPixmap* pix = pageAt(i); + QGraphicsPixmapItem *pixmapItem = new UBSceneThumbnailPixmap(*pix, proxy, i); // deleted by the tree widget + + if (proxy == mBoardController->selectedDocument() && mBoardController->activeSceneIndex() == i) + { + selection = pixmapItem; + } + + items << pixmapItem; + int pageIndex = pageFromSceneIndex(i); + if(pageIndex) + labels << tr("Page %1").arg(pageIndex); + else + labels << tr("Title page"); + + itemsPath.append(QUrl::fromLocalFile(proxy->persistencePath() + QString("/pages/%1").arg(UBDocumentContainer::pageFromSceneIndex(i)))); + } + } + + mDocumentUI->thumbnailWidget->setGraphicsItems(items, itemsPath, labels, UBApplication::mimeTypeUniboardPage); + + UBDocumentProxyTreeItem* proxyTi = selectedDocumentProxyTreeItem(); + if (proxyTi && (proxyTi->parent() == mTrashTi)) + mDocumentUI->thumbnailWidget->setDragEnabled(false); + else + mDocumentUI->thumbnailWidget->setDragEnabled(true); + + mDocumentUI->thumbnailWidget->ensureVisible(0, 0, 10, 10); + + if (selection) { + disconnect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); + UBSceneThumbnailPixmap *currentScene = dynamic_cast(selection); + if (currentScene) + mDocumentUI->thumbnailWidget->hightlightItem(currentScene->sceneIndex()); + connect(mDocumentUI->thumbnailWidget->scene(), SIGNAL(selectionChanged()), this, SLOT(pageSelectionChanged())); + } + + QApplication::restoreOverrideCursor(); +} diff --git a/src/document/UBDocumentController.h b/src/document/UBDocumentController.h index c146b6e8..a77c05e6 100644 --- a/src/document/UBDocumentController.h +++ b/src/document/UBDocumentController.h @@ -19,136 +19,136 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBDOCUMENTCONTROLLER_H_ -#define UBDOCUMENTCONTROLLER_H_ - -#include -#include "document/UBDocumentContainer.h" - -namespace Ui -{ - class documents; -} - -#include "gui/UBMessageWindow.h" - -class UBGraphicsScene; -class QDialog; -class UBDocumentProxy; -class UBBoardController; -class UBThumbnailsScene; -class UBDocumentGroupTreeItem; -class UBDocumentProxyTreeItem; -class UBMainWindow; -class UBDocumentToolsPalette; - -class UBDocumentController : public UBDocumentContainer -{ - Q_OBJECT; - - public: - UBDocumentController(UBMainWindow* mainWindow); - virtual ~UBDocumentController(); - - void closing(); - QWidget* controlView(); - UBDocumentProxyTreeItem* findDocument(UBDocumentProxy* proxy); - bool addFileToDocument(UBDocumentProxy* document); - void deletePages(QList itemsToDelete); - int getSelectedItemIndex(); - - bool pageCanBeMovedUp(int page); - bool pageCanBeMovedDown(int page); - bool pageCanBeDuplicated(int page); - bool pageCanBeDeleted(int page); - QString documentTrashGroupName(){ return mDocumentTrashGroupName;} - QString defaultDocumentGroupName(){ return mDefaultDocumentGroupName;} - - signals: - void exportDone(); - - public slots: - void createNewDocument(); - void createNewDocumentGroup(); - void deleteSelectedItem(); - void renameSelectedItem(); - void openSelectedItem(); - void duplicateSelectedItem(); - void importFile(); - void moveSceneToIndex(UBDocumentProxy* proxy, int source, int target); - void selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument = true); - void show(); - void hide(); - void showMessage(const QString& message, bool showSpinningWheel = false); - void hideMessage(); - void toggleDocumentToolsPalette(); - void cut(); - void copy(); - void paste(); - void focusChanged(QWidget *old, QWidget *current); - - protected: - virtual void setupViews(); - virtual void setupToolbar(); - void setupPalettes(); - bool isOKToOpenDocument(UBDocumentProxy* proxy); - UBDocumentProxy* selectedDocumentProxy(); - UBDocumentProxyTreeItem* selectedDocumentProxyTreeItem(); - UBDocumentGroupTreeItem* selectedDocumentGroupTreeItem(); - QStringList allGroupNames(); - - enum LastSelectedElementType - { - None = 0, Folder, Document, Page - }; - - LastSelectedElementType mSelectionType; - - private: - QWidget *mParentWidget; - UBBoardController *mBoardController; - Ui::documents* mDocumentUI; - UBMainWindow* mMainWindow; - QWidget *mDocumentWidget; - QPointer mMessageWindow; - QAction* mAddFolderOfImagesAction; - QAction* mAddFileToDocumentAction; - QAction* mAddImagesAction; - bool mIsClosing; - UBDocumentToolsPalette *mToolsPalette; - bool mToolsPalettePositionned; - UBDocumentGroupTreeItem* mTrashTi; - - void moveDocumentToTrash(UBDocumentGroupTreeItem* groupTi, UBDocumentProxyTreeItem *proxyTi); - void moveFolderToTrash(UBDocumentGroupTreeItem* groupTi); - QString mDocumentTrashGroupName; - QString mDefaultDocumentGroupName; - - private slots: - void documentZoomSliderValueChanged (int value); - void loadDocumentProxies(); - void itemSelectionChanged(); - void exportDocument(); - void itemChanged(QTreeWidgetItem * item, int column); - void thumbnailViewResized(); - void pageSelectionChanged(); - void selectionChanged(); - void documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex); - void pageDoubleClicked(QGraphicsItem* item, int index); - void pageClicked(QGraphicsItem* item, int index); - void itemClicked(QTreeWidgetItem * item, int column ); - void addToDocument(); - void addDocumentInTree(UBDocumentProxy* pDocument); - void updateDocumentInTree(UBDocumentProxy* pDocument); - void addFolderOfImages(); - void addFileToDocument(); - void addImages(); - - void refreshDocumentThumbnailsView(UBDocumentContainer* source); -}; - - - -#endif /* UBDOCUMENTCONTROLLER_H_ */ + + +#ifndef UBDOCUMENTCONTROLLER_H_ +#define UBDOCUMENTCONTROLLER_H_ + +#include +#include "document/UBDocumentContainer.h" + +namespace Ui +{ + class documents; +} + +#include "gui/UBMessageWindow.h" + +class UBGraphicsScene; +class QDialog; +class UBDocumentProxy; +class UBBoardController; +class UBThumbnailsScene; +class UBDocumentGroupTreeItem; +class UBDocumentProxyTreeItem; +class UBMainWindow; +class UBDocumentToolsPalette; + +class UBDocumentController : public UBDocumentContainer +{ + Q_OBJECT; + + public: + UBDocumentController(UBMainWindow* mainWindow); + virtual ~UBDocumentController(); + + void closing(); + QWidget* controlView(); + UBDocumentProxyTreeItem* findDocument(UBDocumentProxy* proxy); + bool addFileToDocument(UBDocumentProxy* document); + void deletePages(QList itemsToDelete); + int getSelectedItemIndex(); + + bool pageCanBeMovedUp(int page); + bool pageCanBeMovedDown(int page); + bool pageCanBeDuplicated(int page); + bool pageCanBeDeleted(int page); + QString documentTrashGroupName(){ return mDocumentTrashGroupName;} + QString defaultDocumentGroupName(){ return mDefaultDocumentGroupName;} + + signals: + void exportDone(); + + public slots: + void createNewDocument(); + void createNewDocumentGroup(); + void deleteSelectedItem(); + void renameSelectedItem(); + void openSelectedItem(); + void duplicateSelectedItem(); + void importFile(); + void moveSceneToIndex(UBDocumentProxy* proxy, int source, int target); + void selectDocument(UBDocumentProxy* proxy, bool setAsCurrentDocument = true); + void show(); + void hide(); + void showMessage(const QString& message, bool showSpinningWheel = false); + void hideMessage(); + void toggleDocumentToolsPalette(); + void cut(); + void copy(); + void paste(); + void focusChanged(QWidget *old, QWidget *current); + + protected: + virtual void setupViews(); + virtual void setupToolbar(); + void setupPalettes(); + bool isOKToOpenDocument(UBDocumentProxy* proxy); + UBDocumentProxy* selectedDocumentProxy(); + UBDocumentProxyTreeItem* selectedDocumentProxyTreeItem(); + UBDocumentGroupTreeItem* selectedDocumentGroupTreeItem(); + QStringList allGroupNames(); + + enum LastSelectedElementType + { + None = 0, Folder, Document, Page + }; + + LastSelectedElementType mSelectionType; + + private: + QWidget *mParentWidget; + UBBoardController *mBoardController; + Ui::documents* mDocumentUI; + UBMainWindow* mMainWindow; + QWidget *mDocumentWidget; + QPointer mMessageWindow; + QAction* mAddFolderOfImagesAction; + QAction* mAddFileToDocumentAction; + QAction* mAddImagesAction; + bool mIsClosing; + UBDocumentToolsPalette *mToolsPalette; + bool mToolsPalettePositionned; + UBDocumentGroupTreeItem* mTrashTi; + + void moveDocumentToTrash(UBDocumentGroupTreeItem* groupTi, UBDocumentProxyTreeItem *proxyTi); + void moveFolderToTrash(UBDocumentGroupTreeItem* groupTi); + QString mDocumentTrashGroupName; + QString mDefaultDocumentGroupName; + + private slots: + void documentZoomSliderValueChanged (int value); + void loadDocumentProxies(); + void itemSelectionChanged(); + void exportDocument(); + void itemChanged(QTreeWidgetItem * item, int column); + void thumbnailViewResized(); + void pageSelectionChanged(); + void selectionChanged(); + void documentSceneChanged(UBDocumentProxy* proxy, int pSceneIndex); + void pageDoubleClicked(QGraphicsItem* item, int index); + void pageClicked(QGraphicsItem* item, int index); + void itemClicked(QTreeWidgetItem * item, int column ); + void addToDocument(); + void addDocumentInTree(UBDocumentProxy* pDocument); + void updateDocumentInTree(UBDocumentProxy* pDocument); + void addFolderOfImages(); + void addFileToDocument(); + void addImages(); + + void refreshDocumentThumbnailsView(UBDocumentContainer* source); +}; + + + +#endif /* UBDOCUMENTCONTROLLER_H_ */ diff --git a/src/document/UBDocumentProxy.cpp b/src/document/UBDocumentProxy.cpp index c3424c8c..707cc1e5 100644 --- a/src/document/UBDocumentProxy.cpp +++ b/src/document/UBDocumentProxy.cpp @@ -19,222 +19,222 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBDocumentProxy.h" - -#include "frameworks/UBStringUtils.h" - -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBSettings.h" -#include "core/UBDocumentManager.h" - -#include "core/memcheck.h" - -UBDocumentProxy::UBDocumentProxy() - : mPageCount(0) -{ - init(); -} - - -UBDocumentProxy::UBDocumentProxy(const QString& pPersistancePath) - : mPageCount(0) -{ - init(); - setPersistencePath(pPersistancePath); -} - - -void UBDocumentProxy::init() -{ - setMetaData(UBSettings::documentGroupName, ""); - - QDateTime now = QDateTime::currentDateTime(); - setMetaData(UBSettings::documentName, now.toString(Qt::SystemLocaleShortDate)); - - setUuid(QUuid::createUuid()); - - setDefaultDocumentSize(UBSettings::settings()->pageSize->get().toSize()); - - //teacherGuide metadata - setMetaData(UBSettings::sessionTitle,""); - setMetaData(UBSettings::sessionAuthors,""); - setMetaData(UBSettings::sessionObjectives,""); - setMetaData(UBSettings::sessionKeywords,""); - setMetaData(UBSettings::sessionGradeLevel,""); - setMetaData(UBSettings::sessionSubjects,""); - setMetaData(UBSettings::sessionType,""); - setMetaData(UBSettings::sessionLicence,""); -} - - -UBDocumentProxy::~UBDocumentProxy() -{ - // NOOP -} - - -int UBDocumentProxy::pageCount() -{ - return mPageCount; -} - - -void UBDocumentProxy::setPageCount(int pPageCount) -{ - mPageCount = pPageCount; -} - - -int UBDocumentProxy::incPageCount() -{ - if (mPageCount <= 0) - { - mPageCount = 1; - } - else - { - mPageCount++; - } - - return mPageCount; - -} - - -int UBDocumentProxy::decPageCount() -{ - mPageCount --; - - if (mPageCount < 0) - { - mPageCount = 0; - } - - return mPageCount; -} - -QString UBDocumentProxy::persistencePath() const -{ - return mPersistencePath; -} - -void UBDocumentProxy::setPersistencePath(const QString& pPersistencePath) -{ - if (pPersistencePath != mPersistencePath) - { - mIsModified = true; - mPersistencePath = pPersistencePath; - } -} - -void UBDocumentProxy::setMetaData(const QString& pKey, const QVariant& pValue) -{ - if (mMetaDatas.contains(pKey) && mMetaDatas.value(pKey) == pValue) - return; - else - { - mIsModified = true; - mMetaDatas.insert(pKey, pValue); - if (pKey == UBSettings::documentUpdatedAt) - { - UBDocumentManager *documentManager = UBDocumentManager::documentManager(); - if (documentManager) - documentManager->emitDocumentUpdated(this); - } - } -} - -QVariant UBDocumentProxy::metaData(const QString& pKey) const -{ - if (mMetaDatas.contains(pKey)) - { - return mMetaDatas.value(pKey); - } - else - { - qDebug() << "Unknown metadata key" << pKey; - return QString(""); // failsafe - } -} - -QHash UBDocumentProxy::metaDatas() const -{ - return mMetaDatas; -} - -QString UBDocumentProxy::name() const -{ - return metaData(UBSettings::documentName).toString(); -} - -QString UBDocumentProxy::groupName() const -{ - return metaData(UBSettings::documentGroupName).toString(); -} - -QSize UBDocumentProxy::defaultDocumentSize() const -{ - if (mMetaDatas.contains(UBSettings::documentSize)) - return metaData(UBSettings::documentSize).toSize(); - else - return UBSettings::settings()->pageSize->get().toSize(); -} - -void UBDocumentProxy::setDefaultDocumentSize(QSize pSize) -{ - if (defaultDocumentSize() != pSize) - { - setMetaData(UBSettings::documentSize, QVariant(pSize)); - emit defaultDocumentSizeChanged(); - - mIsModified = true; - } -} - -void UBDocumentProxy::setDefaultDocumentSize(int pWidth, int pHeight) -{ - setDefaultDocumentSize(QSize(pWidth, pHeight)); -} - - -QUuid UBDocumentProxy::uuid() const -{ - QString id = metaData(UBSettings::documentIdentifer).toString(); - QString sUuid = id.replace(UBSettings::uniboardDocumentNamespaceUri + "/", ""); - - return QUuid(sUuid); -} - -void UBDocumentProxy::setUuid(const QUuid& uuid) -{ - setMetaData(UBSettings::documentIdentifer, - UBSettings::uniboardDocumentNamespaceUri + "/" + UBStringUtils::toCanonicalUuid(uuid)); -} - - -QDateTime UBDocumentProxy::documentDate() -{ - if(mMetaDatas.contains(UBSettings::documentDate)) - return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentDate).toString()); - return QDateTime::currentDateTime(); -} - -QDateTime UBDocumentProxy::lastUpdate() -{ - if(mMetaDatas.contains(UBSettings::documentUpdatedAt)) - return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentUpdatedAt).toString()); - return QDateTime().currentDateTime(); -} - -bool UBDocumentProxy::isModified() const -{ - return mIsModified; -} - - - - - + + +#include "UBDocumentProxy.h" + +#include "frameworks/UBStringUtils.h" + +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBSettings.h" +#include "core/UBDocumentManager.h" + +#include "core/memcheck.h" + +UBDocumentProxy::UBDocumentProxy() + : mPageCount(0) +{ + init(); +} + + +UBDocumentProxy::UBDocumentProxy(const QString& pPersistancePath) + : mPageCount(0) +{ + init(); + setPersistencePath(pPersistancePath); +} + + +void UBDocumentProxy::init() +{ + setMetaData(UBSettings::documentGroupName, ""); + + QDateTime now = QDateTime::currentDateTime(); + setMetaData(UBSettings::documentName, now.toString(Qt::SystemLocaleShortDate)); + + setUuid(QUuid::createUuid()); + + setDefaultDocumentSize(UBSettings::settings()->pageSize->get().toSize()); + + //teacherGuide metadata + setMetaData(UBSettings::sessionTitle,""); + setMetaData(UBSettings::sessionAuthors,""); + setMetaData(UBSettings::sessionObjectives,""); + setMetaData(UBSettings::sessionKeywords,""); + setMetaData(UBSettings::sessionGradeLevel,""); + setMetaData(UBSettings::sessionSubjects,""); + setMetaData(UBSettings::sessionType,""); + setMetaData(UBSettings::sessionLicence,""); +} + + +UBDocumentProxy::~UBDocumentProxy() +{ + // NOOP +} + + +int UBDocumentProxy::pageCount() +{ + return mPageCount; +} + + +void UBDocumentProxy::setPageCount(int pPageCount) +{ + mPageCount = pPageCount; +} + + +int UBDocumentProxy::incPageCount() +{ + if (mPageCount <= 0) + { + mPageCount = 1; + } + else + { + mPageCount++; + } + + return mPageCount; + +} + + +int UBDocumentProxy::decPageCount() +{ + mPageCount --; + + if (mPageCount < 0) + { + mPageCount = 0; + } + + return mPageCount; +} + +QString UBDocumentProxy::persistencePath() const +{ + return mPersistencePath; +} + +void UBDocumentProxy::setPersistencePath(const QString& pPersistencePath) +{ + if (pPersistencePath != mPersistencePath) + { + mIsModified = true; + mPersistencePath = pPersistencePath; + } +} + +void UBDocumentProxy::setMetaData(const QString& pKey, const QVariant& pValue) +{ + if (mMetaDatas.contains(pKey) && mMetaDatas.value(pKey) == pValue) + return; + else + { + mIsModified = true; + mMetaDatas.insert(pKey, pValue); + if (pKey == UBSettings::documentUpdatedAt) + { + UBDocumentManager *documentManager = UBDocumentManager::documentManager(); + if (documentManager) + documentManager->emitDocumentUpdated(this); + } + } +} + +QVariant UBDocumentProxy::metaData(const QString& pKey) const +{ + if (mMetaDatas.contains(pKey)) + { + return mMetaDatas.value(pKey); + } + else + { + qDebug() << "Unknown metadata key" << pKey; + return QString(""); // failsafe + } +} + +QHash UBDocumentProxy::metaDatas() const +{ + return mMetaDatas; +} + +QString UBDocumentProxy::name() const +{ + return metaData(UBSettings::documentName).toString(); +} + +QString UBDocumentProxy::groupName() const +{ + return metaData(UBSettings::documentGroupName).toString(); +} + +QSize UBDocumentProxy::defaultDocumentSize() const +{ + if (mMetaDatas.contains(UBSettings::documentSize)) + return metaData(UBSettings::documentSize).toSize(); + else + return UBSettings::settings()->pageSize->get().toSize(); +} + +void UBDocumentProxy::setDefaultDocumentSize(QSize pSize) +{ + if (defaultDocumentSize() != pSize) + { + setMetaData(UBSettings::documentSize, QVariant(pSize)); + emit defaultDocumentSizeChanged(); + + mIsModified = true; + } +} + +void UBDocumentProxy::setDefaultDocumentSize(int pWidth, int pHeight) +{ + setDefaultDocumentSize(QSize(pWidth, pHeight)); +} + + +QUuid UBDocumentProxy::uuid() const +{ + QString id = metaData(UBSettings::documentIdentifer).toString(); + QString sUuid = id.replace(UBSettings::uniboardDocumentNamespaceUri + "/", ""); + + return QUuid(sUuid); +} + +void UBDocumentProxy::setUuid(const QUuid& uuid) +{ + setMetaData(UBSettings::documentIdentifer, + UBSettings::uniboardDocumentNamespaceUri + "/" + UBStringUtils::toCanonicalUuid(uuid)); +} + + +QDateTime UBDocumentProxy::documentDate() +{ + if(mMetaDatas.contains(UBSettings::documentDate)) + return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentDate).toString()); + return QDateTime::currentDateTime(); +} + +QDateTime UBDocumentProxy::lastUpdate() +{ + if(mMetaDatas.contains(UBSettings::documentUpdatedAt)) + return UBStringUtils::fromUtcIsoDate(metaData(UBSettings::documentUpdatedAt).toString()); + return QDateTime().currentDateTime(); +} + +bool UBDocumentProxy::isModified() const +{ + return mIsModified; +} + + + + + diff --git a/src/document/UBDocumentProxy.h b/src/document/UBDocumentProxy.h index ba3edf5c..dd55fdb4 100644 --- a/src/document/UBDocumentProxy.h +++ b/src/document/UBDocumentProxy.h @@ -19,89 +19,89 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBDOCUMENTPROXY_H_ -#define UBDOCUMENTPROXY_H_ - -#include - -#include "frameworks/UBStringUtils.h" - -#include "core/UBSettings.h" - -class UBGraphicsScene; - -class UBDocumentProxy : public QObject -{ - Q_OBJECT - - friend class UBPersistenceManager; - - public: - - UBDocumentProxy(); - UBDocumentProxy(const QString& pPersistencePath); - - virtual ~UBDocumentProxy(); - - QString persistencePath() const; - - void setPersistencePath(const QString& pPersistencePath); - - void setMetaData(const QString& pKey , const QVariant& pValue); - QVariant metaData(const QString& pKey) const; - QHash metaDatas() const; - - QString name() const; - QString groupName() const; - QDateTime documentDate(); - - QDateTime lastUpdate(); - - - QSize defaultDocumentSize() const; - void setDefaultDocumentSize(QSize pSize); - void setDefaultDocumentSize(int pWidth, int pHeight); - - QUuid uuid() const; - void setUuid(const QUuid& uuid); - - bool isModified() const; - - int pageCount(); - - protected: - void setPageCount(int pPageCount); - int incPageCount(); - int decPageCount(); - - signals: - void defaultDocumentSizeChanged(); - - private: - - void init(); - - QString mPersistencePath; - - QHash mMetaDatas; - - bool mIsModified; - - int mPageCount; - -}; - -inline bool operator==(const UBDocumentProxy &proxy1, const UBDocumentProxy &proxy2) -{ - return proxy1.persistencePath() == proxy2.persistencePath(); -} - -inline uint qHash(const UBDocumentProxy &key) -{ - return qHash(key.persistencePath()); -} - - -#endif /* UBDOCUMENTPROXY_H_ */ + + +#ifndef UBDOCUMENTPROXY_H_ +#define UBDOCUMENTPROXY_H_ + +#include + +#include "frameworks/UBStringUtils.h" + +#include "core/UBSettings.h" + +class UBGraphicsScene; + +class UBDocumentProxy : public QObject +{ + Q_OBJECT + + friend class UBPersistenceManager; + + public: + + UBDocumentProxy(); + UBDocumentProxy(const QString& pPersistencePath); + + virtual ~UBDocumentProxy(); + + QString persistencePath() const; + + void setPersistencePath(const QString& pPersistencePath); + + void setMetaData(const QString& pKey , const QVariant& pValue); + QVariant metaData(const QString& pKey) const; + QHash metaDatas() const; + + QString name() const; + QString groupName() const; + QDateTime documentDate(); + + QDateTime lastUpdate(); + + + QSize defaultDocumentSize() const; + void setDefaultDocumentSize(QSize pSize); + void setDefaultDocumentSize(int pWidth, int pHeight); + + QUuid uuid() const; + void setUuid(const QUuid& uuid); + + bool isModified() const; + + int pageCount(); + + protected: + void setPageCount(int pPageCount); + int incPageCount(); + int decPageCount(); + + signals: + void defaultDocumentSizeChanged(); + + private: + + void init(); + + QString mPersistencePath; + + QHash mMetaDatas; + + bool mIsModified; + + int mPageCount; + +}; + +inline bool operator==(const UBDocumentProxy &proxy1, const UBDocumentProxy &proxy2) +{ + return proxy1.persistencePath() == proxy2.persistencePath(); +} + +inline uint qHash(const UBDocumentProxy &key) +{ + return qHash(key.persistencePath()); +} + + +#endif /* UBDOCUMENTPROXY_H_ */ diff --git a/src/domain/UBGraphicsDelegateFrame.cpp b/src/domain/UBGraphicsDelegateFrame.cpp index 9b25d041..dddc56b4 100644 --- a/src/domain/UBGraphicsDelegateFrame.cpp +++ b/src/domain/UBGraphicsDelegateFrame.cpp @@ -19,987 +19,987 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBGraphicsDelegateFrame.h" - -#include -#include - -#include "core/UBApplication.h" -#include "core/UBSettings.h" - -#include "board/UBBoardController.h" -#include "board/UBBoardView.h" - -#include "domain/UBGraphicsItemDelegate.h" -#include "domain/UBGraphicsScene.h" -#include "domain/UBGraphicsProxyWidget.h" - -#include "gui/UBResources.h" - -#include "core/memcheck.h" - -UBGraphicsDelegateFrame::UBGraphicsDelegateFrame(UBGraphicsItemDelegate* pDelegate, QRectF pRect, qreal pFrameWidth, bool respectRatio) - : QGraphicsRectItem(), QObject(pDelegate) - , mCurrentTool(None) - , mDelegate(pDelegate) - , mVisible(true) - , mFrameWidth(pFrameWidth) - , mNominalFrameWidth(pFrameWidth) - , mRespectRatio(respectRatio) - , mAngle(0) - , mAngleOffset(0) - , mTotalScaleX(-1) - , mTotalScaleY(-1) - , mTranslateX(0) - , mTranslateY(0) - , mTotalTranslateX(0) - , mTotalTranslateY(0) - , mOperationMode(Scaling) - , mFlippedX(false) - , mFlippedY(false) - , mMirrorX(false) - , mMirrorY(false) -{ - mAngleTolerance = UBSettings::settings()->angleTolerance->get().toReal(); - - setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); - - setAcceptedMouseButtons(Qt::LeftButton); - setRect(pRect.adjusted(mFrameWidth, mFrameWidth, mFrameWidth * -1, mFrameWidth * -1)); - - setBrush(QBrush(UBSettings::paletteColor)); - setPen(Qt::NoPen); - setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); - - mBottomRightResizeGripSvgItem = new QGraphicsSvgItem(":/images/resize.svg", this); - mBottomResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeBottom.svg", this); - mLeftResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeLeft.svg", this); - mRightResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeRight.svg", this); - mTopResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeTop.svg", this); - - mBottomRightResizeGrip = new QGraphicsRectItem(this); - mBottomRightResizeGrip->setPen(Qt::NoPen); - mBottomResizeGrip = new QGraphicsRectItem(this); - mBottomResizeGrip->setPen(Qt::NoPen); - mLeftResizeGrip = new QGraphicsRectItem(this); - mLeftResizeGrip->setPen(Qt::NoPen); - mRightResizeGrip = new QGraphicsRectItem(this); - mRightResizeGrip->setPen(Qt::NoPen); - mTopResizeGrip = new QGraphicsRectItem(this); - mTopResizeGrip->setPen(Qt::NoPen); - - mRotateButton = new QGraphicsSvgItem(":/images/rotate.svg", this); - mRotateButton->setCursor(UBResources::resources()->rotateCursor); - mRotateButton->setVisible(mDelegate->canRotate()); - - updateResizeCursors(); - - setAntiScale(1.0); - - positionHandles(); - - this->setAcceptHoverEvents(true); -} - - -UBGraphicsDelegateFrame::~UBGraphicsDelegateFrame() -{ - // NOOP -} - -void UBGraphicsDelegateFrame::setAntiScale(qreal pAntiScale) -{ - mFrameWidth = mNominalFrameWidth * pAntiScale; - - QTransform tr; - tr.scale(pAntiScale, pAntiScale); - - mBottomRightResizeGripSvgItem->setTransform(tr); - mBottomResizeGripSvgItem->setTransform(tr); - mLeftResizeGripSvgItem->setTransform(tr); - mRightResizeGripSvgItem->setTransform(tr); - mTopResizeGripSvgItem->setTransform(tr); - mRotateButton->setTransform(tr); -} - - -void UBGraphicsDelegateFrame::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - Q_UNUSED(option); - Q_UNUSED(widget); - - QPainterPath path; - path.addRoundedRect(rect(), mFrameWidth / 2, mFrameWidth / 2); - - if (rect().width() > 1 && rect().height() > 1) - { - QPainterPath extruded; - extruded.addRect(rect().adjusted(mFrameWidth, mFrameWidth, (mFrameWidth * -1), (mFrameWidth * -1))); - path = path.subtracted(extruded); - } - - painter->fillPath(path, brush()); -} - - -QPainterPath UBGraphicsDelegateFrame::shape() const -{ - QPainterPath path; - - //We do not use the rounded rect here because we want the bottom right corner - //to be included in the frame (for resize grip handling : #702) - path.addRect(rect()); - - if (rect().width() > 0 && rect().height() > 0) - { - QPainterPath extruded; - extruded.addRect(rect().adjusted(mFrameWidth, mFrameWidth, mFrameWidth * -1, mFrameWidth * -1)); - path = path.subtracted(extruded); - } - - return path; -} - - -void UBGraphicsDelegateFrame::initializeTransform() -{ - QTransform itemTransform = delegated()->sceneTransform(); - QRectF itemRect = delegated()->boundingRect(); - QPointF topLeft = itemTransform.map(itemRect.topLeft()); - QPointF topRight = itemTransform.map(itemRect.topRight()); - QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft()); - - qreal horizontalFlip = (topLeft.x() > topRight.x()) ? -1 : 1; - mMirrorX = horizontalFlip < 0 ; - if(horizontalFlip < 0){ - // why this is because of the way of calculating the translations that checks which side is the most is the - // nearest instead of checking which one is the left side. - QPointF tmp = topLeft; - topLeft = topRight; - topRight = tmp; - - // because of the calculation of the height is done by lenght and not deltaY - bottomLeft = itemTransform.map(itemRect.bottomRight()); - } - - qreal verticalFlip = (bottomLeft.y() < topLeft.y()) ? -1 : 1; - // not sure that is usefull - mMirrorY = verticalFlip < 0; - if(verticalFlip < 0 && !mMirrorX){ - topLeft = itemTransform.map(itemRect.bottomLeft()); - topRight = itemTransform.map(itemRect.bottomRight()); - bottomLeft = itemTransform.map(itemRect.topLeft()); - } - - QLineF topLine(topLeft, topRight); - QLineF leftLine(topLeft, bottomLeft); - qreal width = topLine.length(); - qreal height = leftLine.length(); - - mAngle = topLine.angle(); - - // the fact the the length is used we loose the horizontalFlip information - // a better way to do this is using DeltaX that preserve the direction information. - mTotalScaleX = (width / itemRect.width()) * horizontalFlip; - mTotalScaleY = height / itemRect.height() * verticalFlip; - - QTransform tr; - QPointF center = delegated()->boundingRect().center(); - tr.translate(center.x() * mTotalScaleX, center.y() * mTotalScaleY); - tr.rotate(-mAngle); - tr.translate(-center.x() * mTotalScaleX, -center.y() * mTotalScaleY); - tr.scale(mTotalScaleX, mTotalScaleY); - - mTotalTranslateX = delegated()->transform().dx() - tr.dx(); - mTotalTranslateY = delegated()->transform().dy() - tr.dy(); -} - - -void UBGraphicsDelegateFrame::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - mDelegate->startUndoStep(); - - mStartingPoint = event->scenePos(); - - initializeTransform(); - - mScaleX = 1; - mScaleY = 1; - mTranslateX = 0; - mTranslateY = 0; - mAngleOffset = 0; - - mInitialTransform = buildTransform(); - mOriginalSize = delegated()->boundingRect().size(); - - mCurrentTool = toolFromPos(event->pos()); - setCursorFromAngle(QString::number((int)mAngle % 360)); - event->accept(); - - if (moving()) - prepareFramesToMove(getLinkedFrames()); - -} - -void UBGraphicsDelegateFrame::setCursorFromAngle(QString angle) -{ - if (mCurrentTool == Rotate) - { - QWidget *controlViewport = UBApplication::boardController->controlView()->viewport(); - - QSize cursorSize(45,30); - - - QImage mask_img(cursorSize, QImage::Format_Mono); - mask_img.fill(0xff); - QPainter mask_ptr(&mask_img); - mask_ptr.setBrush( QBrush( QColor(0, 0, 0) ) ); - mask_ptr.drawRoundedRect(0,0, cursorSize.width()-1, cursorSize.height()-1, 6, 6); - QBitmap bmpMask = QBitmap::fromImage(mask_img); - - - QPixmap pixCursor(cursorSize); - pixCursor.fill(QColor(Qt::white)); - - QPainter painter(&pixCursor); - - painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - painter.setBrush(QBrush(Qt::white)); - painter.setPen(QPen(QColor(Qt::black))); - painter.drawRoundedRect(1,1,cursorSize.width()-2,cursorSize.height()-2,6,6); - painter.setFont(QFont("Arial", 10)); - painter.drawText(1,1,cursorSize.width(),cursorSize.height(), Qt::AlignCenter, angle.append(QChar(176))); - painter.end(); - - pixCursor.setMask(bmpMask); - controlViewport->setCursor(pixCursor); - } -} - - -bool UBGraphicsDelegateFrame::canResizeBottomRight(qreal width, qreal height, qreal scaleFactor) -{ - bool res = false; - - if(!mMirrorX && !mMirrorX && ((width * scaleFactor) > 2*mFrameWidth && (height * scaleFactor) > 2*mFrameWidth)){ - res = true; - }else if(mMirrorX && !mMirrorY && (-width * scaleFactor) > 2*mFrameWidth && (height*scaleFactor) > 2*mFrameWidth){ - res = true; - }else if(!mMirrorX && mMirrorY && (width * scaleFactor) > 2*mFrameWidth && (-height*scaleFactor) > 2*mFrameWidth){ - res = true; - }else if(mMirrorX && mMirrorY && (-width * scaleFactor) > 2*mFrameWidth && (-height*scaleFactor) > 2*mFrameWidth){ - res = true; - } - - return res; -} - -QPointF UBGraphicsDelegateFrame::getFixedPointFromPos() -{ - QPointF fixedPoint; - if (!moving() && !rotating()) - { - if (resizingTop()) - { - if (mMirrorX && mMirrorY) - { - if ((0 < mAngle) && (mAngle < 90)) - fixedPoint = delegated()->sceneBoundingRect().topLeft(); - else - fixedPoint = delegated()->sceneBoundingRect().topRight(); - } - else - { - if ((0 < mAngle) && (mAngle <= 90)) - fixedPoint = delegated()->sceneBoundingRect().bottomRight(); - else - fixedPoint = delegated()->sceneBoundingRect().bottomLeft(); - } - } - else if (resizingLeft()) - { - if (mMirrorX && mMirrorY) - { - if ((0 < mAngle) && (mAngle < 90)) - fixedPoint = delegated()->sceneBoundingRect().bottomLeft(); - else - fixedPoint = delegated()->sceneBoundingRect().topLeft(); - } - else - { - if ((0 < mAngle) && (mAngle <= 90)) - fixedPoint = delegated()->sceneBoundingRect().topRight(); - else - fixedPoint = delegated()->sceneBoundingRect().bottomRight(); - } - } - } - return fixedPoint; -} - - -QSizeF UBGraphicsDelegateFrame::getResizeVector(qreal moveX, qreal moveY) -{ - qreal dPosX = 0; - qreal dPosY = 0; - - if (resizingTop()) - { - if (mMirrorX && mMirrorY) - dPosY = moveY; - else - dPosY = -moveY; - } - else if (resizingLeft()) - { - if (mMirrorX && mMirrorY) - dPosX = moveX; - else - dPosX = -moveX; - } - - else if (resizingRight()) - dPosX = (mMirrorX) ? -moveX : moveX; - else if (resizingBottom()) - dPosY = mMirrorY ? -moveY : moveY; - - return QSizeF(dPosX, dPosY); -} - -QSizeF UBGraphicsDelegateFrame::resizeDelegate(qreal moveX, qreal moveY) -{ - QSizeF incVector; - mFixedPoint = getFixedPointFromPos(); - - UBResizableGraphicsItem* resizableItem = dynamic_cast(delegated()); - if (resizableItem) - { - incVector = getResizeVector(moveX, moveY); - resizableItem->resize(mOriginalSize + incVector); - - if (resizingTop() || resizingLeft() || ((mMirrorX || mMirrorY) && resizingBottomRight())) - { - QPointF pos1 = getFixedPointFromPos(); - delegated()->setPos(delegated()->pos()-pos1+mFixedPoint); - } - } - - return incVector; -} - -void UBGraphicsDelegateFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - if (None == mCurrentTool) - return; - - QLineF move = QLineF(mStartingPoint, event->scenePos()); - qreal moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); - qreal moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); - qreal width = delegated()->boundingRect().width() * mTotalScaleX; - qreal height = delegated()->boundingRect().height() * mTotalScaleY; - - if (mOperationMode == Scaling) - { - if(!rotating()) - { - mTranslateX = moveX; - // Perform the resize - if (resizingBottomRight()) - { - // ----------------------------------------------------- - // ! We want to keep the aspect ratio with this resize ! - // ----------------------------------------------------- - qreal scaleX; - qreal scaleY; - - if(!mMirrorX){ - scaleX = (width + moveX) / width; - }else{ - scaleX = (width - moveX) / width; - } - - if(!mMirrorY){ - scaleY = (height + moveY) / height; - }else{ - scaleY = (height - moveY) / height; - } - - qreal scaleFactor = (scaleX + scaleY) / 2; - - // Do not allow resizing of image size under frame size - if (canResizeBottomRight(width, height, scaleFactor)) - { - if (mRespectRatio) - { - mScaleX = scaleFactor; - mScaleY = scaleFactor; - } - else - { - mScaleX = scaleX; - mScaleY = scaleY; - } - } - }else if (resizingLeft() || resizingRight()) - { - if(width != 0){ - qreal scaleX = 0.0; - if(resizingLeft()){ - scaleX = (width - moveX) / width; - }else if(resizingRight()){ - scaleX = (width + moveX) / width; - } - if(mDelegate->isFlippable() && qAbs(scaleX) != 0){ - if((qAbs(width * scaleX)) < 2*mFrameWidth){ - bool negative = (scaleX < 0)?true:false; - if(negative){ - if(mMirrorX) - scaleX = 2*mFrameWidth/width; - else - scaleX = -2*mFrameWidth/width; - }else{ - scaleX = -1; - mFlippedX = !mFlippedX; - } - } - mScaleX = scaleX; - }else if (scaleX > 1 || (width * scaleX) > 2 * mFrameWidth){ - mScaleX = scaleX; - if(resizingLeft()){ - mTranslateX = moveX; - } - } - } - }else if(resizingTop() || resizingBottom()){ - if(height != 0){ - qreal scaleY = 0.0; - if(resizingTop()){ - scaleY = (height - moveY) / height; - }else if(resizingBottom()){ - scaleY = (height + moveY) / height; - } - - if(mDelegate->isFlippable() && qAbs(scaleY) != 0){ - if((qAbs(height * scaleY)) < 2*mFrameWidth){ - bool negative = (scaleY < 0)?true:false; - if(negative){ - if(mMirrorY) - scaleY = 2*mFrameWidth/width; - else - scaleY = -2*mFrameWidth/width; - }else{ - scaleY = -1; - mFlippedY = !mFlippedY; - } - } - mScaleY = scaleY; - }else if (scaleY > 1 || (height * scaleY) > 2 * mFrameWidth) - { - mScaleY = scaleY; - if(resizingTop()){ - mTranslateY = moveY; - } - } - } - } - } - } - - if (rotating()) - { - mTranslateX = 0; - mTranslateY = 0; - - QLineF startLine(sceneBoundingRect().center(), event->lastScenePos()); - QLineF currentLine(sceneBoundingRect().center(), event->scenePos()); - mAngle += startLine.angleTo(currentLine); - - if ((int)mAngle % 45 >= 45 - mAngleTolerance || (int)mAngle % 45 <= mAngleTolerance) - { - mAngle = qRound(mAngle / 45) * 45; - mAngleOffset += startLine.angleTo(currentLine); - if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) - { - mAngle += mAngleOffset; - mAngleOffset = 0; - } - } - else if ((int)mAngle % 30 >= 30 - mAngleTolerance || (int)mAngle % 30 <= mAngleTolerance) - { - mAngle = qRound(mAngle / 30) * 30; - mAngleOffset += startLine.angleTo(currentLine); - if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) - { - mAngle += mAngleOffset; - mAngleOffset = 0; - } - } - - setCursorFromAngle(QString::number((int)mAngle % 360)); - } - else if (moving()) - { - mTranslateX = move.dx(); - mTranslateY = move.dy(); - moveLinkedItems(move); - } - - if (mOperationMode == Scaling || moving() || rotating()) - { - QTransform tr = buildTransform(); - - if (resizingRight() || resizingBottom() || resizingBottomRight()) - { - QPointF ref; - - // we just detects coordinates of corner before and after scaling and then moves object at diff between them. - if (resizingBottomRight() && (mMirrorX || mMirrorY)) - { - if (mFlippedX && !mMirrorX && mFlippedY)// && !mMirrorY) - { - mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); - mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); - } - else if ((mFlippedX || mMirrorX) && (mFlippedY || mMirrorY)) - { - mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); - mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); - } - else if (mFlippedX || mMirrorX) - { - mTranslateX += mInitialTransform.map(delegated()->boundingRect().topRight()).x() - tr.map(delegated()->boundingRect().topRight()).x(); - mTranslateY += mInitialTransform.map(delegated()->boundingRect().topRight()).y() - tr.map(delegated()->boundingRect().topRight()).y(); - } - else if (mFlippedY || mMirrorY) - { - mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); - mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); - } - else - { - mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); - mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); - } - } - else - { - mTranslateX += mInitialTransform.map(delegated()->boundingRect().topLeft()).x() - tr.map(delegated()->boundingRect().topLeft()).x(); - mTranslateY += mInitialTransform.map(delegated()->boundingRect().topLeft()).y() - tr.map(delegated()->boundingRect().topLeft()).y(); - } - } - else if (resizingTop() || resizingLeft()) - { - QPointF bottomRight = tr.map(delegated()->boundingRect().bottomRight()); - QPointF fixedPoint = mInitialTransform.map(delegated()->boundingRect().bottomRight()); - mTranslateX += fixedPoint.x() - bottomRight.x(); - mTranslateY += fixedPoint.y() - bottomRight.y(); - } - delegated()->setTransform(buildTransform()); - } - else // resizing/resizing horizontally - { - - if (resizingBottomRight()) - { - static QSizeF incV = QSizeF(); - static QSizeF incH = QSizeF(); - - if (mMirrorX && mMirrorY) - mCurrentTool = ResizeTop; - else - mCurrentTool = ResizeBottom; - - incV = resizeDelegate(moveX, moveY); - mOriginalSize += incV; - - if (mMirrorX && mMirrorY) - mCurrentTool = ResizeLeft; - else - mCurrentTool = ResizeRight; - - move = QLineF(event->lastScenePos(), event->scenePos()); - moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); - moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); - - mFixedPoint = getFixedPointFromPos(); - - incH = resizeDelegate(moveX, moveY); - - mOriginalSize -= incV; - mOriginalSize += incH; - - mCurrentTool = ResizeBottomRight; - } - else - resizeDelegate(moveX, moveY); - } - event->accept(); -} - -QList UBGraphicsDelegateFrame::getLinkedFrames() -{ - QList linkedFrames; - QList sItems = mDelegate->delegated()->scene()->selectedItems(); - if (sItems.count()) - { - sItems.removeAll(delegated()); - - foreach(QGraphicsItem *item, sItems) - { - UBGraphicsItem *gitem = dynamic_cast(item); - if (gitem) - linkedFrames << gitem->Delegate()->frame(); - } - } - return linkedFrames; -} - -void UBGraphicsDelegateFrame::prepareFramesToMove(QList framesToMove) -{ - mLinkedFrames = framesToMove; - foreach (UBGraphicsDelegateFrame *frame, mLinkedFrames) - { - frame->prepareLinkedFrameToMove(); - } -} - -void UBGraphicsDelegateFrame::prepareLinkedFrameToMove() -{ - mDelegate->startUndoStep(); - - mStartingPoint = QPointF(0,0); - - initializeTransform(); - - mScaleX = 1; - mScaleY = 1; - mTranslateX = 0; - mTranslateY = 0; - mAngleOffset = 0; - - mInitialTransform = buildTransform(); - - mCurrentTool = Move; -} - -void UBGraphicsDelegateFrame::moveLinkedItems(QLineF movingVector, bool bLinked) -{ - if (bLinked) - { - mCurrentTool = Move; - - mTranslateX = movingVector.dx(); - mTranslateY = movingVector.dy(); - - delegated()->setTransform(buildTransform(), false); - } - else - { - foreach(UBGraphicsDelegateFrame* frame, mLinkedFrames) - { - frame->moveLinkedItems(movingVector, true); - } - } -} - -QTransform UBGraphicsDelegateFrame::buildTransform() -{ - QTransform tr; - QPointF center = delegated()->boundingRect().center(); - - // Translate - tr.translate(mTotalTranslateX + mTranslateX, mTotalTranslateY + mTranslateY); - - // Set angle - tr.translate(center.x() * mTotalScaleX * mScaleX, center.y() * mTotalScaleY * mScaleY); - tr.rotate(-mAngle); - tr.translate(-center.x() * mTotalScaleX * mScaleX, -center.y() * mTotalScaleY * mScaleY); - - // Scale - tr.scale(mTotalScaleX * mScaleX, mTotalScaleY * mScaleY); - return tr; -} - - -void UBGraphicsDelegateFrame::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - updateResizeCursors(); - - mDelegate->commitUndoStep(); - mTotalScaleX *= mScaleX; - mTotalScaleY *= mScaleY; - mTotalTranslateX += mTranslateX; - mTotalTranslateY += mTranslateY; - event->accept(); - - mCurrentTool = None; - - QGraphicsRectItem::mouseReleaseEvent(event); - - // Show the buttons - if(isResizing()){ - mResizing = false; - } -} - - -void UBGraphicsDelegateFrame::updateResizeCursors() -{ - QPixmap pix(":/images/cursors/resize.png"); - QTransform tr; - - tr.rotate(-mAngle); - QCursor resizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); - mLeftResizeGrip->setCursor(resizeCursor); - mRightResizeGrip->setCursor(resizeCursor); - - tr.rotate(-90); - resizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); - mBottomResizeGrip->setCursor(resizeCursor); - mTopResizeGrip->setCursor(resizeCursor); - - tr.rotate(-45); - resizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); - mBottomRightResizeGrip->setCursor(resizeCursor); -} - - -void UBGraphicsDelegateFrame::setVisible(bool visible) -{ - mVisible = visible; - if (mVisible) - setBrush(QBrush(UBSettings::paletteColor)); - else - setBrush(Qt::NoBrush); -} - - -void UBGraphicsDelegateFrame::positionHandles() -{ - QRectF itemRect = delegated()->boundingRect(); - - if (mDelegate->getToolBarItem() && mDelegate->getToolBarItem()->isVisibleOnBoard() - && mDelegate->getToolBarItem()->isShifting()) - { - QPointF graphicsItemPosition = itemRect.topLeft(); - itemRect.setTopLeft(graphicsItemPosition-QPointF(0,mDelegate->getToolBarItem()->boundingRect().height()* mDelegate->antiScaleRatio())); - } - - QTransform itemTransform = delegated()->sceneTransform(); - QPointF topLeft = itemTransform.map(itemRect.topLeft()); - QPointF topRight = itemTransform.map(itemRect.topRight()); - QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft()); - QPointF bottomRight = itemTransform.map(itemRect.bottomRight()); - QPointF center = itemTransform.map(itemRect.center()); - int rotateHeight = QLineF(topLeft, bottomLeft).length(); - - // Handle the mirroring - if(topLeft.x() > topRight.x()){ - QPointF topTmp = topRight; - QPointF bottomTmp = bottomRight; - topRight = topLeft; - topLeft = topTmp; - bottomRight = bottomLeft; - bottomLeft = bottomTmp; - } - - if(bottomLeft.y() > topLeft.y()){ - QPointF leftTmp = bottomLeft; - QPointF rightTmp = bottomRight; - bottomLeft = topLeft; - topLeft = leftTmp; - bottomRight = topRight; - topRight = rightTmp; - } - - QLineF topLine(topLeft, topRight); - qreal angle = topLine.angle(); - qreal width = topLine.length(); - - QLineF leftLine(topLeft, bottomLeft); - qreal height = leftLine.length(); - - int h = rotating()?rotateHeight:height; - - if (mVisible) - { - setRect(center.x() - mFrameWidth - width / 2, center.y() - mFrameWidth - h / 2, width + 2 * mFrameWidth, h + 2 * mFrameWidth); - } - else - { - setRect(center.x() - width / 2, center.y() - h / 2, width, h); - } - - resetTransform(); - translate(center.x(), center.y()); - rotate(-angle); - translate(-center.x(), -center.y()); - - mBottomRightResizeGripSvgItem->setParentItem(this); - mBottomResizeGripSvgItem->setParentItem(this); - mLeftResizeGripSvgItem->setParentItem(this); - mRightResizeGripSvgItem->setParentItem(this); - mTopResizeGripSvgItem->setParentItem(this); - mRotateButton->setParentItem(this); - - mBottomRightResizeGrip->setParentItem(this); - mBottomResizeGrip->setParentItem(this); - mLeftResizeGrip->setParentItem(this); - mRightResizeGrip->setParentItem(this); - mTopResizeGrip->setParentItem(this); - - QRectF brRect = mBottomRightResizeGripSvgItem->mapRectToParent(mBottomRightResizeGripSvgItem->boundingRect()); - QRectF bRect = mBottomResizeGripSvgItem->mapRectToParent(mBottomResizeGripSvgItem->boundingRect()); - QRectF lRect = mLeftResizeGripSvgItem->mapRectToParent(mLeftResizeGripSvgItem->boundingRect()); - QRectF rRect = mRightResizeGripSvgItem->mapRectToParent(mRightResizeGripSvgItem->boundingRect()); - QRectF trRect = mTopResizeGripSvgItem->mapRectToParent(mTopResizeGripSvgItem->boundingRect()); - - mBottomRightResizeGripSvgItem->setPos(rect().right() - brRect.width(), rect().bottom() - brRect.height()); - mBottomResizeGripSvgItem->setPos(rect().center().x() - bRect.width() / 2, rect().bottom() - bRect.height()); - - mLeftResizeGripSvgItem->setPos(rect().left(), rect().center().y() - lRect.height() / 2); - mRightResizeGripSvgItem->setPos(rect().right() - rRect.width(), rect().center().y() - rRect.height() / 2); - - mTopResizeGripSvgItem->setPos(rect().center().x() - trRect.width() / 2, rect().y()); - mRotateButton->setPos(rect().right() - mFrameWidth - 5, rect().top() + 5); - - mBottomRightResizeGrip->setRect(bottomRightResizeGripRect()); - mBottomResizeGrip->setRect(bottomResizeGripRect()); - mLeftResizeGrip->setRect(leftResizeGripRect()); - mRightResizeGrip->setRect(rightResizeGripRect()); - mTopResizeGrip->setRect(topResizeGripRect()); - - QVariant vLocked = delegated()->data(UBGraphicsItemData::ItemLocked); - bool isLocked = (vLocked.isValid() && vLocked.toBool()); - bool bShowHorizontalResizers = ResizingHorizontally == mOperationMode; - bool bShowVerticalResizers = ResizingHorizontally != mOperationMode; - bool bShowAllResizers = Resizing == mOperationMode || Scaling == mOperationMode ; - - mBottomRightResizeGripSvgItem->setVisible(!isLocked && bShowAllResizers); - mBottomResizeGripSvgItem->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); - mLeftResizeGripSvgItem->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); - mRightResizeGripSvgItem->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); - mTopResizeGripSvgItem->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); - mRotateButton->setVisible(mDelegate->canRotate() && !isLocked); - - mBottomRightResizeGrip->setVisible(!isLocked && bShowAllResizers); - mBottomResizeGrip->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); - mLeftResizeGrip->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); - mRightResizeGrip->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); - mTopResizeGrip->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); - - if (isLocked) - { - QColor baseColor = UBSettings::paletteColor; - baseColor.setAlphaF(baseColor.alphaF() / 3); - setBrush(QBrush(baseColor)); - } - else - { - setBrush(QBrush(UBSettings::paletteColor)); - } - - //make frame interact like delegated item when selected. Maybe should be deleted if selection logic will change - setZValue(delegated()->zValue()); -} - - -QGraphicsItem* UBGraphicsDelegateFrame::delegated() -{ - return mDelegate->delegated(); -} - -UBGraphicsDelegateFrame::FrameTool UBGraphicsDelegateFrame::toolFromPos(QPointF pos) -{ - if(mDelegate->isLocked()) - return None; - else if (bottomRightResizeGripRect().contains(pos) && ResizingHorizontally != mOperationMode) - return ResizeBottomRight; - else if (bottomResizeGripRect().contains(pos) && ResizingHorizontally != mOperationMode){ - if(mMirrorY){ - return ResizeTop; - }else{ - return ResizeBottom; - } - } - else if (leftResizeGripRect().contains(pos)){ - if(mMirrorX){ - return ResizeRight; - }else{ - return ResizeLeft; - } - return ResizeLeft; - } - else if (rightResizeGripRect().contains(pos)){ - if(mMirrorX){ - return ResizeLeft; - }else{ - return ResizeRight; - } - } - else if (topResizeGripRect().contains(pos) && ResizingHorizontally != mOperationMode){ - if(mMirrorY){ - return ResizeBottom; - }else{ - return ResizeTop; - } - } - else if (rotateButtonBounds().contains(pos) && mDelegate && mDelegate->canRotate()) - return Rotate; - else - return Move; -} - - -QRectF UBGraphicsDelegateFrame::bottomRightResizeGripRect() const -{ - return QRectF(rect().right() - mFrameWidth, rect().bottom() - mFrameWidth, mFrameWidth, mFrameWidth); -} - - -QRectF UBGraphicsDelegateFrame::bottomResizeGripRect() const -{ - return QRectF(rect().center().x() - mFrameWidth / 2, rect().bottom() - mFrameWidth, mFrameWidth, mFrameWidth); -} - - -QRectF UBGraphicsDelegateFrame::leftResizeGripRect() const -{ - return QRectF(rect().left(), rect().center().y() - mFrameWidth / 2, mFrameWidth, mFrameWidth); -} - - -QRectF UBGraphicsDelegateFrame::rightResizeGripRect() const -{ - return QRectF(rect().right() - mFrameWidth, rect().center().y() - mFrameWidth / 2, mFrameWidth, mFrameWidth); -} - - -QRectF UBGraphicsDelegateFrame::topResizeGripRect() const -{ - return QRectF(rect().center().x() - mFrameWidth / 2, rect().top(), mFrameWidth, mFrameWidth); -} - - -QRectF UBGraphicsDelegateFrame::rotateButtonBounds() const -{ - return QRectF(rect().right()- mFrameWidth, rect().top(), mFrameWidth, mFrameWidth); -} - -void UBGraphicsDelegateFrame::refreshGeometry() -{ - // Here we want to have the left on the left, the right on the right, the top on the top and the bottom on the bottom! - QRectF itemRect = delegated()->boundingRect(); - QTransform itemTransform = delegated()->sceneTransform(); - QPointF topLeft = itemTransform.map(itemRect.topLeft()); - QPointF topRight = itemTransform.map(itemRect.topRight()); - QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft()); - - QLineF topLine(topLeft, topRight); - qreal width = topLine.length(); - QLineF leftLine(topLeft, bottomLeft); - qreal height = leftLine.length(); - setRect(topRight.x() - mFrameWidth, topLeft.y() - mFrameWidth, width + 2*mFrameWidth, height + 2*mFrameWidth); -} + + +#include "UBGraphicsDelegateFrame.h" + +#include +#include + +#include "core/UBApplication.h" +#include "core/UBSettings.h" + +#include "board/UBBoardController.h" +#include "board/UBBoardView.h" + +#include "domain/UBGraphicsItemDelegate.h" +#include "domain/UBGraphicsScene.h" +#include "domain/UBGraphicsProxyWidget.h" + +#include "gui/UBResources.h" + +#include "core/memcheck.h" + +UBGraphicsDelegateFrame::UBGraphicsDelegateFrame(UBGraphicsItemDelegate* pDelegate, QRectF pRect, qreal pFrameWidth, bool respectRatio) + : QGraphicsRectItem(), QObject(pDelegate) + , mCurrentTool(None) + , mDelegate(pDelegate) + , mVisible(true) + , mFrameWidth(pFrameWidth) + , mNominalFrameWidth(pFrameWidth) + , mRespectRatio(respectRatio) + , mAngle(0) + , mAngleOffset(0) + , mTotalScaleX(-1) + , mTotalScaleY(-1) + , mTranslateX(0) + , mTranslateY(0) + , mTotalTranslateX(0) + , mTotalTranslateY(0) + , mOperationMode(Scaling) + , mFlippedX(false) + , mFlippedY(false) + , mMirrorX(false) + , mMirrorY(false) +{ + mAngleTolerance = UBSettings::settings()->angleTolerance->get().toReal(); + + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + + setAcceptedMouseButtons(Qt::LeftButton); + setRect(pRect.adjusted(mFrameWidth, mFrameWidth, mFrameWidth * -1, mFrameWidth * -1)); + + setBrush(QBrush(UBSettings::paletteColor)); + setPen(Qt::NoPen); + setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); + + mBottomRightResizeGripSvgItem = new QGraphicsSvgItem(":/images/resize.svg", this); + mBottomResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeBottom.svg", this); + mLeftResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeLeft.svg", this); + mRightResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeRight.svg", this); + mTopResizeGripSvgItem = new QGraphicsSvgItem(":/images/resizeTop.svg", this); + + mBottomRightResizeGrip = new QGraphicsRectItem(this); + mBottomRightResizeGrip->setPen(Qt::NoPen); + mBottomResizeGrip = new QGraphicsRectItem(this); + mBottomResizeGrip->setPen(Qt::NoPen); + mLeftResizeGrip = new QGraphicsRectItem(this); + mLeftResizeGrip->setPen(Qt::NoPen); + mRightResizeGrip = new QGraphicsRectItem(this); + mRightResizeGrip->setPen(Qt::NoPen); + mTopResizeGrip = new QGraphicsRectItem(this); + mTopResizeGrip->setPen(Qt::NoPen); + + mRotateButton = new QGraphicsSvgItem(":/images/rotate.svg", this); + mRotateButton->setCursor(UBResources::resources()->rotateCursor); + mRotateButton->setVisible(mDelegate->canRotate()); + + updateResizeCursors(); + + setAntiScale(1.0); + + positionHandles(); + + this->setAcceptHoverEvents(true); +} + + +UBGraphicsDelegateFrame::~UBGraphicsDelegateFrame() +{ + // NOOP +} + +void UBGraphicsDelegateFrame::setAntiScale(qreal pAntiScale) +{ + mFrameWidth = mNominalFrameWidth * pAntiScale; + + QTransform tr; + tr.scale(pAntiScale, pAntiScale); + + mBottomRightResizeGripSvgItem->setTransform(tr); + mBottomResizeGripSvgItem->setTransform(tr); + mLeftResizeGripSvgItem->setTransform(tr); + mRightResizeGripSvgItem->setTransform(tr); + mTopResizeGripSvgItem->setTransform(tr); + mRotateButton->setTransform(tr); +} + + +void UBGraphicsDelegateFrame::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + QPainterPath path; + path.addRoundedRect(rect(), mFrameWidth / 2, mFrameWidth / 2); + + if (rect().width() > 1 && rect().height() > 1) + { + QPainterPath extruded; + extruded.addRect(rect().adjusted(mFrameWidth, mFrameWidth, (mFrameWidth * -1), (mFrameWidth * -1))); + path = path.subtracted(extruded); + } + + painter->fillPath(path, brush()); +} + + +QPainterPath UBGraphicsDelegateFrame::shape() const +{ + QPainterPath path; + + //We do not use the rounded rect here because we want the bottom right corner + //to be included in the frame (for resize grip handling : #702) + path.addRect(rect()); + + if (rect().width() > 0 && rect().height() > 0) + { + QPainterPath extruded; + extruded.addRect(rect().adjusted(mFrameWidth, mFrameWidth, mFrameWidth * -1, mFrameWidth * -1)); + path = path.subtracted(extruded); + } + + return path; +} + + +void UBGraphicsDelegateFrame::initializeTransform() +{ + QTransform itemTransform = delegated()->sceneTransform(); + QRectF itemRect = delegated()->boundingRect(); + QPointF topLeft = itemTransform.map(itemRect.topLeft()); + QPointF topRight = itemTransform.map(itemRect.topRight()); + QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft()); + + qreal horizontalFlip = (topLeft.x() > topRight.x()) ? -1 : 1; + mMirrorX = horizontalFlip < 0 ; + if(horizontalFlip < 0){ + // why this is because of the way of calculating the translations that checks which side is the most is the + // nearest instead of checking which one is the left side. + QPointF tmp = topLeft; + topLeft = topRight; + topRight = tmp; + + // because of the calculation of the height is done by lenght and not deltaY + bottomLeft = itemTransform.map(itemRect.bottomRight()); + } + + qreal verticalFlip = (bottomLeft.y() < topLeft.y()) ? -1 : 1; + // not sure that is usefull + mMirrorY = verticalFlip < 0; + if(verticalFlip < 0 && !mMirrorX){ + topLeft = itemTransform.map(itemRect.bottomLeft()); + topRight = itemTransform.map(itemRect.bottomRight()); + bottomLeft = itemTransform.map(itemRect.topLeft()); + } + + QLineF topLine(topLeft, topRight); + QLineF leftLine(topLeft, bottomLeft); + qreal width = topLine.length(); + qreal height = leftLine.length(); + + mAngle = topLine.angle(); + + // the fact the the length is used we loose the horizontalFlip information + // a better way to do this is using DeltaX that preserve the direction information. + mTotalScaleX = (width / itemRect.width()) * horizontalFlip; + mTotalScaleY = height / itemRect.height() * verticalFlip; + + QTransform tr; + QPointF center = delegated()->boundingRect().center(); + tr.translate(center.x() * mTotalScaleX, center.y() * mTotalScaleY); + tr.rotate(-mAngle); + tr.translate(-center.x() * mTotalScaleX, -center.y() * mTotalScaleY); + tr.scale(mTotalScaleX, mTotalScaleY); + + mTotalTranslateX = delegated()->transform().dx() - tr.dx(); + mTotalTranslateY = delegated()->transform().dy() - tr.dy(); +} + + +void UBGraphicsDelegateFrame::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + mDelegate->startUndoStep(); + + mStartingPoint = event->scenePos(); + + initializeTransform(); + + mScaleX = 1; + mScaleY = 1; + mTranslateX = 0; + mTranslateY = 0; + mAngleOffset = 0; + + mInitialTransform = buildTransform(); + mOriginalSize = delegated()->boundingRect().size(); + + mCurrentTool = toolFromPos(event->pos()); + setCursorFromAngle(QString::number((int)mAngle % 360)); + event->accept(); + + if (moving()) + prepareFramesToMove(getLinkedFrames()); + +} + +void UBGraphicsDelegateFrame::setCursorFromAngle(QString angle) +{ + if (mCurrentTool == Rotate) + { + QWidget *controlViewport = UBApplication::boardController->controlView()->viewport(); + + QSize cursorSize(45,30); + + + QImage mask_img(cursorSize, QImage::Format_Mono); + mask_img.fill(0xff); + QPainter mask_ptr(&mask_img); + mask_ptr.setBrush( QBrush( QColor(0, 0, 0) ) ); + mask_ptr.drawRoundedRect(0,0, cursorSize.width()-1, cursorSize.height()-1, 6, 6); + QBitmap bmpMask = QBitmap::fromImage(mask_img); + + + QPixmap pixCursor(cursorSize); + pixCursor.fill(QColor(Qt::white)); + + QPainter painter(&pixCursor); + + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + painter.setBrush(QBrush(Qt::white)); + painter.setPen(QPen(QColor(Qt::black))); + painter.drawRoundedRect(1,1,cursorSize.width()-2,cursorSize.height()-2,6,6); + painter.setFont(QFont("Arial", 10)); + painter.drawText(1,1,cursorSize.width(),cursorSize.height(), Qt::AlignCenter, angle.append(QChar(176))); + painter.end(); + + pixCursor.setMask(bmpMask); + controlViewport->setCursor(pixCursor); + } +} + + +bool UBGraphicsDelegateFrame::canResizeBottomRight(qreal width, qreal height, qreal scaleFactor) +{ + bool res = false; + + if(!mMirrorX && !mMirrorX && ((width * scaleFactor) > 2*mFrameWidth && (height * scaleFactor) > 2*mFrameWidth)){ + res = true; + }else if(mMirrorX && !mMirrorY && (-width * scaleFactor) > 2*mFrameWidth && (height*scaleFactor) > 2*mFrameWidth){ + res = true; + }else if(!mMirrorX && mMirrorY && (width * scaleFactor) > 2*mFrameWidth && (-height*scaleFactor) > 2*mFrameWidth){ + res = true; + }else if(mMirrorX && mMirrorY && (-width * scaleFactor) > 2*mFrameWidth && (-height*scaleFactor) > 2*mFrameWidth){ + res = true; + } + + return res; +} + +QPointF UBGraphicsDelegateFrame::getFixedPointFromPos() +{ + QPointF fixedPoint; + if (!moving() && !rotating()) + { + if (resizingTop()) + { + if (mMirrorX && mMirrorY) + { + if ((0 < mAngle) && (mAngle < 90)) + fixedPoint = delegated()->sceneBoundingRect().topLeft(); + else + fixedPoint = delegated()->sceneBoundingRect().topRight(); + } + else + { + if ((0 < mAngle) && (mAngle <= 90)) + fixedPoint = delegated()->sceneBoundingRect().bottomRight(); + else + fixedPoint = delegated()->sceneBoundingRect().bottomLeft(); + } + } + else if (resizingLeft()) + { + if (mMirrorX && mMirrorY) + { + if ((0 < mAngle) && (mAngle < 90)) + fixedPoint = delegated()->sceneBoundingRect().bottomLeft(); + else + fixedPoint = delegated()->sceneBoundingRect().topLeft(); + } + else + { + if ((0 < mAngle) && (mAngle <= 90)) + fixedPoint = delegated()->sceneBoundingRect().topRight(); + else + fixedPoint = delegated()->sceneBoundingRect().bottomRight(); + } + } + } + return fixedPoint; +} + + +QSizeF UBGraphicsDelegateFrame::getResizeVector(qreal moveX, qreal moveY) +{ + qreal dPosX = 0; + qreal dPosY = 0; + + if (resizingTop()) + { + if (mMirrorX && mMirrorY) + dPosY = moveY; + else + dPosY = -moveY; + } + else if (resizingLeft()) + { + if (mMirrorX && mMirrorY) + dPosX = moveX; + else + dPosX = -moveX; + } + + else if (resizingRight()) + dPosX = (mMirrorX) ? -moveX : moveX; + else if (resizingBottom()) + dPosY = mMirrorY ? -moveY : moveY; + + return QSizeF(dPosX, dPosY); +} + +QSizeF UBGraphicsDelegateFrame::resizeDelegate(qreal moveX, qreal moveY) +{ + QSizeF incVector; + mFixedPoint = getFixedPointFromPos(); + + UBResizableGraphicsItem* resizableItem = dynamic_cast(delegated()); + if (resizableItem) + { + incVector = getResizeVector(moveX, moveY); + resizableItem->resize(mOriginalSize + incVector); + + if (resizingTop() || resizingLeft() || ((mMirrorX || mMirrorY) && resizingBottomRight())) + { + QPointF pos1 = getFixedPointFromPos(); + delegated()->setPos(delegated()->pos()-pos1+mFixedPoint); + } + } + + return incVector; +} + +void UBGraphicsDelegateFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (None == mCurrentTool) + return; + + QLineF move = QLineF(mStartingPoint, event->scenePos()); + qreal moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); + qreal moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); + qreal width = delegated()->boundingRect().width() * mTotalScaleX; + qreal height = delegated()->boundingRect().height() * mTotalScaleY; + + if (mOperationMode == Scaling) + { + if(!rotating()) + { + mTranslateX = moveX; + // Perform the resize + if (resizingBottomRight()) + { + // ----------------------------------------------------- + // ! We want to keep the aspect ratio with this resize ! + // ----------------------------------------------------- + qreal scaleX; + qreal scaleY; + + if(!mMirrorX){ + scaleX = (width + moveX) / width; + }else{ + scaleX = (width - moveX) / width; + } + + if(!mMirrorY){ + scaleY = (height + moveY) / height; + }else{ + scaleY = (height - moveY) / height; + } + + qreal scaleFactor = (scaleX + scaleY) / 2; + + // Do not allow resizing of image size under frame size + if (canResizeBottomRight(width, height, scaleFactor)) + { + if (mRespectRatio) + { + mScaleX = scaleFactor; + mScaleY = scaleFactor; + } + else + { + mScaleX = scaleX; + mScaleY = scaleY; + } + } + }else if (resizingLeft() || resizingRight()) + { + if(width != 0){ + qreal scaleX = 0.0; + if(resizingLeft()){ + scaleX = (width - moveX) / width; + }else if(resizingRight()){ + scaleX = (width + moveX) / width; + } + if(mDelegate->isFlippable() && qAbs(scaleX) != 0){ + if((qAbs(width * scaleX)) < 2*mFrameWidth){ + bool negative = (scaleX < 0)?true:false; + if(negative){ + if(mMirrorX) + scaleX = 2*mFrameWidth/width; + else + scaleX = -2*mFrameWidth/width; + }else{ + scaleX = -1; + mFlippedX = !mFlippedX; + } + } + mScaleX = scaleX; + }else if (scaleX > 1 || (width * scaleX) > 2 * mFrameWidth){ + mScaleX = scaleX; + if(resizingLeft()){ + mTranslateX = moveX; + } + } + } + }else if(resizingTop() || resizingBottom()){ + if(height != 0){ + qreal scaleY = 0.0; + if(resizingTop()){ + scaleY = (height - moveY) / height; + }else if(resizingBottom()){ + scaleY = (height + moveY) / height; + } + + if(mDelegate->isFlippable() && qAbs(scaleY) != 0){ + if((qAbs(height * scaleY)) < 2*mFrameWidth){ + bool negative = (scaleY < 0)?true:false; + if(negative){ + if(mMirrorY) + scaleY = 2*mFrameWidth/width; + else + scaleY = -2*mFrameWidth/width; + }else{ + scaleY = -1; + mFlippedY = !mFlippedY; + } + } + mScaleY = scaleY; + }else if (scaleY > 1 || (height * scaleY) > 2 * mFrameWidth) + { + mScaleY = scaleY; + if(resizingTop()){ + mTranslateY = moveY; + } + } + } + } + } + } + + if (rotating()) + { + mTranslateX = 0; + mTranslateY = 0; + + QLineF startLine(sceneBoundingRect().center(), event->lastScenePos()); + QLineF currentLine(sceneBoundingRect().center(), event->scenePos()); + mAngle += startLine.angleTo(currentLine); + + if ((int)mAngle % 45 >= 45 - mAngleTolerance || (int)mAngle % 45 <= mAngleTolerance) + { + mAngle = qRound(mAngle / 45) * 45; + mAngleOffset += startLine.angleTo(currentLine); + if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) + { + mAngle += mAngleOffset; + mAngleOffset = 0; + } + } + else if ((int)mAngle % 30 >= 30 - mAngleTolerance || (int)mAngle % 30 <= mAngleTolerance) + { + mAngle = qRound(mAngle / 30) * 30; + mAngleOffset += startLine.angleTo(currentLine); + if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) + { + mAngle += mAngleOffset; + mAngleOffset = 0; + } + } + + setCursorFromAngle(QString::number((int)mAngle % 360)); + } + else if (moving()) + { + mTranslateX = move.dx(); + mTranslateY = move.dy(); + moveLinkedItems(move); + } + + if (mOperationMode == Scaling || moving() || rotating()) + { + QTransform tr = buildTransform(); + + if (resizingRight() || resizingBottom() || resizingBottomRight()) + { + QPointF ref; + + // we just detects coordinates of corner before and after scaling and then moves object at diff between them. + if (resizingBottomRight() && (mMirrorX || mMirrorY)) + { + if (mFlippedX && !mMirrorX && mFlippedY)// && !mMirrorY) + { + mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); + mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); + } + else if ((mFlippedX || mMirrorX) && (mFlippedY || mMirrorY)) + { + mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); + mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); + } + else if (mFlippedX || mMirrorX) + { + mTranslateX += mInitialTransform.map(delegated()->boundingRect().topRight()).x() - tr.map(delegated()->boundingRect().topRight()).x(); + mTranslateY += mInitialTransform.map(delegated()->boundingRect().topRight()).y() - tr.map(delegated()->boundingRect().topRight()).y(); + } + else if (mFlippedY || mMirrorY) + { + mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); + mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); + } + else + { + mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); + mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); + } + } + else + { + mTranslateX += mInitialTransform.map(delegated()->boundingRect().topLeft()).x() - tr.map(delegated()->boundingRect().topLeft()).x(); + mTranslateY += mInitialTransform.map(delegated()->boundingRect().topLeft()).y() - tr.map(delegated()->boundingRect().topLeft()).y(); + } + } + else if (resizingTop() || resizingLeft()) + { + QPointF bottomRight = tr.map(delegated()->boundingRect().bottomRight()); + QPointF fixedPoint = mInitialTransform.map(delegated()->boundingRect().bottomRight()); + mTranslateX += fixedPoint.x() - bottomRight.x(); + mTranslateY += fixedPoint.y() - bottomRight.y(); + } + delegated()->setTransform(buildTransform()); + } + else // resizing/resizing horizontally + { + + if (resizingBottomRight()) + { + static QSizeF incV = QSizeF(); + static QSizeF incH = QSizeF(); + + if (mMirrorX && mMirrorY) + mCurrentTool = ResizeTop; + else + mCurrentTool = ResizeBottom; + + incV = resizeDelegate(moveX, moveY); + mOriginalSize += incV; + + if (mMirrorX && mMirrorY) + mCurrentTool = ResizeLeft; + else + mCurrentTool = ResizeRight; + + move = QLineF(event->lastScenePos(), event->scenePos()); + moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); + moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); + + mFixedPoint = getFixedPointFromPos(); + + incH = resizeDelegate(moveX, moveY); + + mOriginalSize -= incV; + mOriginalSize += incH; + + mCurrentTool = ResizeBottomRight; + } + else + resizeDelegate(moveX, moveY); + } + event->accept(); +} + +QList UBGraphicsDelegateFrame::getLinkedFrames() +{ + QList linkedFrames; + QList sItems = mDelegate->delegated()->scene()->selectedItems(); + if (sItems.count()) + { + sItems.removeAll(delegated()); + + foreach(QGraphicsItem *item, sItems) + { + UBGraphicsItem *gitem = dynamic_cast(item); + if (gitem) + linkedFrames << gitem->Delegate()->frame(); + } + } + return linkedFrames; +} + +void UBGraphicsDelegateFrame::prepareFramesToMove(QList framesToMove) +{ + mLinkedFrames = framesToMove; + foreach (UBGraphicsDelegateFrame *frame, mLinkedFrames) + { + frame->prepareLinkedFrameToMove(); + } +} + +void UBGraphicsDelegateFrame::prepareLinkedFrameToMove() +{ + mDelegate->startUndoStep(); + + mStartingPoint = QPointF(0,0); + + initializeTransform(); + + mScaleX = 1; + mScaleY = 1; + mTranslateX = 0; + mTranslateY = 0; + mAngleOffset = 0; + + mInitialTransform = buildTransform(); + + mCurrentTool = Move; +} + +void UBGraphicsDelegateFrame::moveLinkedItems(QLineF movingVector, bool bLinked) +{ + if (bLinked) + { + mCurrentTool = Move; + + mTranslateX = movingVector.dx(); + mTranslateY = movingVector.dy(); + + delegated()->setTransform(buildTransform(), false); + } + else + { + foreach(UBGraphicsDelegateFrame* frame, mLinkedFrames) + { + frame->moveLinkedItems(movingVector, true); + } + } +} + +QTransform UBGraphicsDelegateFrame::buildTransform() +{ + QTransform tr; + QPointF center = delegated()->boundingRect().center(); + + // Translate + tr.translate(mTotalTranslateX + mTranslateX, mTotalTranslateY + mTranslateY); + + // Set angle + tr.translate(center.x() * mTotalScaleX * mScaleX, center.y() * mTotalScaleY * mScaleY); + tr.rotate(-mAngle); + tr.translate(-center.x() * mTotalScaleX * mScaleX, -center.y() * mTotalScaleY * mScaleY); + + // Scale + tr.scale(mTotalScaleX * mScaleX, mTotalScaleY * mScaleY); + return tr; +} + + +void UBGraphicsDelegateFrame::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + updateResizeCursors(); + + mDelegate->commitUndoStep(); + mTotalScaleX *= mScaleX; + mTotalScaleY *= mScaleY; + mTotalTranslateX += mTranslateX; + mTotalTranslateY += mTranslateY; + event->accept(); + + mCurrentTool = None; + + QGraphicsRectItem::mouseReleaseEvent(event); + + // Show the buttons + if(isResizing()){ + mResizing = false; + } +} + + +void UBGraphicsDelegateFrame::updateResizeCursors() +{ + QPixmap pix(":/images/cursors/resize.png"); + QTransform tr; + + tr.rotate(-mAngle); + QCursor resizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); + mLeftResizeGrip->setCursor(resizeCursor); + mRightResizeGrip->setCursor(resizeCursor); + + tr.rotate(-90); + resizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); + mBottomResizeGrip->setCursor(resizeCursor); + mTopResizeGrip->setCursor(resizeCursor); + + tr.rotate(-45); + resizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); + mBottomRightResizeGrip->setCursor(resizeCursor); +} + + +void UBGraphicsDelegateFrame::setVisible(bool visible) +{ + mVisible = visible; + if (mVisible) + setBrush(QBrush(UBSettings::paletteColor)); + else + setBrush(Qt::NoBrush); +} + + +void UBGraphicsDelegateFrame::positionHandles() +{ + QRectF itemRect = delegated()->boundingRect(); + + if (mDelegate->getToolBarItem() && mDelegate->getToolBarItem()->isVisibleOnBoard() + && mDelegate->getToolBarItem()->isShifting()) + { + QPointF graphicsItemPosition = itemRect.topLeft(); + itemRect.setTopLeft(graphicsItemPosition-QPointF(0,mDelegate->getToolBarItem()->boundingRect().height()* mDelegate->antiScaleRatio())); + } + + QTransform itemTransform = delegated()->sceneTransform(); + QPointF topLeft = itemTransform.map(itemRect.topLeft()); + QPointF topRight = itemTransform.map(itemRect.topRight()); + QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft()); + QPointF bottomRight = itemTransform.map(itemRect.bottomRight()); + QPointF center = itemTransform.map(itemRect.center()); + int rotateHeight = QLineF(topLeft, bottomLeft).length(); + + // Handle the mirroring + if(topLeft.x() > topRight.x()){ + QPointF topTmp = topRight; + QPointF bottomTmp = bottomRight; + topRight = topLeft; + topLeft = topTmp; + bottomRight = bottomLeft; + bottomLeft = bottomTmp; + } + + if(bottomLeft.y() > topLeft.y()){ + QPointF leftTmp = bottomLeft; + QPointF rightTmp = bottomRight; + bottomLeft = topLeft; + topLeft = leftTmp; + bottomRight = topRight; + topRight = rightTmp; + } + + QLineF topLine(topLeft, topRight); + qreal angle = topLine.angle(); + qreal width = topLine.length(); + + QLineF leftLine(topLeft, bottomLeft); + qreal height = leftLine.length(); + + int h = rotating()?rotateHeight:height; + + if (mVisible) + { + setRect(center.x() - mFrameWidth - width / 2, center.y() - mFrameWidth - h / 2, width + 2 * mFrameWidth, h + 2 * mFrameWidth); + } + else + { + setRect(center.x() - width / 2, center.y() - h / 2, width, h); + } + + resetTransform(); + translate(center.x(), center.y()); + rotate(-angle); + translate(-center.x(), -center.y()); + + mBottomRightResizeGripSvgItem->setParentItem(this); + mBottomResizeGripSvgItem->setParentItem(this); + mLeftResizeGripSvgItem->setParentItem(this); + mRightResizeGripSvgItem->setParentItem(this); + mTopResizeGripSvgItem->setParentItem(this); + mRotateButton->setParentItem(this); + + mBottomRightResizeGrip->setParentItem(this); + mBottomResizeGrip->setParentItem(this); + mLeftResizeGrip->setParentItem(this); + mRightResizeGrip->setParentItem(this); + mTopResizeGrip->setParentItem(this); + + QRectF brRect = mBottomRightResizeGripSvgItem->mapRectToParent(mBottomRightResizeGripSvgItem->boundingRect()); + QRectF bRect = mBottomResizeGripSvgItem->mapRectToParent(mBottomResizeGripSvgItem->boundingRect()); + QRectF lRect = mLeftResizeGripSvgItem->mapRectToParent(mLeftResizeGripSvgItem->boundingRect()); + QRectF rRect = mRightResizeGripSvgItem->mapRectToParent(mRightResizeGripSvgItem->boundingRect()); + QRectF trRect = mTopResizeGripSvgItem->mapRectToParent(mTopResizeGripSvgItem->boundingRect()); + + mBottomRightResizeGripSvgItem->setPos(rect().right() - brRect.width(), rect().bottom() - brRect.height()); + mBottomResizeGripSvgItem->setPos(rect().center().x() - bRect.width() / 2, rect().bottom() - bRect.height()); + + mLeftResizeGripSvgItem->setPos(rect().left(), rect().center().y() - lRect.height() / 2); + mRightResizeGripSvgItem->setPos(rect().right() - rRect.width(), rect().center().y() - rRect.height() / 2); + + mTopResizeGripSvgItem->setPos(rect().center().x() - trRect.width() / 2, rect().y()); + mRotateButton->setPos(rect().right() - mFrameWidth - 5, rect().top() + 5); + + mBottomRightResizeGrip->setRect(bottomRightResizeGripRect()); + mBottomResizeGrip->setRect(bottomResizeGripRect()); + mLeftResizeGrip->setRect(leftResizeGripRect()); + mRightResizeGrip->setRect(rightResizeGripRect()); + mTopResizeGrip->setRect(topResizeGripRect()); + + QVariant vLocked = delegated()->data(UBGraphicsItemData::ItemLocked); + bool isLocked = (vLocked.isValid() && vLocked.toBool()); + bool bShowHorizontalResizers = ResizingHorizontally == mOperationMode; + bool bShowVerticalResizers = ResizingHorizontally != mOperationMode; + bool bShowAllResizers = Resizing == mOperationMode || Scaling == mOperationMode ; + + mBottomRightResizeGripSvgItem->setVisible(!isLocked && bShowAllResizers); + mBottomResizeGripSvgItem->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); + mLeftResizeGripSvgItem->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); + mRightResizeGripSvgItem->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); + mTopResizeGripSvgItem->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); + mRotateButton->setVisible(mDelegate->canRotate() && !isLocked); + + mBottomRightResizeGrip->setVisible(!isLocked && bShowAllResizers); + mBottomResizeGrip->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); + mLeftResizeGrip->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); + mRightResizeGrip->setVisible(!isLocked && (bShowHorizontalResizers || bShowAllResizers)); + mTopResizeGrip->setVisible(!isLocked && (bShowVerticalResizers || bShowAllResizers)); + + if (isLocked) + { + QColor baseColor = UBSettings::paletteColor; + baseColor.setAlphaF(baseColor.alphaF() / 3); + setBrush(QBrush(baseColor)); + } + else + { + setBrush(QBrush(UBSettings::paletteColor)); + } + + //make frame interact like delegated item when selected. Maybe should be deleted if selection logic will change + setZValue(delegated()->zValue()); +} + + +QGraphicsItem* UBGraphicsDelegateFrame::delegated() +{ + return mDelegate->delegated(); +} + +UBGraphicsDelegateFrame::FrameTool UBGraphicsDelegateFrame::toolFromPos(QPointF pos) +{ + if(mDelegate->isLocked()) + return None; + else if (bottomRightResizeGripRect().contains(pos) && ResizingHorizontally != mOperationMode) + return ResizeBottomRight; + else if (bottomResizeGripRect().contains(pos) && ResizingHorizontally != mOperationMode){ + if(mMirrorY){ + return ResizeTop; + }else{ + return ResizeBottom; + } + } + else if (leftResizeGripRect().contains(pos)){ + if(mMirrorX){ + return ResizeRight; + }else{ + return ResizeLeft; + } + return ResizeLeft; + } + else if (rightResizeGripRect().contains(pos)){ + if(mMirrorX){ + return ResizeLeft; + }else{ + return ResizeRight; + } + } + else if (topResizeGripRect().contains(pos) && ResizingHorizontally != mOperationMode){ + if(mMirrorY){ + return ResizeBottom; + }else{ + return ResizeTop; + } + } + else if (rotateButtonBounds().contains(pos) && mDelegate && mDelegate->canRotate()) + return Rotate; + else + return Move; +} + + +QRectF UBGraphicsDelegateFrame::bottomRightResizeGripRect() const +{ + return QRectF(rect().right() - mFrameWidth, rect().bottom() - mFrameWidth, mFrameWidth, mFrameWidth); +} + + +QRectF UBGraphicsDelegateFrame::bottomResizeGripRect() const +{ + return QRectF(rect().center().x() - mFrameWidth / 2, rect().bottom() - mFrameWidth, mFrameWidth, mFrameWidth); +} + + +QRectF UBGraphicsDelegateFrame::leftResizeGripRect() const +{ + return QRectF(rect().left(), rect().center().y() - mFrameWidth / 2, mFrameWidth, mFrameWidth); +} + + +QRectF UBGraphicsDelegateFrame::rightResizeGripRect() const +{ + return QRectF(rect().right() - mFrameWidth, rect().center().y() - mFrameWidth / 2, mFrameWidth, mFrameWidth); +} + + +QRectF UBGraphicsDelegateFrame::topResizeGripRect() const +{ + return QRectF(rect().center().x() - mFrameWidth / 2, rect().top(), mFrameWidth, mFrameWidth); +} + + +QRectF UBGraphicsDelegateFrame::rotateButtonBounds() const +{ + return QRectF(rect().right()- mFrameWidth, rect().top(), mFrameWidth, mFrameWidth); +} + +void UBGraphicsDelegateFrame::refreshGeometry() +{ + // Here we want to have the left on the left, the right on the right, the top on the top and the bottom on the bottom! + QRectF itemRect = delegated()->boundingRect(); + QTransform itemTransform = delegated()->sceneTransform(); + QPointF topLeft = itemTransform.map(itemRect.topLeft()); + QPointF topRight = itemTransform.map(itemRect.topRight()); + QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft()); + + QLineF topLine(topLeft, topRight); + qreal width = topLine.length(); + QLineF leftLine(topLeft, bottomLeft); + qreal height = leftLine.length(); + setRect(topRight.x() - mFrameWidth, topLeft.y() - mFrameWidth, width + 2*mFrameWidth, height + 2*mFrameWidth); +} diff --git a/src/domain/UBGraphicsItemUndoCommand.cpp b/src/domain/UBGraphicsItemUndoCommand.cpp index 77d09f5d..1b70b76c 100644 --- a/src/domain/UBGraphicsItemUndoCommand.cpp +++ b/src/domain/UBGraphicsItemUndoCommand.cpp @@ -19,221 +19,221 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBGraphicsItemUndoCommand.h" - -#include - -#include "UBGraphicsScene.h" - -#include "core/UBApplication.h" - -#include "board/UBBoardController.h" - -#include "core/memcheck.h" -#include "domain/UBGraphicsGroupContainerItem.h" -#include "domain/UBGraphicsPolygonItem.h" - -UBGraphicsItemUndoCommand::UBGraphicsItemUndoCommand(UBGraphicsScene* pScene, const QSet& pRemovedItems, - const QSet& pAddedItems, const GroupDataTable &groupsMap) - : mScene(pScene) - , mRemovedItems(pRemovedItems - pAddedItems) - , mAddedItems(pAddedItems - pRemovedItems) - , mExcludedFromGroup(groupsMap) -{ - mFirstRedo = true; - - QSetIterator itAdded(mAddedItems); - while (itAdded.hasNext()) - { - UBApplication::boardController->freezeW3CWidget(itAdded.next(), true); - } - - QSetIterator itRemoved(mRemovedItems); - while (itRemoved.hasNext()) - { - UBApplication::boardController->freezeW3CWidget(itRemoved.next(), false); - } -} - -UBGraphicsItemUndoCommand::UBGraphicsItemUndoCommand(UBGraphicsScene* pScene, QGraphicsItem* pRemovedItem, - QGraphicsItem* pAddedItem) : - mScene(pScene) -{ - - if (pRemovedItem) - { - mRemovedItems.insert(pRemovedItem); - } - - if (pAddedItem) - { - mAddedItems.insert(pAddedItem); - } - - mFirstRedo = true; - -} - -UBGraphicsItemUndoCommand::~UBGraphicsItemUndoCommand() -{ - //NOOP -} - -void UBGraphicsItemUndoCommand::undo() -{ - if (!mScene){ - return; - } - - QSetIterator itAdded(mAddedItems); - while (itAdded.hasNext()) - { - QGraphicsItem* item = itAdded.next(); - - UBApplication::boardController->freezeW3CWidget(item, true); - item->setSelected(false); - mScene->removeItem(item); - } - - QSetIterator itRemoved(mRemovedItems); - while (itRemoved.hasNext()) - { - QGraphicsItem* item = itRemoved.next(); - if (item) - { - if (UBItemLayerType::FixedBackground == item->data(UBGraphicsItemData::ItemLayerType)) - mScene->setAsBackgroundObject(item); - else - mScene->addItem(item); - - if (UBGraphicsPolygonItem::Type == item->type()) - { - UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast(item); - if (polygonItem) - { - mScene->removeItem(polygonItem); - mScene->removeItemFromDeletion(polygonItem); - polygonItem->strokesGroup()->addToGroup(polygonItem); - } - } - - UBApplication::boardController->freezeW3CWidget(item, false); - } - } - - QMapIterator curMapElement(mExcludedFromGroup); - UBGraphicsGroupContainerItem *nextGroup = NULL; - UBGraphicsGroupContainerItem *previousGroupItem = NULL; - bool groupChanged = false; - - while (curMapElement.hasNext()) { - curMapElement.next(); - - groupChanged = previousGroupItem != curMapElement.key(); - //trying to find the group on the scene; - if (!nextGroup || groupChanged) { - UBGraphicsGroupContainerItem *groupCandidate = curMapElement.key(); - if (groupCandidate) { - nextGroup = groupCandidate; - if(!mScene->items().contains(nextGroup)) { - mScene->addItem(nextGroup); - } - nextGroup->setVisible(true); - } - } - - QGraphicsItem *groupedItem = mScene->itemForUuid(curMapElement.value()); - if (groupedItem) { - nextGroup->addToGroup(groupedItem); - } - - previousGroupItem = curMapElement.key(); - UBGraphicsItem::Delegate(nextGroup)->update(); - } - - // force refresh, QT is a bit lazy and take a lot of time (nb item ^2 ?) to trigger repaint - mScene->update(mScene->sceneRect()); - -} - -void UBGraphicsItemUndoCommand::redo() -{ - // the Undo framework calls a redo while appending the undo command. - // as we have already plotted the elements, we do not want to do it twice - if (!mFirstRedo) - { - if (!mScene){ - return; - } - - QMapIterator curMapElement(mExcludedFromGroup); - UBGraphicsGroupContainerItem *nextGroup = NULL; - UBGraphicsGroupContainerItem *previousGroupItem = NULL; - bool groupChanged = false; - - while (curMapElement.hasNext()) { - curMapElement.next(); - - groupChanged = previousGroupItem != curMapElement.key(); - //trying to find the group on the scene; - if (!nextGroup || groupChanged) { - UBGraphicsGroupContainerItem *groupCandidate = curMapElement.key(); - if (groupCandidate) { - nextGroup = groupCandidate; - } - } - QGraphicsItem *groupedItem = mScene->itemForUuid(curMapElement.value()); - if (groupedItem) { - if (nextGroup->childItems().count() == 1) { - nextGroup->destroy(false); - break; - } - nextGroup->removeFromGroup(groupedItem); - } - - previousGroupItem = curMapElement.key(); - UBGraphicsItem::Delegate(nextGroup)->update(); - } - - QSetIterator itRemoved(mRemovedItems); - while (itRemoved.hasNext()) - { - QGraphicsItem* item = itRemoved.next(); - item->setSelected(false); - mScene->removeItem(item); - UBApplication::boardController->freezeW3CWidget(item, true); - } - - QSetIterator itAdded(mAddedItems); - while (itAdded.hasNext()) - { - QGraphicsItem* item = itAdded.next(); - if (item) - { - UBApplication::boardController->freezeW3CWidget(item, false); - - if (UBItemLayerType::FixedBackground == item->data(UBGraphicsItemData::ItemLayerType)) - mScene->setAsBackgroundObject(item); - else - mScene->addItem(item); - - UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast(item); - if (polygonItem) - { - mScene->removeItem(polygonItem); - mScene->removeItemFromDeletion(polygonItem); - polygonItem->strokesGroup()->addToGroup(polygonItem); - } - } - } - - // force refresh, QT is a bit lazy and take a lot of time (nb item ^2) to trigger repaint - mScene->update(mScene->sceneRect()); - } - else - { - mFirstRedo = false; - } -} + + +#include "UBGraphicsItemUndoCommand.h" + +#include + +#include "UBGraphicsScene.h" + +#include "core/UBApplication.h" + +#include "board/UBBoardController.h" + +#include "core/memcheck.h" +#include "domain/UBGraphicsGroupContainerItem.h" +#include "domain/UBGraphicsPolygonItem.h" + +UBGraphicsItemUndoCommand::UBGraphicsItemUndoCommand(UBGraphicsScene* pScene, const QSet& pRemovedItems, + const QSet& pAddedItems, const GroupDataTable &groupsMap) + : mScene(pScene) + , mRemovedItems(pRemovedItems - pAddedItems) + , mAddedItems(pAddedItems - pRemovedItems) + , mExcludedFromGroup(groupsMap) +{ + mFirstRedo = true; + + QSetIterator itAdded(mAddedItems); + while (itAdded.hasNext()) + { + UBApplication::boardController->freezeW3CWidget(itAdded.next(), true); + } + + QSetIterator itRemoved(mRemovedItems); + while (itRemoved.hasNext()) + { + UBApplication::boardController->freezeW3CWidget(itRemoved.next(), false); + } +} + +UBGraphicsItemUndoCommand::UBGraphicsItemUndoCommand(UBGraphicsScene* pScene, QGraphicsItem* pRemovedItem, + QGraphicsItem* pAddedItem) : + mScene(pScene) +{ + + if (pRemovedItem) + { + mRemovedItems.insert(pRemovedItem); + } + + if (pAddedItem) + { + mAddedItems.insert(pAddedItem); + } + + mFirstRedo = true; + +} + +UBGraphicsItemUndoCommand::~UBGraphicsItemUndoCommand() +{ + //NOOP +} + +void UBGraphicsItemUndoCommand::undo() +{ + if (!mScene){ + return; + } + + QSetIterator itAdded(mAddedItems); + while (itAdded.hasNext()) + { + QGraphicsItem* item = itAdded.next(); + + UBApplication::boardController->freezeW3CWidget(item, true); + item->setSelected(false); + mScene->removeItem(item); + } + + QSetIterator itRemoved(mRemovedItems); + while (itRemoved.hasNext()) + { + QGraphicsItem* item = itRemoved.next(); + if (item) + { + if (UBItemLayerType::FixedBackground == item->data(UBGraphicsItemData::ItemLayerType)) + mScene->setAsBackgroundObject(item); + else + mScene->addItem(item); + + if (UBGraphicsPolygonItem::Type == item->type()) + { + UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast(item); + if (polygonItem) + { + mScene->removeItem(polygonItem); + mScene->removeItemFromDeletion(polygonItem); + polygonItem->strokesGroup()->addToGroup(polygonItem); + } + } + + UBApplication::boardController->freezeW3CWidget(item, false); + } + } + + QMapIterator curMapElement(mExcludedFromGroup); + UBGraphicsGroupContainerItem *nextGroup = NULL; + UBGraphicsGroupContainerItem *previousGroupItem = NULL; + bool groupChanged = false; + + while (curMapElement.hasNext()) { + curMapElement.next(); + + groupChanged = previousGroupItem != curMapElement.key(); + //trying to find the group on the scene; + if (!nextGroup || groupChanged) { + UBGraphicsGroupContainerItem *groupCandidate = curMapElement.key(); + if (groupCandidate) { + nextGroup = groupCandidate; + if(!mScene->items().contains(nextGroup)) { + mScene->addItem(nextGroup); + } + nextGroup->setVisible(true); + } + } + + QGraphicsItem *groupedItem = mScene->itemForUuid(curMapElement.value()); + if (groupedItem) { + nextGroup->addToGroup(groupedItem); + } + + previousGroupItem = curMapElement.key(); + UBGraphicsItem::Delegate(nextGroup)->update(); + } + + // force refresh, QT is a bit lazy and take a lot of time (nb item ^2 ?) to trigger repaint + mScene->update(mScene->sceneRect()); + +} + +void UBGraphicsItemUndoCommand::redo() +{ + // the Undo framework calls a redo while appending the undo command. + // as we have already plotted the elements, we do not want to do it twice + if (!mFirstRedo) + { + if (!mScene){ + return; + } + + QMapIterator curMapElement(mExcludedFromGroup); + UBGraphicsGroupContainerItem *nextGroup = NULL; + UBGraphicsGroupContainerItem *previousGroupItem = NULL; + bool groupChanged = false; + + while (curMapElement.hasNext()) { + curMapElement.next(); + + groupChanged = previousGroupItem != curMapElement.key(); + //trying to find the group on the scene; + if (!nextGroup || groupChanged) { + UBGraphicsGroupContainerItem *groupCandidate = curMapElement.key(); + if (groupCandidate) { + nextGroup = groupCandidate; + } + } + QGraphicsItem *groupedItem = mScene->itemForUuid(curMapElement.value()); + if (groupedItem) { + if (nextGroup->childItems().count() == 1) { + nextGroup->destroy(false); + break; + } + nextGroup->removeFromGroup(groupedItem); + } + + previousGroupItem = curMapElement.key(); + UBGraphicsItem::Delegate(nextGroup)->update(); + } + + QSetIterator itRemoved(mRemovedItems); + while (itRemoved.hasNext()) + { + QGraphicsItem* item = itRemoved.next(); + item->setSelected(false); + mScene->removeItem(item); + UBApplication::boardController->freezeW3CWidget(item, true); + } + + QSetIterator itAdded(mAddedItems); + while (itAdded.hasNext()) + { + QGraphicsItem* item = itAdded.next(); + if (item) + { + UBApplication::boardController->freezeW3CWidget(item, false); + + if (UBItemLayerType::FixedBackground == item->data(UBGraphicsItemData::ItemLayerType)) + mScene->setAsBackgroundObject(item); + else + mScene->addItem(item); + + UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast(item); + if (polygonItem) + { + mScene->removeItem(polygonItem); + mScene->removeItemFromDeletion(polygonItem); + polygonItem->strokesGroup()->addToGroup(polygonItem); + } + } + } + + // force refresh, QT is a bit lazy and take a lot of time (nb item ^2) to trigger repaint + mScene->update(mScene->sceneRect()); + } + else + { + mFirstRedo = false; + } +} diff --git a/src/domain/UBGraphicsVideoItemDelegate.h b/src/domain/UBGraphicsVideoItemDelegate.h index 25416a16..29ffd4f5 100644 --- a/src/domain/UBGraphicsVideoItemDelegate.h +++ b/src/domain/UBGraphicsVideoItemDelegate.h @@ -19,106 +19,106 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBGRAPHICSVIDEOITEMDELEGATE_H_ -#define UBGRAPHICSVIDEOITEMDELEGATE_H_ - -#include -#include - -#include "core/UB.h" -#include "UBGraphicsItemDelegate.h" - -class QGraphicsSceneMouseEvent; -class QGraphicsItem; -class UBGraphicsVideoItem; - -class DelegateVideoControl: public QGraphicsRectItem -{ - public: - - DelegateVideoControl(UBGraphicsVideoItem* pDelegated, QGraphicsItem * parent = 0); - - virtual ~DelegateVideoControl() - { - // NOOP - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - - QPainterPath shape() const; - - void setAntiScale(qreal antiScale){ mAntiScale = antiScale; } - - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - - void updateTicker(qint64 time); - void totalTimeChanged( qint64 newTotalTime); - - protected: - - - void seekToMousePos(QPointF mousePos); - - UBGraphicsVideoItem* mDelegate; - bool mDisplayCurrentTime; - - qreal mAntiScale; - qint64 mCurrentTimeInMs; - qint64 mTotalTimeInMs; - - private: - int mStartWidth; - QRectF mBalloon; -}; - - -class UBGraphicsVideoItemDelegate : public UBGraphicsItemDelegate -{ - Q_OBJECT - - public: - UBGraphicsVideoItemDelegate(UBGraphicsVideoItem* pDelegated, Phonon::MediaObject* pMedia, QObject * parent = 0); - virtual ~UBGraphicsVideoItemDelegate(); - - virtual void positionHandles(); - - public slots: - - void toggleMute(); - void updateTicker(qint64 time); - - protected slots: - - virtual void remove(bool canUndo = true); - - void togglePlayPause(); - - void mediaStateChanged ( Phonon::State newstate, Phonon::State oldstate ); - - void updatePlayPauseState(); - - void totalTimeChanged( qint64 newTotalTime); - - protected: - - virtual void buildButtons(); - - private: - - UBGraphicsVideoItem* delegated(); - - DelegateButton* mPlayPauseButton; - DelegateButton* mStopButton; - DelegateButton* mMuteButton; - DelegateVideoControl *mVideoControl; - - Phonon::MediaObject* mMedia; -}; - - -#endif /* UBGRAPHICSVIDEOITEMDELEGATE_H_ */ + + +#ifndef UBGRAPHICSVIDEOITEMDELEGATE_H_ +#define UBGRAPHICSVIDEOITEMDELEGATE_H_ + +#include +#include + +#include "core/UB.h" +#include "UBGraphicsItemDelegate.h" + +class QGraphicsSceneMouseEvent; +class QGraphicsItem; +class UBGraphicsVideoItem; + +class DelegateVideoControl: public QGraphicsRectItem +{ + public: + + DelegateVideoControl(UBGraphicsVideoItem* pDelegated, QGraphicsItem * parent = 0); + + virtual ~DelegateVideoControl() + { + // NOOP + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget); + + QPainterPath shape() const; + + void setAntiScale(qreal antiScale){ mAntiScale = antiScale; } + + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + void updateTicker(qint64 time); + void totalTimeChanged( qint64 newTotalTime); + + protected: + + + void seekToMousePos(QPointF mousePos); + + UBGraphicsVideoItem* mDelegate; + bool mDisplayCurrentTime; + + qreal mAntiScale; + qint64 mCurrentTimeInMs; + qint64 mTotalTimeInMs; + + private: + int mStartWidth; + QRectF mBalloon; +}; + + +class UBGraphicsVideoItemDelegate : public UBGraphicsItemDelegate +{ + Q_OBJECT + + public: + UBGraphicsVideoItemDelegate(UBGraphicsVideoItem* pDelegated, Phonon::MediaObject* pMedia, QObject * parent = 0); + virtual ~UBGraphicsVideoItemDelegate(); + + virtual void positionHandles(); + + public slots: + + void toggleMute(); + void updateTicker(qint64 time); + + protected slots: + + virtual void remove(bool canUndo = true); + + void togglePlayPause(); + + void mediaStateChanged ( Phonon::State newstate, Phonon::State oldstate ); + + void updatePlayPauseState(); + + void totalTimeChanged( qint64 newTotalTime); + + protected: + + virtual void buildButtons(); + + private: + + UBGraphicsVideoItem* delegated(); + + DelegateButton* mPlayPauseButton; + DelegateButton* mStopButton; + DelegateButton* mMuteButton; + DelegateVideoControl *mVideoControl; + + Phonon::MediaObject* mMedia; +}; + + +#endif /* UBGRAPHICSVIDEOITEMDELEGATE_H_ */ diff --git a/src/frameworks/UBGeometryUtils.cpp b/src/frameworks/UBGeometryUtils.cpp index cf78cf1e..d1cc1fe2 100644 --- a/src/frameworks/UBGeometryUtils.cpp +++ b/src/frameworks/UBGeometryUtils.cpp @@ -19,221 +19,221 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBGeometryUtils.h" - -#include "core/memcheck.h" - -const double PI = 4.0 * atan(1.0); -const int UBGeometryUtils::centimeterGraduationHeight = 15; -const int UBGeometryUtils::halfCentimeterGraduationHeight = 10; -const int UBGeometryUtils::millimeterGraduationHeight = 5; -const int UBGeometryUtils::millimetersPerCentimeter = 10; -const int UBGeometryUtils::millimetersPerHalfCentimeter = 5; -const float UBGeometryUtils::inchSize = 25.4f; - -UBGeometryUtils::UBGeometryUtils() -{ - // NOOP -} - -UBGeometryUtils::~UBGeometryUtils() -{ - // NOOP -} - -QPolygonF UBGeometryUtils::lineToPolygon(const QLineF& pLine, const qreal& pWidth) -{ - qreal x1 = pLine.x1(); - qreal y1 = pLine.y1(); - - qreal x2 = pLine.x2(); - qreal y2 = pLine.y2(); - - qreal alpha = (90.0 - pLine.angle()) * PI / 180.0; - qreal hypothenuse = pWidth / 2; - - // TODO UB 4.x PERF cache sin/cos table - qreal opposite = sin(alpha) * hypothenuse; - qreal adjacent = cos(alpha) * hypothenuse; - - QPointF p1a(x1 - adjacent, y1 - opposite); - QPointF p1b(x1 + adjacent, y1 + opposite); - - QPointF p2a(x2 - adjacent, y2 - opposite); - QPointF p2b(x2 + adjacent, y2 + opposite); - - QPainterPath painterPath; - - painterPath.moveTo(p1a); - painterPath.lineTo(p2a); - - painterPath.arcTo(x2 - hypothenuse, y2 - hypothenuse, pWidth, pWidth, (90.0 + pLine.angle()), -180.0); - - //painterPath.lineTo(p2b); - painterPath.lineTo(p1b); - - painterPath.arcTo(x1 - hypothenuse, y1 - hypothenuse, pWidth, pWidth, -1 * (90.0 - pLine.angle()), -180.0); - - painterPath.closeSubpath(); - - return painterPath.toFillPolygon(); -} - -QPolygonF UBGeometryUtils::lineToPolygon(const QPointF& pStart, const QPointF& pEnd, - const qreal& pStartWidth, const qreal& pEndWidth) -{ - - qreal x1 = pStart.x(); - qreal y1 = pStart.y(); - - qreal x2 = pEnd.x(); - qreal y2 = pEnd.y(); - - QLineF line(pStart, pEnd); - - qreal alpha = (90.0 - line.angle()) * PI / 180.0; - qreal hypothenuseStart = pStartWidth / 2; - - qreal hypothenuseEnd = pEndWidth / 2; - - qreal sinAlpha = sin(alpha); - qreal cosAlpha = cos(alpha); - - // TODO UB 4.x PERF cache sin/cos table - qreal oppositeStart = sinAlpha * hypothenuseStart; - qreal adjacentStart = cosAlpha * hypothenuseStart; - - QPointF p1a(x1 - adjacentStart, y1 - oppositeStart); - QPointF p1b(x1 + adjacentStart, y1 + oppositeStart); - - qreal oppositeEnd = sinAlpha * hypothenuseEnd; - qreal adjacentEnd = cosAlpha * hypothenuseEnd; - - QPointF p2a(x2 - adjacentEnd, y2 - oppositeEnd); - - QPainterPath painterPath; - - painterPath.moveTo(p1a); - painterPath.lineTo(p2a); - - painterPath.arcTo(x2 - hypothenuseEnd, y2 - hypothenuseEnd, pEndWidth, pEndWidth, (90.0 + line.angle()), -180.0); - - painterPath.lineTo(p1b); - - painterPath.arcTo(x1 - hypothenuseStart, y1 - hypothenuseStart, pStartWidth, pStartWidth, -1 * (90.0 - line.angle()), -180.0); - - painterPath.closeSubpath(); - - return painterPath.toFillPolygon(); -} - -QPolygonF UBGeometryUtils::arcToPolygon(const QLineF& startRadius, qreal spanAngleInDegrees, qreal width) -{ - qreal startAngleInDegrees = - startRadius.angle(); - if (startAngleInDegrees > 180) - startAngleInDegrees -= 360; - else if (startAngleInDegrees < -180) - startAngleInDegrees += 360; - - qreal radiusLength = startRadius.length(); - qreal angle = 2 * asin(width / (2 * radiusLength)) * 180 / PI; - bool overlap = abs(spanAngleInDegrees) > 360 - angle; - if (overlap) - spanAngleInDegrees = spanAngleInDegrees < 0 ? -360 : 360; - - qreal endAngleInDegrees = startAngleInDegrees + spanAngleInDegrees; - - qreal innerRadius = radiusLength - width / 2; - QRectF innerSquare( - startRadius.p1().x() - innerRadius, - startRadius.p1().y() - innerRadius, - 2 * innerRadius, - 2 * innerRadius); - qreal outerRadius = radiusLength + width / 2; - QRectF outerSquare( - startRadius.p1().x() - outerRadius, - startRadius.p1().y() - outerRadius, - 2 * outerRadius, - 2 * outerRadius); - QRectF startSquare( - startRadius.p2().x() - width / 2, - startRadius.p2().y() - width / 2, - width, - width); - QRectF endSquare( - startRadius.p1().x() + radiusLength * cos(endAngleInDegrees * PI / 180.0) - width / 2, - startRadius.p1().y() + radiusLength * sin(endAngleInDegrees * PI / 180.0) - width / 2, - width, - width); - - QPainterPath painterPath( - QPointF( - startRadius.p1().x() + innerRadius * cos(startAngleInDegrees * PI / 180.0), - startRadius.p1().y() + innerRadius * sin(startAngleInDegrees * PI / 180.0))); - startAngleInDegrees = - startAngleInDegrees; - endAngleInDegrees = - endAngleInDegrees; - spanAngleInDegrees = - spanAngleInDegrees; - - if (overlap) - { - painterPath.addEllipse(outerSquare); - QPainterPath innerPainterPath; - innerPainterPath.addEllipse(innerSquare); - painterPath = painterPath.subtracted(innerPainterPath); - } - else - { - painterPath.arcTo(innerSquare, startAngleInDegrees, spanAngleInDegrees); - painterPath.arcTo(endSquare, 180.0 + endAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); - painterPath.arcTo(outerSquare, endAngleInDegrees, - spanAngleInDegrees); - painterPath.arcTo(startSquare, startAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); - painterPath.closeSubpath(); - } - - return painterPath.toFillPolygon(); -} - -QPointF UBGeometryUtils::pointConstrainedInRect(QPointF point, QRectF rect) -{ - return QPointF(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); -} - - -QPoint UBGeometryUtils::pointConstrainedInRect(QPoint point, QRect rect) -{ - return QPoint(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); -} - - -QRectF UBGeometryUtils::lineToInnerRect(const QLineF& pLine, const qreal& pWidth) -{ - qreal centerX = (pLine.x1() + pLine.x2()) / 2; - qreal centerY = (pLine.y1() + pLine.y2()) / 2; - - // Please put a fucking comment here - qreal side = sqrt((pWidth * pWidth) / 2); - qreal halfSide = side / 2; - - return QRectF(centerX - halfSide, centerY - halfSide, side, side); -} - - -void UBGeometryUtils::crashPointList(QVector &points) -{ - // QVector result(points); - int position = 1; - - while(position < points.size()) - { - if (points.at(position) == points.at(position - 1)) - { - points.remove(position); - } - else - { - ++position; - } - } -} + + +#include "UBGeometryUtils.h" + +#include "core/memcheck.h" + +const double PI = 4.0 * atan(1.0); +const int UBGeometryUtils::centimeterGraduationHeight = 15; +const int UBGeometryUtils::halfCentimeterGraduationHeight = 10; +const int UBGeometryUtils::millimeterGraduationHeight = 5; +const int UBGeometryUtils::millimetersPerCentimeter = 10; +const int UBGeometryUtils::millimetersPerHalfCentimeter = 5; +const float UBGeometryUtils::inchSize = 25.4f; + +UBGeometryUtils::UBGeometryUtils() +{ + // NOOP +} + +UBGeometryUtils::~UBGeometryUtils() +{ + // NOOP +} + +QPolygonF UBGeometryUtils::lineToPolygon(const QLineF& pLine, const qreal& pWidth) +{ + qreal x1 = pLine.x1(); + qreal y1 = pLine.y1(); + + qreal x2 = pLine.x2(); + qreal y2 = pLine.y2(); + + qreal alpha = (90.0 - pLine.angle()) * PI / 180.0; + qreal hypothenuse = pWidth / 2; + + // TODO UB 4.x PERF cache sin/cos table + qreal opposite = sin(alpha) * hypothenuse; + qreal adjacent = cos(alpha) * hypothenuse; + + QPointF p1a(x1 - adjacent, y1 - opposite); + QPointF p1b(x1 + adjacent, y1 + opposite); + + QPointF p2a(x2 - adjacent, y2 - opposite); + QPointF p2b(x2 + adjacent, y2 + opposite); + + QPainterPath painterPath; + + painterPath.moveTo(p1a); + painterPath.lineTo(p2a); + + painterPath.arcTo(x2 - hypothenuse, y2 - hypothenuse, pWidth, pWidth, (90.0 + pLine.angle()), -180.0); + + //painterPath.lineTo(p2b); + painterPath.lineTo(p1b); + + painterPath.arcTo(x1 - hypothenuse, y1 - hypothenuse, pWidth, pWidth, -1 * (90.0 - pLine.angle()), -180.0); + + painterPath.closeSubpath(); + + return painterPath.toFillPolygon(); +} + +QPolygonF UBGeometryUtils::lineToPolygon(const QPointF& pStart, const QPointF& pEnd, + const qreal& pStartWidth, const qreal& pEndWidth) +{ + + qreal x1 = pStart.x(); + qreal y1 = pStart.y(); + + qreal x2 = pEnd.x(); + qreal y2 = pEnd.y(); + + QLineF line(pStart, pEnd); + + qreal alpha = (90.0 - line.angle()) * PI / 180.0; + qreal hypothenuseStart = pStartWidth / 2; + + qreal hypothenuseEnd = pEndWidth / 2; + + qreal sinAlpha = sin(alpha); + qreal cosAlpha = cos(alpha); + + // TODO UB 4.x PERF cache sin/cos table + qreal oppositeStart = sinAlpha * hypothenuseStart; + qreal adjacentStart = cosAlpha * hypothenuseStart; + + QPointF p1a(x1 - adjacentStart, y1 - oppositeStart); + QPointF p1b(x1 + adjacentStart, y1 + oppositeStart); + + qreal oppositeEnd = sinAlpha * hypothenuseEnd; + qreal adjacentEnd = cosAlpha * hypothenuseEnd; + + QPointF p2a(x2 - adjacentEnd, y2 - oppositeEnd); + + QPainterPath painterPath; + + painterPath.moveTo(p1a); + painterPath.lineTo(p2a); + + painterPath.arcTo(x2 - hypothenuseEnd, y2 - hypothenuseEnd, pEndWidth, pEndWidth, (90.0 + line.angle()), -180.0); + + painterPath.lineTo(p1b); + + painterPath.arcTo(x1 - hypothenuseStart, y1 - hypothenuseStart, pStartWidth, pStartWidth, -1 * (90.0 - line.angle()), -180.0); + + painterPath.closeSubpath(); + + return painterPath.toFillPolygon(); +} + +QPolygonF UBGeometryUtils::arcToPolygon(const QLineF& startRadius, qreal spanAngleInDegrees, qreal width) +{ + qreal startAngleInDegrees = - startRadius.angle(); + if (startAngleInDegrees > 180) + startAngleInDegrees -= 360; + else if (startAngleInDegrees < -180) + startAngleInDegrees += 360; + + qreal radiusLength = startRadius.length(); + qreal angle = 2 * asin(width / (2 * radiusLength)) * 180 / PI; + bool overlap = abs(spanAngleInDegrees) > 360 - angle; + if (overlap) + spanAngleInDegrees = spanAngleInDegrees < 0 ? -360 : 360; + + qreal endAngleInDegrees = startAngleInDegrees + spanAngleInDegrees; + + qreal innerRadius = radiusLength - width / 2; + QRectF innerSquare( + startRadius.p1().x() - innerRadius, + startRadius.p1().y() - innerRadius, + 2 * innerRadius, + 2 * innerRadius); + qreal outerRadius = radiusLength + width / 2; + QRectF outerSquare( + startRadius.p1().x() - outerRadius, + startRadius.p1().y() - outerRadius, + 2 * outerRadius, + 2 * outerRadius); + QRectF startSquare( + startRadius.p2().x() - width / 2, + startRadius.p2().y() - width / 2, + width, + width); + QRectF endSquare( + startRadius.p1().x() + radiusLength * cos(endAngleInDegrees * PI / 180.0) - width / 2, + startRadius.p1().y() + radiusLength * sin(endAngleInDegrees * PI / 180.0) - width / 2, + width, + width); + + QPainterPath painterPath( + QPointF( + startRadius.p1().x() + innerRadius * cos(startAngleInDegrees * PI / 180.0), + startRadius.p1().y() + innerRadius * sin(startAngleInDegrees * PI / 180.0))); + startAngleInDegrees = - startAngleInDegrees; + endAngleInDegrees = - endAngleInDegrees; + spanAngleInDegrees = - spanAngleInDegrees; + + if (overlap) + { + painterPath.addEllipse(outerSquare); + QPainterPath innerPainterPath; + innerPainterPath.addEllipse(innerSquare); + painterPath = painterPath.subtracted(innerPainterPath); + } + else + { + painterPath.arcTo(innerSquare, startAngleInDegrees, spanAngleInDegrees); + painterPath.arcTo(endSquare, 180.0 + endAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); + painterPath.arcTo(outerSquare, endAngleInDegrees, - spanAngleInDegrees); + painterPath.arcTo(startSquare, startAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); + painterPath.closeSubpath(); + } + + return painterPath.toFillPolygon(); +} + +QPointF UBGeometryUtils::pointConstrainedInRect(QPointF point, QRectF rect) +{ + return QPointF(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); +} + + +QPoint UBGeometryUtils::pointConstrainedInRect(QPoint point, QRect rect) +{ + return QPoint(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); +} + + +QRectF UBGeometryUtils::lineToInnerRect(const QLineF& pLine, const qreal& pWidth) +{ + qreal centerX = (pLine.x1() + pLine.x2()) / 2; + qreal centerY = (pLine.y1() + pLine.y2()) / 2; + + // Please put a fucking comment here + qreal side = sqrt((pWidth * pWidth) / 2); + qreal halfSide = side / 2; + + return QRectF(centerX - halfSide, centerY - halfSide, side, side); +} + + +void UBGeometryUtils::crashPointList(QVector &points) +{ + // QVector result(points); + int position = 1; + + while(position < points.size()) + { + if (points.at(position) == points.at(position - 1)) + { + points.remove(position); + } + else + { + ++position; + } + } +} diff --git a/src/frameworks/UBGeometryUtils.h b/src/frameworks/UBGeometryUtils.h index 49796bee..383b7547 100644 --- a/src/frameworks/UBGeometryUtils.h +++ b/src/frameworks/UBGeometryUtils.h @@ -19,39 +19,39 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBGEOMETRYUTILS_H_ -#define UBGEOMETRYUTILS_H_ - -#include - -class UBGeometryUtils -{ - private: - UBGeometryUtils(); - virtual ~UBGeometryUtils(); - - public: - static QPolygonF lineToPolygon(const QLineF& pLine, const qreal& pWidth); - static QRectF lineToInnerRect(const QLineF& pLine, const qreal& pWidth); - - static QPolygonF arcToPolygon(const QLineF& startRadius, qreal spanAngle, qreal width); - - static QPolygonF lineToPolygon(const QPointF& pStart, const QPointF& pEnd, - const qreal& pStartWidth, const qreal& pEndWidth); - - static QPointF pointConstrainedInRect(QPointF point, QRectF rect); - static QPoint pointConstrainedInRect(QPoint point, QRect rect); - - static void crashPointList(QVector &points); - - const static int centimeterGraduationHeight; - const static int halfCentimeterGraduationHeight; - const static int millimeterGraduationHeight; - const static int millimetersPerCentimeter; - const static int millimetersPerHalfCentimeter; - const static float inchSize; -}; - -#endif /* UBGEOMETRYUTILS_H_ */ + + +#ifndef UBGEOMETRYUTILS_H_ +#define UBGEOMETRYUTILS_H_ + +#include + +class UBGeometryUtils +{ + private: + UBGeometryUtils(); + virtual ~UBGeometryUtils(); + + public: + static QPolygonF lineToPolygon(const QLineF& pLine, const qreal& pWidth); + static QRectF lineToInnerRect(const QLineF& pLine, const qreal& pWidth); + + static QPolygonF arcToPolygon(const QLineF& startRadius, qreal spanAngle, qreal width); + + static QPolygonF lineToPolygon(const QPointF& pStart, const QPointF& pEnd, + const qreal& pStartWidth, const qreal& pEndWidth); + + static QPointF pointConstrainedInRect(QPointF point, QRectF rect); + static QPoint pointConstrainedInRect(QPoint point, QRect rect); + + static void crashPointList(QVector &points); + + const static int centimeterGraduationHeight; + const static int halfCentimeterGraduationHeight; + const static int millimeterGraduationHeight; + const static int millimetersPerCentimeter; + const static int millimetersPerHalfCentimeter; + const static float inchSize; +}; + +#endif /* UBGEOMETRYUTILS_H_ */ diff --git a/src/frameworks/UBPlatformUtils_mac.mm b/src/frameworks/UBPlatformUtils_mac.mm index 28c5ab14..02782e5f 100644 --- a/src/frameworks/UBPlatformUtils_mac.mm +++ b/src/frameworks/UBPlatformUtils_mac.mm @@ -461,8 +461,8 @@ void UBPlatformUtils::initializeKeyboardLayouts() int count = CFArrayGetCount(kbds); QList result; - qDebug() << "initializeKeyboardLayouts"; - qDebug() << "Found system locales: " << count; + qDebug() << "initializeKeyboardLayouts"; + qDebug() << "Found system locales: " << count; for(int i=0; i. */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/UBApplication.h" -#include "UBDocumentNavigator.h" -#include "board/UBBoardController.h" -#include "adaptors/UBThumbnailAdaptor.h" -#include "adaptors/UBSvgSubsetAdaptor.h" -#include "document/UBDocumentController.h" -#include "domain/UBGraphicsScene.h" -#include "board/UBBoardPaletteManager.h" -#include "core/UBApplicationController.h" - -#include "core/memcheck.h" - -/** - * \brief Constructor - * @param parent as the parent widget - * @param name as the object name - */ -UBDocumentNavigator::UBDocumentNavigator(QWidget *parent, const char *name):QGraphicsView(parent) - , mScene(NULL) - , mNbColumns(1) - , mThumbnailWidth(0) - , mThumbnailMinWidth(100) -{ - setObjectName(name); - mScene = new QGraphicsScene(this); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setScene(mScene); - mThumbnailWidth = width() - 2*border(); - - setFrameShadow(QFrame::Plain); - - connect(UBApplication::boardController, SIGNAL(documentThumbnailsUpdated(UBDocumentContainer*)), this, SLOT(generateThumbnails(UBDocumentContainer*))); - connect(UBApplication::boardController, SIGNAL(documentPageUpdated(int)), this, SLOT(updateSpecificThumbnail(int))); - connect(UBApplication::boardController, SIGNAL(pageSelectionChanged(int)), this, SLOT(onScrollToSelectedPage(int))); -} - -/** - * \brief Destructor - */ -UBDocumentNavigator::~UBDocumentNavigator() -{ - if(NULL != mScene) - { - delete mScene; - mScene = NULL; - } -} - -#include "gui/UBDockTeacherGuideWidget.h" -#include "gui/UBTeacherGuideWidget.h" - -/** - * \brief Generate the thumbnails - */ -void UBDocumentNavigator::generateThumbnails(UBDocumentContainer* source) -{ - - mThumbsWithLabels.clear(); - foreach(QGraphicsItem* it, mScene->items()) - { - mScene->removeItem(it); - delete it; - it = NULL; - } - - for(int i = 0; i < source->selectedDocument()->pageCount(); i++) - { - const QPixmap* pix = source->pageAt(i); - Q_ASSERT(!pix->isNull()); - int pageIndex = UBDocumentContainer::pageFromSceneIndex(i); - - UBSceneThumbnailNavigPixmap* pixmapItem = new UBSceneThumbnailNavigPixmap(*pix, source->selectedDocument(), i); - - QString label = pageIndex == 0 ? tr("Title page") : tr("Page %0").arg(pageIndex); - UBThumbnailTextItem *labelItem = new UBThumbnailTextItem(label); - - UBImgTextThumbnailElement thumbWithText(pixmapItem, labelItem); - thumbWithText.setBorder(border()); - mThumbsWithLabels.append(thumbWithText); - - mScene->addItem(pixmapItem); - mScene->addItem(labelItem); - } - - // Draw the items - refreshScene(); -} - -void UBDocumentNavigator::onScrollToSelectedPage(int index) -{ - int c = 0; - foreach(UBImgTextThumbnailElement el, mThumbsWithLabels) - { - if (c==index) - { - el.getThumbnail()->setSelected(true); - } - else - { - el.getThumbnail()->setSelected(false); - } - c++; - } -} - -/** - * \brief Refresh the given thumbnail - * @param iPage as the given page related thumbnail - */ -void UBDocumentNavigator::updateSpecificThumbnail(int iPage) -{ - // Generate the new thumbnail - //UBGraphicsScene* pScene = UBApplication::boardController->activeScene(); - - const QPixmap* pix = UBApplication::boardController->pageAt(iPage); - UBSceneThumbnailNavigPixmap* newItem = new UBSceneThumbnailNavigPixmap(*pix, UBApplication::boardController->selectedDocument(), iPage); - - // Get the old thumbnail - UBSceneThumbnailNavigPixmap* oldItem = mThumbsWithLabels.at(iPage).getThumbnail(); - if(NULL != oldItem) - { - mScene->removeItem(oldItem); - mScene->addItem(newItem); - mThumbsWithLabels[iPage].setThumbnail(newItem); - delete oldItem; - oldItem = NULL; - } - -} - -/** - * \brief Put the element in the right place in the scene. - */ -void UBDocumentNavigator::refreshScene() -{ - qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio; - - for(int i = 0; i < mThumbsWithLabels.size(); i++) - { - // Get the item - UBImgTextThumbnailElement& item = mThumbsWithLabels[i]; - int columnIndex = i % mNbColumns; - int rowIndex = i / mNbColumns; - item.Place(rowIndex, columnIndex, mThumbnailWidth, thumbnailHeight); - } - scene()->setSceneRect(scene()->itemsBoundingRect()); -} - -/** - * \brief Set the number of thumbnails columns - * @param nbColumns as the number of columns - */ -void UBDocumentNavigator::setNbColumns(int nbColumns) -{ - mNbColumns = nbColumns; -} - -/** - * \brief Get the number of columns - * @return the number of thumbnails columns - */ -int UBDocumentNavigator::nbColumns() -{ - return mNbColumns; -} - -/** - * \brief Set the thumbnails minimum width - * @param width as the minimum width - */ -void UBDocumentNavigator::setThumbnailMinWidth(int width) -{ - mThumbnailMinWidth = width; -} - -/** - * \brief Get the thumbnails minimum width - * @return the minimum thumbnails width - */ -int UBDocumentNavigator::thumbnailMinWidth() -{ - return mThumbnailMinWidth; -} - -/** - * \brief Get the border size - * @return the border size in pixels - */ -int UBDocumentNavigator::border() -{ - return 20; -} - -/** - * \brief Handle the resize event - * @param event as the resize event - */ -void UBDocumentNavigator::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event); - - // Update the thumbnails width - mThumbnailWidth = (width() > mThumbnailMinWidth) ? width() - 2*border() : mThumbnailMinWidth; - - // Refresh the scene - refreshScene(); -} - -/** - * \brief Handle the mouse press event - * @param event as the mouse event - */ -void UBDocumentNavigator::mousePressEvent(QMouseEvent *event) -{ - QGraphicsItem* pClickedItem = itemAt(event->pos()); - if(NULL != pClickedItem) - { - - // First, select the clicked item - UBSceneThumbnailNavigPixmap* pCrntItem = dynamic_cast(pClickedItem); - - if(NULL == pCrntItem) - { - // If we fall here we may have clicked on the label instead of the thumbnail - UBThumbnailTextItem* pTextItem = dynamic_cast(pClickedItem); - if(NULL != pTextItem) - { - for(int i = 0; i < mThumbsWithLabels.size(); i++) - { - const UBImgTextThumbnailElement& el = mThumbsWithLabels.at(i); - if(el.getCaption() == pTextItem) - { - pCrntItem = el.getThumbnail(); - break; - } - } - } - } - - int index = 0; - for(int i = 0; i < mThumbsWithLabels.size(); i++) - { - if (mThumbsWithLabels.at(i).getThumbnail() == pCrntItem) - { - index = i; - break; - } - } - UBApplication::boardController->setActiveDocumentScene(index); - } - QGraphicsView::mousePressEvent(event); -} - -void UBDocumentNavigator::mouseReleaseEvent(QMouseEvent *event) -{ - event->accept(); -} + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core/UBApplication.h" +#include "UBDocumentNavigator.h" +#include "board/UBBoardController.h" +#include "adaptors/UBThumbnailAdaptor.h" +#include "adaptors/UBSvgSubsetAdaptor.h" +#include "document/UBDocumentController.h" +#include "domain/UBGraphicsScene.h" +#include "board/UBBoardPaletteManager.h" +#include "core/UBApplicationController.h" + +#include "core/memcheck.h" + +/** + * \brief Constructor + * @param parent as the parent widget + * @param name as the object name + */ +UBDocumentNavigator::UBDocumentNavigator(QWidget *parent, const char *name):QGraphicsView(parent) + , mScene(NULL) + , mNbColumns(1) + , mThumbnailWidth(0) + , mThumbnailMinWidth(100) +{ + setObjectName(name); + mScene = new QGraphicsScene(this); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setScene(mScene); + mThumbnailWidth = width() - 2*border(); + + setFrameShadow(QFrame::Plain); + + connect(UBApplication::boardController, SIGNAL(documentThumbnailsUpdated(UBDocumentContainer*)), this, SLOT(generateThumbnails(UBDocumentContainer*))); + connect(UBApplication::boardController, SIGNAL(documentPageUpdated(int)), this, SLOT(updateSpecificThumbnail(int))); + connect(UBApplication::boardController, SIGNAL(pageSelectionChanged(int)), this, SLOT(onScrollToSelectedPage(int))); +} + +/** + * \brief Destructor + */ +UBDocumentNavigator::~UBDocumentNavigator() +{ + if(NULL != mScene) + { + delete mScene; + mScene = NULL; + } +} + +#include "gui/UBDockTeacherGuideWidget.h" +#include "gui/UBTeacherGuideWidget.h" + +/** + * \brief Generate the thumbnails + */ +void UBDocumentNavigator::generateThumbnails(UBDocumentContainer* source) +{ + + mThumbsWithLabels.clear(); + foreach(QGraphicsItem* it, mScene->items()) + { + mScene->removeItem(it); + delete it; + it = NULL; + } + + for(int i = 0; i < source->selectedDocument()->pageCount(); i++) + { + const QPixmap* pix = source->pageAt(i); + Q_ASSERT(!pix->isNull()); + int pageIndex = UBDocumentContainer::pageFromSceneIndex(i); + + UBSceneThumbnailNavigPixmap* pixmapItem = new UBSceneThumbnailNavigPixmap(*pix, source->selectedDocument(), i); + + QString label = pageIndex == 0 ? tr("Title page") : tr("Page %0").arg(pageIndex); + UBThumbnailTextItem *labelItem = new UBThumbnailTextItem(label); + + UBImgTextThumbnailElement thumbWithText(pixmapItem, labelItem); + thumbWithText.setBorder(border()); + mThumbsWithLabels.append(thumbWithText); + + mScene->addItem(pixmapItem); + mScene->addItem(labelItem); + } + + // Draw the items + refreshScene(); +} + +void UBDocumentNavigator::onScrollToSelectedPage(int index) +{ + int c = 0; + foreach(UBImgTextThumbnailElement el, mThumbsWithLabels) + { + if (c==index) + { + el.getThumbnail()->setSelected(true); + } + else + { + el.getThumbnail()->setSelected(false); + } + c++; + } +} + +/** + * \brief Refresh the given thumbnail + * @param iPage as the given page related thumbnail + */ +void UBDocumentNavigator::updateSpecificThumbnail(int iPage) +{ + // Generate the new thumbnail + //UBGraphicsScene* pScene = UBApplication::boardController->activeScene(); + + const QPixmap* pix = UBApplication::boardController->pageAt(iPage); + UBSceneThumbnailNavigPixmap* newItem = new UBSceneThumbnailNavigPixmap(*pix, UBApplication::boardController->selectedDocument(), iPage); + + // Get the old thumbnail + UBSceneThumbnailNavigPixmap* oldItem = mThumbsWithLabels.at(iPage).getThumbnail(); + if(NULL != oldItem) + { + mScene->removeItem(oldItem); + mScene->addItem(newItem); + mThumbsWithLabels[iPage].setThumbnail(newItem); + delete oldItem; + oldItem = NULL; + } + +} + +/** + * \brief Put the element in the right place in the scene. + */ +void UBDocumentNavigator::refreshScene() +{ + qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio; + + for(int i = 0; i < mThumbsWithLabels.size(); i++) + { + // Get the item + UBImgTextThumbnailElement& item = mThumbsWithLabels[i]; + int columnIndex = i % mNbColumns; + int rowIndex = i / mNbColumns; + item.Place(rowIndex, columnIndex, mThumbnailWidth, thumbnailHeight); + } + scene()->setSceneRect(scene()->itemsBoundingRect()); +} + +/** + * \brief Set the number of thumbnails columns + * @param nbColumns as the number of columns + */ +void UBDocumentNavigator::setNbColumns(int nbColumns) +{ + mNbColumns = nbColumns; +} + +/** + * \brief Get the number of columns + * @return the number of thumbnails columns + */ +int UBDocumentNavigator::nbColumns() +{ + return mNbColumns; +} + +/** + * \brief Set the thumbnails minimum width + * @param width as the minimum width + */ +void UBDocumentNavigator::setThumbnailMinWidth(int width) +{ + mThumbnailMinWidth = width; +} + +/** + * \brief Get the thumbnails minimum width + * @return the minimum thumbnails width + */ +int UBDocumentNavigator::thumbnailMinWidth() +{ + return mThumbnailMinWidth; +} + +/** + * \brief Get the border size + * @return the border size in pixels + */ +int UBDocumentNavigator::border() +{ + return 20; +} + +/** + * \brief Handle the resize event + * @param event as the resize event + */ +void UBDocumentNavigator::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + + // Update the thumbnails width + mThumbnailWidth = (width() > mThumbnailMinWidth) ? width() - 2*border() : mThumbnailMinWidth; + + // Refresh the scene + refreshScene(); +} + +/** + * \brief Handle the mouse press event + * @param event as the mouse event + */ +void UBDocumentNavigator::mousePressEvent(QMouseEvent *event) +{ + QGraphicsItem* pClickedItem = itemAt(event->pos()); + if(NULL != pClickedItem) + { + + // First, select the clicked item + UBSceneThumbnailNavigPixmap* pCrntItem = dynamic_cast(pClickedItem); + + if(NULL == pCrntItem) + { + // If we fall here we may have clicked on the label instead of the thumbnail + UBThumbnailTextItem* pTextItem = dynamic_cast(pClickedItem); + if(NULL != pTextItem) + { + for(int i = 0; i < mThumbsWithLabels.size(); i++) + { + const UBImgTextThumbnailElement& el = mThumbsWithLabels.at(i); + if(el.getCaption() == pTextItem) + { + pCrntItem = el.getThumbnail(); + break; + } + } + } + } + + int index = 0; + for(int i = 0; i < mThumbsWithLabels.size(); i++) + { + if (mThumbsWithLabels.at(i).getThumbnail() == pCrntItem) + { + index = i; + break; + } + } + UBApplication::boardController->setActiveDocumentScene(index); + } + QGraphicsView::mousePressEvent(event); +} + +void UBDocumentNavigator::mouseReleaseEvent(QMouseEvent *event) +{ + event->accept(); +} diff --git a/src/gui/UBDocumentNavigator.h b/src/gui/UBDocumentNavigator.h index 838cbfa3..c7696595 100644 --- a/src/gui/UBDocumentNavigator.h +++ b/src/gui/UBDocumentNavigator.h @@ -19,63 +19,63 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBDOCUMENTNAVIGATOR_H -#define UBDOCUMENTNAVIGATOR_H - -#include -#include -#include -#include -#include - -#include "document/UBDocumentProxy.h" -#include "document/UBDocumentContainer.h" -#include "UBThumbnailWidget.h" - -#define NO_PAGESELECTED -1 - -class UBDocumentNavigator : public QGraphicsView -{ - Q_OBJECT -public: - UBDocumentNavigator(QWidget* parent=0, const char* name="documentNavigator"); - ~UBDocumentNavigator(); - - void setNbColumns(int nbColumns); - int nbColumns(); - void setThumbnailMinWidth(int width); - int thumbnailMinWidth(); - -public slots: - void onScrollToSelectedPage(int index);// { if (mCrntItem) centerOn(mCrntItem); } - void generateThumbnails(UBDocumentContainer* source); - void updateSpecificThumbnail(int iPage); - -protected: - virtual void resizeEvent(QResizeEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - -private: - - void refreshScene(); - int border(); - - - /** The scene */ - QGraphicsScene* mScene; - /** The current selected item */ - //UBSceneThumbnailNavigPixmap* mCrntItem; - /** The list of current thumbnails with labels*/ - QList mThumbsWithLabels; - /** The current number of columns */ - int mNbColumns; - /** The current thumbnails width */ - int mThumbnailWidth; - /** The current thumbnails minimum width */ - int mThumbnailMinWidth; -}; - -#endif // UBDOCUMENTNAVIGATOR_H + + +#ifndef UBDOCUMENTNAVIGATOR_H +#define UBDOCUMENTNAVIGATOR_H + +#include +#include +#include +#include +#include + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentContainer.h" +#include "UBThumbnailWidget.h" + +#define NO_PAGESELECTED -1 + +class UBDocumentNavigator : public QGraphicsView +{ + Q_OBJECT +public: + UBDocumentNavigator(QWidget* parent=0, const char* name="documentNavigator"); + ~UBDocumentNavigator(); + + void setNbColumns(int nbColumns); + int nbColumns(); + void setThumbnailMinWidth(int width); + int thumbnailMinWidth(); + +public slots: + void onScrollToSelectedPage(int index);// { if (mCrntItem) centerOn(mCrntItem); } + void generateThumbnails(UBDocumentContainer* source); + void updateSpecificThumbnail(int iPage); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + +private: + + void refreshScene(); + int border(); + + + /** The scene */ + QGraphicsScene* mScene; + /** The current selected item */ + //UBSceneThumbnailNavigPixmap* mCrntItem; + /** The list of current thumbnails with labels*/ + QList mThumbsWithLabels; + /** The current number of columns */ + int mNbColumns; + /** The current thumbnails width */ + int mThumbnailWidth; + /** The current thumbnails minimum width */ + int mThumbnailMinWidth; +}; + +#endif // UBDOCUMENTNAVIGATOR_H diff --git a/src/gui/UBDocumentThumbnailWidget.cpp b/src/gui/UBDocumentThumbnailWidget.cpp index 6826055f..f21df274 100644 --- a/src/gui/UBDocumentThumbnailWidget.cpp +++ b/src/gui/UBDocumentThumbnailWidget.cpp @@ -19,305 +19,305 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBDocumentThumbnailWidget.h" - -#include "core/UBApplication.h" -#include "core/UBMimeData.h" -#include "core/UBSettings.h" - -#include "board/UBBoardController.h" - -#include "document/UBDocumentController.h" - -#include "core/memcheck.h" - - -UBDocumentThumbnailWidget::UBDocumentThumbnailWidget(QWidget* parent) - : UBThumbnailWidget(parent) - , mDropCaretRectItem(0) - , mClosestDropItem(0) - , mDragEnabled(true) - , mScrollMagnitude(0) -{ - bCanDrag = false; - mScrollTimer = new QTimer(this); - connect(mScrollTimer, SIGNAL(timeout()), this, SLOT(autoScroll())); -} - - -UBDocumentThumbnailWidget::~UBDocumentThumbnailWidget() -{ - // NOOP -} - - -void UBDocumentThumbnailWidget::mouseMoveEvent(QMouseEvent *event) -{ - if (!dragEnabled()) - { - event->ignore(); - return; - } - - if (!(event->buttons() & Qt::LeftButton)) - return; - - if ((event->pos() - mMousePressPos).manhattanLength() < QApplication::startDragDistance()) - return; - - QList graphicsItems = items(mMousePressPos); - - UBSceneThumbnailPixmap* sceneItem = 0; - - while (!graphicsItems.isEmpty() && !sceneItem) - sceneItem = dynamic_cast(graphicsItems.takeFirst()); - - if (sceneItem) - { - int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneItem->sceneIndex()); - if(pageIndex != 0){ - QDrag *drag = new QDrag(this); - QList mimeDataItems; - foreach (QGraphicsItem *item, selectedItems()) - mimeDataItems.append(UBMimeDataItem(sceneItem->proxy(), mGraphicItems.indexOf(item))); - - UBMimeData *mime = new UBMimeData(mimeDataItems); - drag->setMimeData(mime); - - drag->setPixmap(sceneItem->pixmap().scaledToWidth(100)); - drag->setHotSpot(QPoint(drag->pixmap().width()/2, drag->pixmap().height() / 2)); - - drag->exec(Qt::MoveAction); - } - } - - UBThumbnailWidget::mouseMoveEvent(event); -} - -void UBDocumentThumbnailWidget::dragEnterEvent(QDragEnterEvent *event) -{ - if (!event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - event->setDropAction(Qt::IgnoreAction); - event->ignore(); - return; - } - - UBThumbnailWidget::dragEnterEvent(event); -} - -void UBDocumentThumbnailWidget::dragLeaveEvent(QDragLeaveEvent *event) -{ - Q_UNUSED(event); - if (mScrollTimer->isActive()) - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - deleteDropCaret(); - UBThumbnailWidget::dragLeaveEvent(event); -} - -void UBDocumentThumbnailWidget::autoScroll() -{ - this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); -} - -void UBDocumentThumbnailWidget::dragMoveEvent(QDragMoveEvent *event) -{ - QRect boundingFrame = frameRect(); - //setting up automatic scrolling - const int SCROLL_DISTANCE = 16; - int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); - if(qAbs(bottomDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else if(qAbs(topDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - - QList pixmapItems; - foreach (QGraphicsItem *item, scene()->items(mapToScene(boundingFrame))) - { - UBSceneThumbnailPixmap* sceneItem = dynamic_cast(item); - if (sceneItem) - pixmapItems.append(sceneItem); - } - - int minDistance = 0; - QGraphicsItem *underlyingItem = itemAt(event->pos()); - mClosestDropItem = dynamic_cast(underlyingItem); - - int pageIndex = -1; - if(mClosestDropItem){ - pageIndex = UBDocumentContainer::pageFromSceneIndex(mClosestDropItem->sceneIndex()); - if(pageIndex == 0){ - event->acceptProposedAction(); - return; - } - } - if (!mClosestDropItem) - { - foreach (UBSceneThumbnailPixmap *item, pixmapItems) - { - qreal scale = item->transform().m11(); - QPointF itemCenter( - item->pos().x() + item->boundingRect().width() * scale / 2, - item->pos().y() + item->boundingRect().height() * scale / 2); - - int distance = (itemCenter.toPoint() - mapToScene(event->pos()).toPoint()).manhattanLength(); - if (!mClosestDropItem || distance < minDistance) - { - mClosestDropItem = item; - minDistance = distance; - pageIndex = UBDocumentContainer::pageFromSceneIndex(mClosestDropItem->sceneIndex()); - } - } - } - - if (mClosestDropItem && pageIndex != 0) - { - qreal scale = mClosestDropItem->transform().m11(); - - QPointF itemCenter( - mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale / 2, - mClosestDropItem->pos().y() + mClosestDropItem->boundingRect().height() * scale / 2); - - mDropIsRight = mapToScene(event->pos()).x() > itemCenter.x(); - - if (!mDropCaretRectItem && selectedItems().count() < mGraphicItems.count()) - { - mDropCaretRectItem = new QGraphicsRectItem(0, scene()); - mDropCaretRectItem->setPen(QPen(Qt::darkGray)); - mDropCaretRectItem->setBrush(QBrush(Qt::lightGray)); - } - - QRectF dropCaretRect( - mDropIsRight ? mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale + spacing() / 2 - 1 : mClosestDropItem->pos().x() - spacing() / 2 - 1, - mClosestDropItem->pos().y(), - 3, - mClosestDropItem->boundingRect().height() * scale); - - if (mDropCaretRectItem) - mDropCaretRectItem->setRect(dropCaretRect); - } - - event->acceptProposedAction(); -} - - -void UBDocumentThumbnailWidget::dropEvent(QDropEvent *event) -{ - if (mScrollTimer->isActive()) - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - deleteDropCaret(); - - if (mClosestDropItem) - { - int targetIndex = mDropIsRight ? mGraphicItems.indexOf(mClosestDropItem) + 1 : mGraphicItems.indexOf(mClosestDropItem); - if(UBDocumentContainer::pageFromSceneIndex(targetIndex) == 0){ - event->ignore(); - return; - } - - QList mimeDataItems; - if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - const UBMimeData* mimeData = qobject_cast(event->mimeData()); - if (mimeData) - mimeDataItems = mimeData->items(); - } - - if (1 == mimeDataItems.count() && - (mimeDataItems.at(0).sceneIndex() == mGraphicItems.indexOf(mClosestDropItem) || - targetIndex == mimeDataItems.at(0).sceneIndex() || - targetIndex == mimeDataItems.at(0).sceneIndex() + 1)) - { - return; - } - - int sourceIndexOffset = 0; - int actualTargetIndex = targetIndex; - for (int i = mimeDataItems.count() - 1; i >= 0; i--) - { - UBMimeDataItem sourceItem = mimeDataItems.at(i); - int actualSourceIndex = sourceItem.sceneIndex(); - if (sourceItem.sceneIndex() >= targetIndex) - actualSourceIndex += sourceIndexOffset; - - //event->acceptProposedAction(); - if (sourceItem.sceneIndex() < targetIndex) - { - if (actualSourceIndex != actualTargetIndex - 1) - emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex - 1); - actualTargetIndex -= 1; - } - else - { - if (actualSourceIndex != actualTargetIndex) - emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex); - sourceIndexOffset += 1; - } - } - } - UBThumbnailWidget::dropEvent(event); -} - -void UBDocumentThumbnailWidget::deleteDropCaret() -{ - if (mDropCaretRectItem && scene()) - { - scene()->removeItem(mDropCaretRectItem); - delete mDropCaretRectItem; - mDropCaretRectItem = 0; - } -} - -void UBDocumentThumbnailWidget::setGraphicsItems(const QList& pGraphicsItems, - const QList& pItemPaths, const QStringList pLabels, - const QString& pMimeType) -{ - deleteDropCaret(); - - UBThumbnailWidget::setGraphicsItems(pGraphicsItems, pItemPaths, pLabels, pMimeType); -} - -void UBDocumentThumbnailWidget::setDragEnabled(bool enabled) -{ - mDragEnabled = enabled; -} - -bool UBDocumentThumbnailWidget::dragEnabled() const -{ - return mDragEnabled; -} - -void UBDocumentThumbnailWidget::hightlightItem(int index) -{ - if (0 <= index && index < mLabelsItems.length()) - { - mLabelsItems.at(index)->highlight(); - } - if (0 <= index && index < mGraphicItems.length()) - { - UBSceneThumbnailPixmap *thumbnail = dynamic_cast(mGraphicItems.at(index)); - if (thumbnail) - thumbnail->highlight(); - } - - selectItemAt(index); -} + + +#include "UBDocumentThumbnailWidget.h" + +#include "core/UBApplication.h" +#include "core/UBMimeData.h" +#include "core/UBSettings.h" + +#include "board/UBBoardController.h" + +#include "document/UBDocumentController.h" + +#include "core/memcheck.h" + + +UBDocumentThumbnailWidget::UBDocumentThumbnailWidget(QWidget* parent) + : UBThumbnailWidget(parent) + , mDropCaretRectItem(0) + , mClosestDropItem(0) + , mDragEnabled(true) + , mScrollMagnitude(0) +{ + bCanDrag = false; + mScrollTimer = new QTimer(this); + connect(mScrollTimer, SIGNAL(timeout()), this, SLOT(autoScroll())); +} + + +UBDocumentThumbnailWidget::~UBDocumentThumbnailWidget() +{ + // NOOP +} + + +void UBDocumentThumbnailWidget::mouseMoveEvent(QMouseEvent *event) +{ + if (!dragEnabled()) + { + event->ignore(); + return; + } + + if (!(event->buttons() & Qt::LeftButton)) + return; + + if ((event->pos() - mMousePressPos).manhattanLength() < QApplication::startDragDistance()) + return; + + QList graphicsItems = items(mMousePressPos); + + UBSceneThumbnailPixmap* sceneItem = 0; + + while (!graphicsItems.isEmpty() && !sceneItem) + sceneItem = dynamic_cast(graphicsItems.takeFirst()); + + if (sceneItem) + { + int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneItem->sceneIndex()); + if(pageIndex != 0){ + QDrag *drag = new QDrag(this); + QList mimeDataItems; + foreach (QGraphicsItem *item, selectedItems()) + mimeDataItems.append(UBMimeDataItem(sceneItem->proxy(), mGraphicItems.indexOf(item))); + + UBMimeData *mime = new UBMimeData(mimeDataItems); + drag->setMimeData(mime); + + drag->setPixmap(sceneItem->pixmap().scaledToWidth(100)); + drag->setHotSpot(QPoint(drag->pixmap().width()/2, drag->pixmap().height() / 2)); + + drag->exec(Qt::MoveAction); + } + } + + UBThumbnailWidget::mouseMoveEvent(event); +} + +void UBDocumentThumbnailWidget::dragEnterEvent(QDragEnterEvent *event) +{ + if (!event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + event->setDropAction(Qt::IgnoreAction); + event->ignore(); + return; + } + + UBThumbnailWidget::dragEnterEvent(event); +} + +void UBDocumentThumbnailWidget::dragLeaveEvent(QDragLeaveEvent *event) +{ + Q_UNUSED(event); + if (mScrollTimer->isActive()) + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + deleteDropCaret(); + UBThumbnailWidget::dragLeaveEvent(event); +} + +void UBDocumentThumbnailWidget::autoScroll() +{ + this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); +} + +void UBDocumentThumbnailWidget::dragMoveEvent(QDragMoveEvent *event) +{ + QRect boundingFrame = frameRect(); + //setting up automatic scrolling + const int SCROLL_DISTANCE = 16; + int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); + if(qAbs(bottomDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else if(qAbs(topDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + + QList pixmapItems; + foreach (QGraphicsItem *item, scene()->items(mapToScene(boundingFrame))) + { + UBSceneThumbnailPixmap* sceneItem = dynamic_cast(item); + if (sceneItem) + pixmapItems.append(sceneItem); + } + + int minDistance = 0; + QGraphicsItem *underlyingItem = itemAt(event->pos()); + mClosestDropItem = dynamic_cast(underlyingItem); + + int pageIndex = -1; + if(mClosestDropItem){ + pageIndex = UBDocumentContainer::pageFromSceneIndex(mClosestDropItem->sceneIndex()); + if(pageIndex == 0){ + event->acceptProposedAction(); + return; + } + } + if (!mClosestDropItem) + { + foreach (UBSceneThumbnailPixmap *item, pixmapItems) + { + qreal scale = item->transform().m11(); + QPointF itemCenter( + item->pos().x() + item->boundingRect().width() * scale / 2, + item->pos().y() + item->boundingRect().height() * scale / 2); + + int distance = (itemCenter.toPoint() - mapToScene(event->pos()).toPoint()).manhattanLength(); + if (!mClosestDropItem || distance < minDistance) + { + mClosestDropItem = item; + minDistance = distance; + pageIndex = UBDocumentContainer::pageFromSceneIndex(mClosestDropItem->sceneIndex()); + } + } + } + + if (mClosestDropItem && pageIndex != 0) + { + qreal scale = mClosestDropItem->transform().m11(); + + QPointF itemCenter( + mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale / 2, + mClosestDropItem->pos().y() + mClosestDropItem->boundingRect().height() * scale / 2); + + mDropIsRight = mapToScene(event->pos()).x() > itemCenter.x(); + + if (!mDropCaretRectItem && selectedItems().count() < mGraphicItems.count()) + { + mDropCaretRectItem = new QGraphicsRectItem(0, scene()); + mDropCaretRectItem->setPen(QPen(Qt::darkGray)); + mDropCaretRectItem->setBrush(QBrush(Qt::lightGray)); + } + + QRectF dropCaretRect( + mDropIsRight ? mClosestDropItem->pos().x() + mClosestDropItem->boundingRect().width() * scale + spacing() / 2 - 1 : mClosestDropItem->pos().x() - spacing() / 2 - 1, + mClosestDropItem->pos().y(), + 3, + mClosestDropItem->boundingRect().height() * scale); + + if (mDropCaretRectItem) + mDropCaretRectItem->setRect(dropCaretRect); + } + + event->acceptProposedAction(); +} + + +void UBDocumentThumbnailWidget::dropEvent(QDropEvent *event) +{ + if (mScrollTimer->isActive()) + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + deleteDropCaret(); + + if (mClosestDropItem) + { + int targetIndex = mDropIsRight ? mGraphicItems.indexOf(mClosestDropItem) + 1 : mGraphicItems.indexOf(mClosestDropItem); + if(UBDocumentContainer::pageFromSceneIndex(targetIndex) == 0){ + event->ignore(); + return; + } + + QList mimeDataItems; + if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + const UBMimeData* mimeData = qobject_cast(event->mimeData()); + if (mimeData) + mimeDataItems = mimeData->items(); + } + + if (1 == mimeDataItems.count() && + (mimeDataItems.at(0).sceneIndex() == mGraphicItems.indexOf(mClosestDropItem) || + targetIndex == mimeDataItems.at(0).sceneIndex() || + targetIndex == mimeDataItems.at(0).sceneIndex() + 1)) + { + return; + } + + int sourceIndexOffset = 0; + int actualTargetIndex = targetIndex; + for (int i = mimeDataItems.count() - 1; i >= 0; i--) + { + UBMimeDataItem sourceItem = mimeDataItems.at(i); + int actualSourceIndex = sourceItem.sceneIndex(); + if (sourceItem.sceneIndex() >= targetIndex) + actualSourceIndex += sourceIndexOffset; + + //event->acceptProposedAction(); + if (sourceItem.sceneIndex() < targetIndex) + { + if (actualSourceIndex != actualTargetIndex - 1) + emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex - 1); + actualTargetIndex -= 1; + } + else + { + if (actualSourceIndex != actualTargetIndex) + emit sceneDropped(sourceItem.documentProxy(), actualSourceIndex, actualTargetIndex); + sourceIndexOffset += 1; + } + } + } + UBThumbnailWidget::dropEvent(event); +} + +void UBDocumentThumbnailWidget::deleteDropCaret() +{ + if (mDropCaretRectItem && scene()) + { + scene()->removeItem(mDropCaretRectItem); + delete mDropCaretRectItem; + mDropCaretRectItem = 0; + } +} + +void UBDocumentThumbnailWidget::setGraphicsItems(const QList& pGraphicsItems, + const QList& pItemPaths, const QStringList pLabels, + const QString& pMimeType) +{ + deleteDropCaret(); + + UBThumbnailWidget::setGraphicsItems(pGraphicsItems, pItemPaths, pLabels, pMimeType); +} + +void UBDocumentThumbnailWidget::setDragEnabled(bool enabled) +{ + mDragEnabled = enabled; +} + +bool UBDocumentThumbnailWidget::dragEnabled() const +{ + return mDragEnabled; +} + +void UBDocumentThumbnailWidget::hightlightItem(int index) +{ + if (0 <= index && index < mLabelsItems.length()) + { + mLabelsItems.at(index)->highlight(); + } + if (0 <= index && index < mGraphicItems.length()) + { + UBSceneThumbnailPixmap *thumbnail = dynamic_cast(mGraphicItems.at(index)); + if (thumbnail) + thumbnail->highlight(); + } + + selectItemAt(index); +} diff --git a/src/gui/UBDocumentTreeWidget.cpp b/src/gui/UBDocumentTreeWidget.cpp index e0bcebb4..3688618c 100644 --- a/src/gui/UBDocumentTreeWidget.cpp +++ b/src/gui/UBDocumentTreeWidget.cpp @@ -19,447 +19,447 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBDocumentTreeWidget.h" - -#include "document/UBDocumentProxy.h" - -#include "core/UBSettings.h" -#include "core/UBApplication.h" -#include "core/UBPersistenceManager.h" -#include "core/UBMimeData.h" -#include "core/UBApplicationController.h" -#include "core/UBDocumentManager.h" -#include "document/UBDocumentController.h" - -#include "adaptors/UBThumbnailAdaptor.h" -#include "adaptors/UBSvgSubsetAdaptor.h" -#include "frameworks/UBFileSystemUtils.h" - -#include "core/memcheck.h" - -UBDocumentTreeWidget::UBDocumentTreeWidget(QWidget * parent) - : QTreeWidget(parent) - , mSelectedProxyTi(0) - , mDropTargetProxyTi(0) -{ - setDragDropMode(QAbstractItemView::InternalMove); - setAutoScroll(true); - - mScrollTimer = new QTimer(this); - connect(UBDocumentManager::documentManager(), SIGNAL(documentUpdated(UBDocumentProxy*)) - , this, SLOT(documentUpdated(UBDocumentProxy*))); - - connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)) - , this, SLOT(itemChangedValidation(QTreeWidgetItem *, int))); - connect(mScrollTimer, SIGNAL(timeout()) - , this, SLOT(autoScroll())); -} - - -UBDocumentTreeWidget::~UBDocumentTreeWidget() -{ - // NOOP -} - - -void UBDocumentTreeWidget::itemChangedValidation(QTreeWidgetItem * item, int column) -{ - if (column == 0) - { - UBDocumentGroupTreeItem *group = dynamic_cast< UBDocumentGroupTreeItem *>(item); - - if (group) - { - QString name = group->text(0); - - for(int i = 0; i < topLevelItemCount (); i++) - { - QTreeWidgetItem *someTopLevelItem = topLevelItem(i); - - if (someTopLevelItem != group && - someTopLevelItem->text(0) == name) - { - group->setText(0, tr("%1 (copy)").arg(name)); - } - } - } - } -} - - -Qt::DropActions UBDocumentTreeWidget::supportedDropActions() const -{ - return Qt::MoveAction | Qt::CopyAction; -} - - -void UBDocumentTreeWidget::mousePressEvent(QMouseEvent *event) -{ - QTreeWidgetItem* twItem = this->itemAt(event->pos()); - - mSelectedProxyTi = dynamic_cast(twItem); - - QTreeWidget::mousePressEvent(event); -} - - -void UBDocumentTreeWidget::dragEnterEvent(QDragEnterEvent *event) -{ - event->acceptProposedAction(); -} - - -void UBDocumentTreeWidget::dragLeaveEvent(QDragLeaveEvent *event) -{ - Q_UNUSED(event); - - if (mScrollTimer->isActive()) - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - - if (mDropTargetProxyTi) - { - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = 0; - } -} - - -void UBDocumentTreeWidget::dragMoveEvent(QDragMoveEvent *event) -{ - QRect boundingFrame = frameRect(); - //setting up automatic scrolling - const int SCROLL_DISTANCE = 4; - int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); - if(qAbs(bottomDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else if(qAbs(topDist) <= SCROLL_DISTANCE) - { - mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; - if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); - } - else - { - mScrollMagnitude = 0; - mScrollTimer->stop(); - } - - - QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); - - if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingItem); - if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) - { - event->setDropAction(Qt::CopyAction); - event->accept(); - } - else - { - event->ignore(); - } - } - else - { - UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); - - if (groupItem && mSelectedProxyTi && groupItem != mSelectedProxyTi->parent()) - event->acceptProposedAction(); - else - event->ignore(); - } - - if (event->isAccepted()) - { - if (mDropTargetProxyTi) - { - if (underlyingItem != mDropTargetProxyTi) - { - mBackground = underlyingItem->background(0); - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = underlyingItem; - mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); - } - } - else - { - mBackground = underlyingItem->background(0); - mDropTargetProxyTi = underlyingItem; - mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); - } - } - else if (mDropTargetProxyTi) - { - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = 0; - } -} - - -void UBDocumentTreeWidget::focusInEvent(QFocusEvent *event) -{ - Q_UNUSED(event); - - // Tolik - //itemSelectionChanged(); - - QTreeWidget::focusInEvent(event); -} - - -void UBDocumentTreeWidget::dropEvent(QDropEvent *event) -{ - if (mDropTargetProxyTi) - { - mDropTargetProxyTi->setBackground(0, mBackground); - mDropTargetProxyTi = 0; - } - - QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); - - UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); - - if (groupItem && mSelectedProxyTi && mSelectedProxyTi->proxy()) - { - UBDocumentGroupTreeItem *sourceGroupItem = dynamic_cast(mSelectedProxyTi->parent()); - bool isTrashItem = sourceGroupItem && sourceGroupItem->isTrashFolder(); - if ((isTrashItem && !groupItem->isTrashFolder()) || - (!isTrashItem && mSelectedProxyTi->proxy()->groupName() != groupItem->groupName())) - { - QString groupName; - if (groupItem->isTrashFolder()) - { - QString oldGroupName = mSelectedProxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); - groupName = UBSettings::trashedDocumentGroupNamePrefix + oldGroupName; - } - else - { - if (groupItem->groupName() == UBApplication::app()->documentController->defaultDocumentGroupName()) - groupName = ""; - else - groupName = groupItem->groupName(); - } - mSelectedProxyTi->proxy()->setMetaData(UBSettings::documentGroupName, groupName); - UBPersistenceManager::persistenceManager()->persistDocumentMetadata(mSelectedProxyTi->proxy()); - - mSelectedProxyTi->parent()->removeChild(mSelectedProxyTi); - - int i = 0; - for (i = 0; i < groupItem->childCount(); i++) - { - QTreeWidgetItem *ti = groupItem->child(i); - UBDocumentProxyTreeItem* pi = dynamic_cast(ti); - if (pi) - { - if (mSelectedProxyTi->proxy()->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) - { - break; - } - } - } - groupItem->insertChild(i, mSelectedProxyTi); - - if (isTrashItem) - mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() | Qt::ItemIsEditable); - - if (groupItem->isTrashFolder()) - mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() ^ Qt::ItemIsEditable); - - //clearSelection(); - expandItem(groupItem); - scrollToItem(mSelectedProxyTi); - - // disabled, as those 2 calls are buggy on windows, the item disappears if we selected them - // - setCurrentItem(mSelectedProxyTi); - mSelectedProxyTi->setSelected(true); - - event->setDropAction(Qt::IgnoreAction); - event->accept(); - } - } - else - { - QTreeWidgetItem* underlyingTreeItem = this->itemAt(event->pos()); - - UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingTreeItem); - if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) - { - if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) - { - event->setDropAction(Qt::CopyAction); - event->accept(); - - const UBMimeData *mimeData = qobject_cast (event->mimeData()); - - if (mimeData && mimeData->items().size() > 0) - { - int count = 0; - int total = mimeData->items().size(); - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - foreach (UBMimeDataItem sourceItem, mimeData->items()) - { - count++; - - UBApplication::applicationController->showMessage(tr("Copying page %1/%2").arg(count).arg(total), true); - - // TODO UB 4.x Move following code to some controller class - UBGraphicsScene *scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(sourceItem.documentProxy(), sourceItem.sceneIndex()); - if (scene) - { - UBGraphicsScene* sceneClone = scene->sceneDeepCopy(); - - UBDocumentProxy *targetDocProxy = targetProxyTreeItem->proxy(); - - foreach (QUrl relativeFile, scene->relativeDependencies()) - { - QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); - QString target = targetDocProxy->persistencePath() + "/" + relativeFile.toString(); - - QFileInfo fi(target); - QDir d = fi.dir(); - - d.mkpath(d.absolutePath()); - QFile::copy(source, target); - } - - UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(targetDocProxy, sceneClone, targetDocProxy->pageCount()); - - //due to incorrect generation of thumbnails of invisible scene I've used direct copying of thumbnail files - //it's not universal and good way but it's faster - QString from = sourceItem.documentProxy()->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceItem.sceneIndex()); - QString to = targetDocProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetDocProxy->pageCount()); - QFile::remove(to); - QFile::copy(from, to); - } - } - - QApplication::restoreOverrideCursor(); - - UBApplication::applicationController->showMessage(tr("%1 pages copied", "", total).arg(total), false); - } - } - else - { - event->setDropAction(Qt::IgnoreAction); - event->ignore(); - } - } - } -} - - -void UBDocumentTreeWidget::documentUpdated(UBDocumentProxy *pDocument) -{ - UBDocumentProxyTreeItem *treeItem = UBApplication::documentController->findDocument(pDocument); - if (treeItem) - { - QTreeWidgetItem * parent = treeItem->parent(); - - if (parent) - { - for (int i = 0; i < parent->indexOfChild(treeItem); i++) - { - QTreeWidgetItem *ti = parent->child(i); - UBDocumentProxyTreeItem* pi = dynamic_cast(ti); - if (pi) - { - if (pDocument->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) - { - bool selected = treeItem->isSelected(); - parent->removeChild(treeItem); - parent->insertChild(i, treeItem); - for (int j = 0; j < selectedItems().count(); j++) - selectedItems().at(j)->setSelected(false); - if (selected) - treeItem->setSelected(true); - break; - } - } - } - } - } -} - - -UBDocumentProxyTreeItem::UBDocumentProxyTreeItem(QTreeWidgetItem * parent, UBDocumentProxy* proxy, bool isEditable) - : QTreeWidgetItem() - , mProxy(proxy) -{ - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; - - if (isEditable) - flags |= Qt::ItemIsEditable; - - setFlags(flags); - - int i = 0; - for (i = 0; i < parent->childCount(); i++) - { - QTreeWidgetItem *ti = parent->child(i); - UBDocumentProxyTreeItem* pi = dynamic_cast(ti); - if (pi) - { - if (proxy->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) - { - break; - } - } - } - parent->insertChild(i, this); -} - - -UBDocumentGroupTreeItem::UBDocumentGroupTreeItem(QTreeWidgetItem *parent, bool isEditable) - : QTreeWidgetItem(parent) -{ - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; - if (isEditable) - flags |= Qt::ItemIsEditable; - setFlags(flags); -} - - -UBDocumentGroupTreeItem::~UBDocumentGroupTreeItem() -{ - // NOOP -} - - -void UBDocumentGroupTreeItem::setGroupName(const QString& groupName) -{ - setText(0, groupName); -} - - -QString UBDocumentGroupTreeItem::groupName() const -{ - return text(0); -} - - -bool UBDocumentGroupTreeItem::isTrashFolder() const -{ - return (0 == (flags() & Qt::ItemIsEditable)) && UBApplication::app()->documentController && (groupName() == UBApplication::app()->documentController->documentTrashGroupName()); -} - -bool UBDocumentGroupTreeItem::isDefaultFolder() const -{ - return (0 == (flags() & Qt::ItemIsEditable)) && UBApplication::app()->documentController && (groupName() == UBApplication::app()->documentController->defaultDocumentGroupName()); -} - - -void UBDocumentTreeWidget::autoScroll() -{ - this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); -} + + +#include "UBDocumentTreeWidget.h" + +#include "document/UBDocumentProxy.h" + +#include "core/UBSettings.h" +#include "core/UBApplication.h" +#include "core/UBPersistenceManager.h" +#include "core/UBMimeData.h" +#include "core/UBApplicationController.h" +#include "core/UBDocumentManager.h" +#include "document/UBDocumentController.h" + +#include "adaptors/UBThumbnailAdaptor.h" +#include "adaptors/UBSvgSubsetAdaptor.h" +#include "frameworks/UBFileSystemUtils.h" + +#include "core/memcheck.h" + +UBDocumentTreeWidget::UBDocumentTreeWidget(QWidget * parent) + : QTreeWidget(parent) + , mSelectedProxyTi(0) + , mDropTargetProxyTi(0) +{ + setDragDropMode(QAbstractItemView::InternalMove); + setAutoScroll(true); + + mScrollTimer = new QTimer(this); + connect(UBDocumentManager::documentManager(), SIGNAL(documentUpdated(UBDocumentProxy*)) + , this, SLOT(documentUpdated(UBDocumentProxy*))); + + connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)) + , this, SLOT(itemChangedValidation(QTreeWidgetItem *, int))); + connect(mScrollTimer, SIGNAL(timeout()) + , this, SLOT(autoScroll())); +} + + +UBDocumentTreeWidget::~UBDocumentTreeWidget() +{ + // NOOP +} + + +void UBDocumentTreeWidget::itemChangedValidation(QTreeWidgetItem * item, int column) +{ + if (column == 0) + { + UBDocumentGroupTreeItem *group = dynamic_cast< UBDocumentGroupTreeItem *>(item); + + if (group) + { + QString name = group->text(0); + + for(int i = 0; i < topLevelItemCount (); i++) + { + QTreeWidgetItem *someTopLevelItem = topLevelItem(i); + + if (someTopLevelItem != group && + someTopLevelItem->text(0) == name) + { + group->setText(0, tr("%1 (copy)").arg(name)); + } + } + } + } +} + + +Qt::DropActions UBDocumentTreeWidget::supportedDropActions() const +{ + return Qt::MoveAction | Qt::CopyAction; +} + + +void UBDocumentTreeWidget::mousePressEvent(QMouseEvent *event) +{ + QTreeWidgetItem* twItem = this->itemAt(event->pos()); + + mSelectedProxyTi = dynamic_cast(twItem); + + QTreeWidget::mousePressEvent(event); +} + + +void UBDocumentTreeWidget::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} + + +void UBDocumentTreeWidget::dragLeaveEvent(QDragLeaveEvent *event) +{ + Q_UNUSED(event); + + if (mScrollTimer->isActive()) + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + + if (mDropTargetProxyTi) + { + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = 0; + } +} + + +void UBDocumentTreeWidget::dragMoveEvent(QDragMoveEvent *event) +{ + QRect boundingFrame = frameRect(); + //setting up automatic scrolling + const int SCROLL_DISTANCE = 4; + int bottomDist = boundingFrame.bottom() - event->pos().y(), topDist = boundingFrame.top() - event->pos().y(); + if(qAbs(bottomDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (SCROLL_DISTANCE - bottomDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else if(qAbs(topDist) <= SCROLL_DISTANCE) + { + mScrollMagnitude = (- SCROLL_DISTANCE - topDist)*4; + if(verticalScrollBar()->isVisible() && !mScrollTimer->isActive()) mScrollTimer->start(100); + } + else + { + mScrollMagnitude = 0; + mScrollTimer->stop(); + } + + + QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); + + if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingItem); + if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) + { + event->setDropAction(Qt::CopyAction); + event->accept(); + } + else + { + event->ignore(); + } + } + else + { + UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); + + if (groupItem && mSelectedProxyTi && groupItem != mSelectedProxyTi->parent()) + event->acceptProposedAction(); + else + event->ignore(); + } + + if (event->isAccepted()) + { + if (mDropTargetProxyTi) + { + if (underlyingItem != mDropTargetProxyTi) + { + mBackground = underlyingItem->background(0); + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = underlyingItem; + mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); + } + } + else + { + mBackground = underlyingItem->background(0); + mDropTargetProxyTi = underlyingItem; + mDropTargetProxyTi->setBackground(0, QBrush(QColor("#6682b5"))); + } + } + else if (mDropTargetProxyTi) + { + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = 0; + } +} + + +void UBDocumentTreeWidget::focusInEvent(QFocusEvent *event) +{ + Q_UNUSED(event); + + // Tolik + //itemSelectionChanged(); + + QTreeWidget::focusInEvent(event); +} + + +void UBDocumentTreeWidget::dropEvent(QDropEvent *event) +{ + if (mDropTargetProxyTi) + { + mDropTargetProxyTi->setBackground(0, mBackground); + mDropTargetProxyTi = 0; + } + + QTreeWidgetItem* underlyingItem = this->itemAt(event->pos()); + + UBDocumentGroupTreeItem *groupItem = dynamic_cast(underlyingItem); + + if (groupItem && mSelectedProxyTi && mSelectedProxyTi->proxy()) + { + UBDocumentGroupTreeItem *sourceGroupItem = dynamic_cast(mSelectedProxyTi->parent()); + bool isTrashItem = sourceGroupItem && sourceGroupItem->isTrashFolder(); + if ((isTrashItem && !groupItem->isTrashFolder()) || + (!isTrashItem && mSelectedProxyTi->proxy()->groupName() != groupItem->groupName())) + { + QString groupName; + if (groupItem->isTrashFolder()) + { + QString oldGroupName = mSelectedProxyTi->proxy()->metaData(UBSettings::documentGroupName).toString(); + groupName = UBSettings::trashedDocumentGroupNamePrefix + oldGroupName; + } + else + { + if (groupItem->groupName() == UBApplication::app()->documentController->defaultDocumentGroupName()) + groupName = ""; + else + groupName = groupItem->groupName(); + } + mSelectedProxyTi->proxy()->setMetaData(UBSettings::documentGroupName, groupName); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(mSelectedProxyTi->proxy()); + + mSelectedProxyTi->parent()->removeChild(mSelectedProxyTi); + + int i = 0; + for (i = 0; i < groupItem->childCount(); i++) + { + QTreeWidgetItem *ti = groupItem->child(i); + UBDocumentProxyTreeItem* pi = dynamic_cast(ti); + if (pi) + { + if (mSelectedProxyTi->proxy()->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) + { + break; + } + } + } + groupItem->insertChild(i, mSelectedProxyTi); + + if (isTrashItem) + mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() | Qt::ItemIsEditable); + + if (groupItem->isTrashFolder()) + mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() ^ Qt::ItemIsEditable); + + //clearSelection(); + expandItem(groupItem); + scrollToItem(mSelectedProxyTi); + + // disabled, as those 2 calls are buggy on windows, the item disappears if we selected them + // + setCurrentItem(mSelectedProxyTi); + mSelectedProxyTi->setSelected(true); + + event->setDropAction(Qt::IgnoreAction); + event->accept(); + } + } + else + { + QTreeWidgetItem* underlyingTreeItem = this->itemAt(event->pos()); + + UBDocumentProxyTreeItem *targetProxyTreeItem = dynamic_cast(underlyingTreeItem); + if (targetProxyTreeItem && targetProxyTreeItem != mSelectedProxyTi) + { + if (event->mimeData()->hasFormat(UBApplication::mimeTypeUniboardPage)) + { + event->setDropAction(Qt::CopyAction); + event->accept(); + + const UBMimeData *mimeData = qobject_cast (event->mimeData()); + + if (mimeData && mimeData->items().size() > 0) + { + int count = 0; + int total = mimeData->items().size(); + + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + foreach (UBMimeDataItem sourceItem, mimeData->items()) + { + count++; + + UBApplication::applicationController->showMessage(tr("Copying page %1/%2").arg(count).arg(total), true); + + // TODO UB 4.x Move following code to some controller class + UBGraphicsScene *scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(sourceItem.documentProxy(), sourceItem.sceneIndex()); + if (scene) + { + UBGraphicsScene* sceneClone = scene->sceneDeepCopy(); + + UBDocumentProxy *targetDocProxy = targetProxyTreeItem->proxy(); + + foreach (QUrl relativeFile, scene->relativeDependencies()) + { + QString source = scene->document()->persistencePath() + "/" + relativeFile.toString(); + QString target = targetDocProxy->persistencePath() + "/" + relativeFile.toString(); + + QFileInfo fi(target); + QDir d = fi.dir(); + + d.mkpath(d.absolutePath()); + QFile::copy(source, target); + } + + UBPersistenceManager::persistenceManager()->insertDocumentSceneAt(targetDocProxy, sceneClone, targetDocProxy->pageCount()); + + //due to incorrect generation of thumbnails of invisible scene I've used direct copying of thumbnail files + //it's not universal and good way but it's faster + QString from = sourceItem.documentProxy()->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", sourceItem.sceneIndex()); + QString to = targetDocProxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.thumbnail.jpg", targetDocProxy->pageCount()); + QFile::remove(to); + QFile::copy(from, to); + } + } + + QApplication::restoreOverrideCursor(); + + UBApplication::applicationController->showMessage(tr("%1 pages copied", "", total).arg(total), false); + } + } + else + { + event->setDropAction(Qt::IgnoreAction); + event->ignore(); + } + } + } +} + + +void UBDocumentTreeWidget::documentUpdated(UBDocumentProxy *pDocument) +{ + UBDocumentProxyTreeItem *treeItem = UBApplication::documentController->findDocument(pDocument); + if (treeItem) + { + QTreeWidgetItem * parent = treeItem->parent(); + + if (parent) + { + for (int i = 0; i < parent->indexOfChild(treeItem); i++) + { + QTreeWidgetItem *ti = parent->child(i); + UBDocumentProxyTreeItem* pi = dynamic_cast(ti); + if (pi) + { + if (pDocument->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) + { + bool selected = treeItem->isSelected(); + parent->removeChild(treeItem); + parent->insertChild(i, treeItem); + for (int j = 0; j < selectedItems().count(); j++) + selectedItems().at(j)->setSelected(false); + if (selected) + treeItem->setSelected(true); + break; + } + } + } + } + } +} + + +UBDocumentProxyTreeItem::UBDocumentProxyTreeItem(QTreeWidgetItem * parent, UBDocumentProxy* proxy, bool isEditable) + : QTreeWidgetItem() + , mProxy(proxy) +{ + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; + + if (isEditable) + flags |= Qt::ItemIsEditable; + + setFlags(flags); + + int i = 0; + for (i = 0; i < parent->childCount(); i++) + { + QTreeWidgetItem *ti = parent->child(i); + UBDocumentProxyTreeItem* pi = dynamic_cast(ti); + if (pi) + { + if (proxy->metaData(UBSettings::documentUpdatedAt).toString() >= pi->proxy()->metaData(UBSettings::documentUpdatedAt).toString()) + { + break; + } + } + } + parent->insertChild(i, this); +} + + +UBDocumentGroupTreeItem::UBDocumentGroupTreeItem(QTreeWidgetItem *parent, bool isEditable) + : QTreeWidgetItem(parent) +{ + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; + if (isEditable) + flags |= Qt::ItemIsEditable; + setFlags(flags); +} + + +UBDocumentGroupTreeItem::~UBDocumentGroupTreeItem() +{ + // NOOP +} + + +void UBDocumentGroupTreeItem::setGroupName(const QString& groupName) +{ + setText(0, groupName); +} + + +QString UBDocumentGroupTreeItem::groupName() const +{ + return text(0); +} + + +bool UBDocumentGroupTreeItem::isTrashFolder() const +{ + return (0 == (flags() & Qt::ItemIsEditable)) && UBApplication::app()->documentController && (groupName() == UBApplication::app()->documentController->documentTrashGroupName()); +} + +bool UBDocumentGroupTreeItem::isDefaultFolder() const +{ + return (0 == (flags() & Qt::ItemIsEditable)) && UBApplication::app()->documentController && (groupName() == UBApplication::app()->documentController->defaultDocumentGroupName()); +} + + +void UBDocumentTreeWidget::autoScroll() +{ + this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + mScrollMagnitude); +} diff --git a/src/gui/UBKeyboardPalette.cpp b/src/gui/UBKeyboardPalette.cpp index 44715121..fe8301bc 100644 --- a/src/gui/UBKeyboardPalette.cpp +++ b/src/gui/UBKeyboardPalette.cpp @@ -19,726 +19,726 @@ * along with Open-Sankoré. If not, see . */ - - -#include -#include -#include - -#include "UBKeyboardPalette.h" -#include "core/UBSettings.h" - -#include "core/UBApplication.h" -#include "gui/UBMainWindow.h" - -#include "core/memcheck.h" - -/* - - UBKeyboardPalette - -*/ - - -UBKeyboardPalette::UBKeyboardPalette(QWidget *parent) - : UBActionPalette(Qt::TopRightCorner, parent) -{ - - // setWindowFlags(/*Qt::CustomizeWindowHint|*/Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint); - - setCustomCloseProcessing(true); - setCustomPosition(true); - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - setFocusPolicy(Qt::NoFocus); - setClosable(true); - setGrip(false); - - capsLock = false; - shift = false; - languagePopupActive = false; - keyboardActive = false; - nSpecialModifierIndex = 0; - specialModifier = 0; - btnWidth = btnHeight = 16; - strSize = "16x16"; - currBtnImages = new BTNImages("16", btnWidth, btnHeight); - storage = NULL; - - - buttons = new UBKeyButton*[47]; - for (int i=0; i<47; i++) - { - buttons[i] = new UBKeyButton(this); - } - - locales = UBPlatformUtils::getKeyboardLayouts(this->nLocalesCount); - - createCtrlButtons(); - - nCurrentLocale = UBSettings::settings()->KeyboardLocale->get().toInt(); - if (nCurrentLocale < 0 || nCurrentLocale >= nLocalesCount) - nCurrentLocale = 0; - if (locales!=NULL) - setInput(locales[nCurrentLocale]); - - setContentsMargins( 22, 22, 22, 22 ); - - init(); -} - -//QList UBKeyboardPalette::instances; -void UBKeyboardPalette::init() -{ - m_isVisible = false; - setVisible(false); - - setKeyButtonSize(UBSettings::settings()->boardKeyboardPaletteKeyBtnSize->get().toString()); - - connect(this, SIGNAL(keyboardActivated(bool)), this, SLOT(onActivated(bool))); - connect(UBSettings::settings()->boardKeyboardPaletteKeyBtnSize, SIGNAL(changed(QVariant)), this, SLOT(keyboardPaletteButtonSizeChanged(QVariant))); - connect(UBApplication::mainWindow->actionVirtualKeyboard, SIGNAL(triggered(bool)), this, SLOT(showKeyboard(bool))); - connect(this, SIGNAL(closed()), this, SLOT(hideKeyboard())); - - //------------------------------// - - UBPlatformUtils::setWindowNonActivableFlag(this, true); -} - -void UBKeyboardPalette::showKeyboard(bool show) -{ - m_isVisible = show; -} - - -void UBKeyboardPalette::hideKeyboard() -{ - UBApplication::mainWindow->actionVirtualKeyboard->activate(QAction::Trigger); -} - -void UBKeyboardPalette::syncPosition(const QPoint & pos) -{ - m_pos = pos; - move(pos); -} - -void UBKeyboardPalette::syncLocale(int nLocale) -{ - nCurrentLocale = nLocale; - setInput(locales[nCurrentLocale]); -} - -void UBKeyboardPalette::keyboardPaletteButtonSizeChanged(QVariant size) -{ - setKeyButtonSize(size.toString()); -} - -void UBKeyboardPalette::setInput(const UBKeyboardLocale* locale) -{ - if (locale!=NULL) - { - for (int i=0; i<47; i++) - buttons[i]->setKeyBt((*locale)[i]); - } - else - { - this->hide(); - } -} - -UBKeyboardPalette::~UBKeyboardPalette() -{ - //for (int i=0; i<47; i++) - // delete buttons[i]; - delete [] buttons; - - //for (int i=0; i<8; i++) - // delete ctrlButtons[i]; - delete [] ctrlButtons; - - //if (locales!=NULL) - //{ - // for (int i=0; iname); -} - -void UBKeyboardPalette::setLocale(int nLocale) -{ - if (locales != NULL) - { - nCurrentLocale = nLocale; - - setInput(locales[nCurrentLocale]); - onLocaleChanged(locales[nCurrentLocale]); - update(); - - UBSettings::settings()->KeyboardLocale->set(nCurrentLocale); - } - emit localeChanged(nLocale); -} - -void UBKeyboardPalette::setKeyButtonSize(const QString& _strSize) -{ - QStringList strs = _strSize.split('x'); - - if (strs.size()==2) - { - strSize = _strSize; - btnWidth = strs[0].toInt(); - btnHeight = strs[1].toInt(); - - if(currBtnImages != NULL) - delete currBtnImages; - currBtnImages = new BTNImages(strs[1], btnWidth, btnHeight); - - adjustSizeAndPosition(); - } -} - -void UBKeyboardPalette::enterEvent ( QEvent * ) -{ - if (keyboardActive) - return; - - keyboardActive = true; - - adjustSizeAndPosition(); - - emit keyboardActivated(true); -} - -void UBKeyboardPalette::leaveEvent ( QEvent * ) -{ - if (languagePopupActive || !keyboardActive || mIsMoving) - return; - - keyboardActive = false; - - adjustSizeAndPosition(); - - emit keyboardActivated(false); -} - -void UBKeyboardPalette::moveEvent ( QMoveEvent * event ) -{ - UBActionPalette::moveEvent(event); - emit moved(event->pos()); -} - -void UBKeyboardPalette::adjustSizeAndPosition(bool pUp) -{ - QSize rSize = sizeHint(); - if (rSize != size()) - { - int dx = (rSize.width() - size().width()) /2; - int dy = rSize.height() - size().height(); - - this->move(x()-dx, y() - dy); - this->resize(rSize.width(), rSize.height()); - } - UBActionPalette::adjustSizeAndPosition(pUp); -} - -void UBKeyboardPalette::paintEvent( QPaintEvent* event) -{ - checkLayout(); - - UBActionPalette::paintEvent(event); - - QRect r = this->geometry(); - - int lleft, ltop, lright, lbottom; - getContentsMargins ( &lleft, <op, &lright, &lbottom ) ; - - //------------------------------------------------ - // calculate start offset from left, and from top - - int ctrlButtonsId = 0; - lleft = ( r.width() - btnWidth * 15 ) / 2; - ltop = ( r.height() - btnHeight * 5 ) / 2; - - //------------------------------------------------ - // set geometry (position) for row 1 - - int offX = lleft; - int offY = ltop; - - //------------------- - - // buttons [`]..[+] - for (int i = 0; i<13; i++) - { - buttons[i]->setGeometry(offX, offY, btnWidth, btnHeight); - offX += btnWidth; - } - - // button Backspace - ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 2, btnHeight); - offX += btnWidth * 2; - - //------------------------------------------------ - // set geometry (position) for row 2 - - offX = lleft; - offY += btnHeight; - offX += btnWidth / 2; - - //------------------- - - // button Tab - ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 2, btnHeight); - offX += btnWidth * 2; - - // buttons [q]..[]] - for (int i = 0; i<12; i++) - { - buttons[i + 13]->setGeometry(offX, offY, btnWidth, btnHeight); - offX += btnWidth; - } - -// // Row 2 Stub -// ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 1.5, btnHeight); -// offX += btnWidth * 1.5; - - //------------------------------------------------ - // set geometry (position) for row 3 - - offX = lleft; - offY += btnHeight; - - //------------------- - -// // Row 3 Stub - - // button Enter - ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 1, btnHeight); - offX += btnWidth*1; - - // buttons [a]..[\] - for (int i = 0; i < 12; i++) - { - buttons[i + 12 + 13]->setGeometry(offX, offY, btnWidth, btnHeight); - offX += btnWidth; - } - - // button Enter - ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 2, btnHeight); - offX += btnWidth*2; - - //------------------------------------------------ - // set geometry (position) for row 4 - - offX = lleft; - offY += btnHeight; - - //------------------- - - // button LCapsLock - ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth*2.5, btnHeight); - offX += btnWidth*2.5; - - for (int i = 0; i < 10; i++) - { - buttons[i + 12 + 12 + 13]->setGeometry(offX, offY, btnWidth, btnHeight); - offX += btnWidth; - } - - // button RCapsLock - ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth*2.5, btnHeight); - offX += btnWidth*2.5; - - //------------------------------------------------ - // set geometry (position) for row 5 - - offX = lleft; - offY += btnHeight; - - //------------------- - - ctrlButtons[ctrlButtonsId++]->setGeometry(offX + btnWidth * 1 , offY, btnWidth * 2, btnHeight); - ctrlButtons[ctrlButtonsId++]->setGeometry(offX + btnWidth * 3 , offY, btnWidth * 9, btnHeight); - ctrlButtons[ctrlButtonsId++]->setGeometry(offX + btnWidth * 12, offY, btnWidth * 2, btnHeight); - - //------------------------------------------------ -} - -void UBKeyboardPalette::onDeactivated() -{ - onActivated(false); -} - - -//-----------------------------------------------------------------------// -// BTNImages Class -//-----------------------------------------------------------------------// - -BTNImages::BTNImages(QString strHeight, int width, int height) -{ - m_strHeight = strHeight; - m_width = width; - m_height = height; - - m_strLeftPassive = ":/images/virtual.keyboard/" + strHeight + "/left-passive.png"; - m_strCenterPassive = ":/images/virtual.keyboard/" + strHeight + "/centre-passive.png"; - m_strRightPassive = ":/images/virtual.keyboard/" + strHeight + "/right-passive.png"; - m_strLeftActive = ":/images/virtual.keyboard/" + strHeight + "/left-active.png"; - m_strCenterActive = ":/images/virtual.keyboard/" + strHeight + "/centre-active.png"; - m_strRightActive = ":/images/virtual.keyboard/" + strHeight + "/right-active.png"; - - m_btnLeftPassive = QImage(m_strLeftPassive); - m_btnCenterPassive = QImage(m_strCenterPassive); - m_btnRightPassive = QImage(m_strRightPassive); - m_btnLeftActive = QImage(m_strLeftActive); - m_btnCenterActive = QImage(m_strCenterActive); - m_btnRightActive = QImage(m_strRightActive); -} - -ContentImage::ContentImage(QString strHeight, int height, QString strContentName) -{ - m_strHeight = strHeight; - m_height = height; - - m_strContent = ":/images/virtual.keyboard/" + strHeight + "/" + strContentName + ".png"; - m_btnContent = QImage(m_strContent); -} - -//-----------------------------------------------------------------------// -// UBKeyboardButton Class -//-----------------------------------------------------------------------// - -UBKeyboardButton::UBKeyboardButton(UBKeyboardPalette* parent, QString contentImagePath = "") - :QWidget(parent), - keyboard(parent), - bFocused(false), - bPressed(false) -{ - m_parent = parent; - - m_contentImagePath = contentImagePath; - imgContent = NULL; - - setCursor(Qt::PointingHandCursor); -} - -UBKeyboardButton::~UBKeyboardButton() -{ - if(imgContent != NULL) - { - delete imgContent; - imgContent = NULL; - } -} - -bool UBKeyboardButton::isPressed() -{ - return bPressed; -} - -void UBKeyboardButton::paintEvent(QPaintEvent*) -{ - - QPainter painter(this); - - //-------------------------- - - if(imgContent != NULL) - { - if(imgContent->m_height != m_parent->currBtnImages->m_height) - { - delete imgContent; - if(!m_contentImagePath.isEmpty()) - imgContent = new ContentImage(m_parent->currBtnImages->m_strHeight, m_parent->currBtnImages->m_height, m_contentImagePath); - } - } - else - if(!m_contentImagePath.isEmpty()) - imgContent = new ContentImage(m_parent->currBtnImages->m_strHeight, m_parent->currBtnImages->m_height, m_contentImagePath); - - //-------------------------- - - if (isPressed()) - { - painter.drawImage( 0,0, m_parent->currBtnImages->m_btnLeftActive, 0,0, m_parent->currBtnImages->m_btnLeftActive.width(), m_parent->currBtnImages->m_btnLeftActive.height() ); - painter.drawImage( QRect(m_parent->currBtnImages->m_btnLeftActive.width(), 0, width() - m_parent->currBtnImages->m_btnLeftActive.width() - m_parent->currBtnImages->m_btnRightActive.width(), height()), m_parent->currBtnImages->m_btnCenterActive ); - painter.drawImage( width() - m_parent->currBtnImages->m_btnRightActive.width(), 0, m_parent->currBtnImages->m_btnRightActive, 0,0, m_parent->currBtnImages->m_btnRightActive.width(), m_parent->currBtnImages->m_btnRightActive.height() ); - } - else - { - painter.drawImage( 0,0, m_parent->currBtnImages->m_btnLeftPassive, 0,0, m_parent->currBtnImages->m_btnLeftPassive.width(), m_parent->currBtnImages->m_btnLeftPassive.height() ); - painter.drawImage( QRect(m_parent->currBtnImages->m_btnLeftPassive.width(), 0, width() - m_parent->currBtnImages->m_btnLeftPassive.width() - m_parent->currBtnImages->m_btnRightPassive.width(), height()), m_parent->currBtnImages->m_btnCenterPassive ); - painter.drawImage( width() - m_parent->currBtnImages->m_btnRightPassive.width(), 0, m_parent->currBtnImages->m_btnRightPassive, 0,0, m_parent->currBtnImages->m_btnRightPassive.width(), m_parent->currBtnImages->m_btnRightPassive.height() ); - } - - //-------------------------- - - this->paintContent(painter); - - //-------------------------- -} - -void UBKeyboardButton::enterEvent ( QEvent*) -{ - bFocused = true; - update(); -} - -void UBKeyboardButton::leaveEvent ( QEvent*) -{ - bFocused = false; - update(); -} - -void UBKeyboardButton::mousePressEvent ( QMouseEvent * event) -{ - event->accept(); - bPressed = true; - update(); - this->onPress(); -} - -void UBKeyboardButton::mouseReleaseEvent ( QMouseEvent * ) -{ - bPressed = false; - update(); - this->onRelease(); -} - -UBKeyButton::UBKeyButton(UBKeyboardPalette* parent) - :UBKeyboardButton(parent), - keybt(0) -{} - -UBKeyButton::~UBKeyButton() -{} - -bool UBKeyButton::shifted() -{ - bool b = keyboard->shift; - if (keybt->capsLockSwitch && keyboard->capsLock) - b = !b; - return b; -} - -void UBKeyButton::onPress() -{ - if (keybt!=NULL) - { - int codeIndex = keyboard->nSpecialModifierIndex * 2 + shifted(); - - if (keyboard->nSpecialModifierIndex) - { - if (keybt->codes[codeIndex].empty()) - { - sendUnicodeSymbol(keyboard->specialModifier); - sendUnicodeSymbol(keybt->codes[shifted()]); - } - else - { - sendUnicodeSymbol(keybt->codes[codeIndex]); - } - - keyboard->nSpecialModifierIndex = 0; - } - else - { - int nSpecialModifierIndex = shifted()? keybt->modifier2 : keybt->modifier1; - - if (nSpecialModifierIndex) - { - keyboard->nSpecialModifierIndex = nSpecialModifierIndex; - keyboard->specialModifier = keybt->codes[codeIndex]; - } - else - { - sendUnicodeSymbol(keybt->codes[codeIndex]); - } - } - } - - if (keyboard->shift) - { - keyboard->shift = false; - keyboard->update(); - } -} - -void UBKeyButton::onRelease() -{} - -void UBKeyButton::paintContent(QPainter& painter) -{ - if (keybt) - { - QString text(QChar(shifted() ? keybt->symbol2 : keybt->symbol1)); - QRect textRect(rect().x()+2, rect().y()+2, rect().width()-4, rect().height()-4); - painter.drawText(textRect, Qt::AlignCenter, text); - } -} - -UBCntrlButton::UBCntrlButton(UBKeyboardPalette* parent, int _code, const QString& _contentImagePath ) - :UBKeyboardButton(parent, _contentImagePath), - label(""), - code(_code) -{} - - -UBCntrlButton::UBCntrlButton(UBKeyboardPalette* parent, const QString& _label, int _code ) - :UBKeyboardButton(parent), - label(_label), - code(_code) -{} - -UBCntrlButton::~UBCntrlButton() -{} - -void UBCntrlButton::onPress() -{ - sendControlSymbol(code); -} - -void UBCntrlButton::onRelease() -{} - -void UBCntrlButton::paintContent(QPainter& painter) -{ - if(!label.isEmpty()) - { - painter.drawText(rect(), Qt::AlignCenter, label); - } - else - if(imgContent != NULL) - { - painter.drawImage(( rect().width() - imgContent->m_btnContent.width() ) / 2, ( rect().height() - imgContent->m_btnContent.height() ) / 2, - imgContent->m_btnContent, 0,0, imgContent->m_btnContent.width(), imgContent->m_btnContent.height()); - } -} - -UBCapsLockButton::UBCapsLockButton(UBKeyboardPalette* parent, const QString _contentImagePath) - :UBKeyboardButton(parent, _contentImagePath) -{} - -UBCapsLockButton::~UBCapsLockButton() -{} - -void UBCapsLockButton::onPress() -{ - keyboard->capsLock = !keyboard->capsLock; - keyboard->update(); -} - -void UBCapsLockButton::onRelease() -{} - -bool UBCapsLockButton::isPressed() -{ - return keyboard->capsLock; -} - -void UBCapsLockButton::paintContent(QPainter& painter) -{ - if(imgContent != NULL) - { - painter.drawImage(( rect().width() - imgContent->m_btnContent.width() ) / 2, ( rect().height() - imgContent->m_btnContent.height() ) / 2, - imgContent->m_btnContent, 0,0, imgContent->m_btnContent.width(), imgContent->m_btnContent.height()); - } - else - painter.drawText(rect(), Qt::AlignCenter, "^"); -} - -UBShiftButton::UBShiftButton(UBKeyboardPalette* parent, const QString _contentImagePath) - :UBKeyboardButton(parent, _contentImagePath) -{} - -UBShiftButton::~UBShiftButton() -{} - -void UBShiftButton::onPress() -{ - keyboard->shift = !keyboard->shift; - keyboard->update(); -} - - -void UBShiftButton::onRelease() -{} - -bool UBShiftButton::isPressed() -{ - return keyboard->shift; -} - -void UBShiftButton::paintContent(QPainter& painter) -{ - if(imgContent != NULL) - { - painter.drawImage(( rect().width() - imgContent->m_btnContent.width() ) / 2, ( rect().height() - imgContent->m_btnContent.height() ) / 2, - imgContent->m_btnContent, 0,0, imgContent->m_btnContent.width(), imgContent->m_btnContent.height()); - } - else - painter.drawText(rect(), Qt::AlignCenter, "^"); -} - - - -UBLocaleButton::UBLocaleButton(UBKeyboardPalette* parent) - :UBKeyboardButton(parent) -{ - localeMenu = new QMenu(this); - - for (int i=0; inLocalesCount; i++) - { - QAction* action = (parent->locales[i]->icon!=NULL) ? - localeMenu->addAction(*parent->locales[i]->icon, parent->locales[i]->fullName) - : localeMenu->addAction(parent->locales[i]->fullName); - action->setData(QVariant(i)); - } -} - -UBLocaleButton::~UBLocaleButton() -{ - delete localeMenu; -} - -void UBLocaleButton::onPress() -{ -} - -void UBLocaleButton::onRelease() -{ - keyboard->languagePopupActive = true; - QAction* action = localeMenu->exec(mapToGlobal(QPoint(0,0))); - keyboard->languagePopupActive = false; - if (action!=NULL) - { - int nLocale = action->data().toInt(); - keyboard->setLocale(nLocale); - } -} - -void UBLocaleButton::paintContent(QPainter& painter) -{ - const QString* localeName = keyboard->getLocaleName(); - if (localeName!=NULL) - painter.drawText(rect(), Qt::AlignCenter, *localeName); -} + + +#include +#include +#include + +#include "UBKeyboardPalette.h" +#include "core/UBSettings.h" + +#include "core/UBApplication.h" +#include "gui/UBMainWindow.h" + +#include "core/memcheck.h" + +/* + + UBKeyboardPalette + +*/ + + +UBKeyboardPalette::UBKeyboardPalette(QWidget *parent) + : UBActionPalette(Qt::TopRightCorner, parent) +{ + + // setWindowFlags(/*Qt::CustomizeWindowHint|*/Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint); + + setCustomCloseProcessing(true); + setCustomPosition(true); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + setFocusPolicy(Qt::NoFocus); + setClosable(true); + setGrip(false); + + capsLock = false; + shift = false; + languagePopupActive = false; + keyboardActive = false; + nSpecialModifierIndex = 0; + specialModifier = 0; + btnWidth = btnHeight = 16; + strSize = "16x16"; + currBtnImages = new BTNImages("16", btnWidth, btnHeight); + storage = NULL; + + + buttons = new UBKeyButton*[47]; + for (int i=0; i<47; i++) + { + buttons[i] = new UBKeyButton(this); + } + + locales = UBPlatformUtils::getKeyboardLayouts(this->nLocalesCount); + + createCtrlButtons(); + + nCurrentLocale = UBSettings::settings()->KeyboardLocale->get().toInt(); + if (nCurrentLocale < 0 || nCurrentLocale >= nLocalesCount) + nCurrentLocale = 0; + if (locales!=NULL) + setInput(locales[nCurrentLocale]); + + setContentsMargins( 22, 22, 22, 22 ); + + init(); +} + +//QList UBKeyboardPalette::instances; +void UBKeyboardPalette::init() +{ + m_isVisible = false; + setVisible(false); + + setKeyButtonSize(UBSettings::settings()->boardKeyboardPaletteKeyBtnSize->get().toString()); + + connect(this, SIGNAL(keyboardActivated(bool)), this, SLOT(onActivated(bool))); + connect(UBSettings::settings()->boardKeyboardPaletteKeyBtnSize, SIGNAL(changed(QVariant)), this, SLOT(keyboardPaletteButtonSizeChanged(QVariant))); + connect(UBApplication::mainWindow->actionVirtualKeyboard, SIGNAL(triggered(bool)), this, SLOT(showKeyboard(bool))); + connect(this, SIGNAL(closed()), this, SLOT(hideKeyboard())); + + //------------------------------// + + UBPlatformUtils::setWindowNonActivableFlag(this, true); +} + +void UBKeyboardPalette::showKeyboard(bool show) +{ + m_isVisible = show; +} + + +void UBKeyboardPalette::hideKeyboard() +{ + UBApplication::mainWindow->actionVirtualKeyboard->activate(QAction::Trigger); +} + +void UBKeyboardPalette::syncPosition(const QPoint & pos) +{ + m_pos = pos; + move(pos); +} + +void UBKeyboardPalette::syncLocale(int nLocale) +{ + nCurrentLocale = nLocale; + setInput(locales[nCurrentLocale]); +} + +void UBKeyboardPalette::keyboardPaletteButtonSizeChanged(QVariant size) +{ + setKeyButtonSize(size.toString()); +} + +void UBKeyboardPalette::setInput(const UBKeyboardLocale* locale) +{ + if (locale!=NULL) + { + for (int i=0; i<47; i++) + buttons[i]->setKeyBt((*locale)[i]); + } + else + { + this->hide(); + } +} + +UBKeyboardPalette::~UBKeyboardPalette() +{ + //for (int i=0; i<47; i++) + // delete buttons[i]; + delete [] buttons; + + //for (int i=0; i<8; i++) + // delete ctrlButtons[i]; + delete [] ctrlButtons; + + //if (locales!=NULL) + //{ + // for (int i=0; iname); +} + +void UBKeyboardPalette::setLocale(int nLocale) +{ + if (locales != NULL) + { + nCurrentLocale = nLocale; + + setInput(locales[nCurrentLocale]); + onLocaleChanged(locales[nCurrentLocale]); + update(); + + UBSettings::settings()->KeyboardLocale->set(nCurrentLocale); + } + emit localeChanged(nLocale); +} + +void UBKeyboardPalette::setKeyButtonSize(const QString& _strSize) +{ + QStringList strs = _strSize.split('x'); + + if (strs.size()==2) + { + strSize = _strSize; + btnWidth = strs[0].toInt(); + btnHeight = strs[1].toInt(); + + if(currBtnImages != NULL) + delete currBtnImages; + currBtnImages = new BTNImages(strs[1], btnWidth, btnHeight); + + adjustSizeAndPosition(); + } +} + +void UBKeyboardPalette::enterEvent ( QEvent * ) +{ + if (keyboardActive) + return; + + keyboardActive = true; + + adjustSizeAndPosition(); + + emit keyboardActivated(true); +} + +void UBKeyboardPalette::leaveEvent ( QEvent * ) +{ + if (languagePopupActive || !keyboardActive || mIsMoving) + return; + + keyboardActive = false; + + adjustSizeAndPosition(); + + emit keyboardActivated(false); +} + +void UBKeyboardPalette::moveEvent ( QMoveEvent * event ) +{ + UBActionPalette::moveEvent(event); + emit moved(event->pos()); +} + +void UBKeyboardPalette::adjustSizeAndPosition(bool pUp) +{ + QSize rSize = sizeHint(); + if (rSize != size()) + { + int dx = (rSize.width() - size().width()) /2; + int dy = rSize.height() - size().height(); + + this->move(x()-dx, y() - dy); + this->resize(rSize.width(), rSize.height()); + } + UBActionPalette::adjustSizeAndPosition(pUp); +} + +void UBKeyboardPalette::paintEvent( QPaintEvent* event) +{ + checkLayout(); + + UBActionPalette::paintEvent(event); + + QRect r = this->geometry(); + + int lleft, ltop, lright, lbottom; + getContentsMargins ( &lleft, <op, &lright, &lbottom ) ; + + //------------------------------------------------ + // calculate start offset from left, and from top + + int ctrlButtonsId = 0; + lleft = ( r.width() - btnWidth * 15 ) / 2; + ltop = ( r.height() - btnHeight * 5 ) / 2; + + //------------------------------------------------ + // set geometry (position) for row 1 + + int offX = lleft; + int offY = ltop; + + //------------------- + + // buttons [`]..[+] + for (int i = 0; i<13; i++) + { + buttons[i]->setGeometry(offX, offY, btnWidth, btnHeight); + offX += btnWidth; + } + + // button Backspace + ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 2, btnHeight); + offX += btnWidth * 2; + + //------------------------------------------------ + // set geometry (position) for row 2 + + offX = lleft; + offY += btnHeight; + offX += btnWidth / 2; + + //------------------- + + // button Tab + ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 2, btnHeight); + offX += btnWidth * 2; + + // buttons [q]..[]] + for (int i = 0; i<12; i++) + { + buttons[i + 13]->setGeometry(offX, offY, btnWidth, btnHeight); + offX += btnWidth; + } + +// // Row 2 Stub +// ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 1.5, btnHeight); +// offX += btnWidth * 1.5; + + //------------------------------------------------ + // set geometry (position) for row 3 + + offX = lleft; + offY += btnHeight; + + //------------------- + +// // Row 3 Stub + + // button Enter + ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 1, btnHeight); + offX += btnWidth*1; + + // buttons [a]..[\] + for (int i = 0; i < 12; i++) + { + buttons[i + 12 + 13]->setGeometry(offX, offY, btnWidth, btnHeight); + offX += btnWidth; + } + + // button Enter + ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth * 2, btnHeight); + offX += btnWidth*2; + + //------------------------------------------------ + // set geometry (position) for row 4 + + offX = lleft; + offY += btnHeight; + + //------------------- + + // button LCapsLock + ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth*2.5, btnHeight); + offX += btnWidth*2.5; + + for (int i = 0; i < 10; i++) + { + buttons[i + 12 + 12 + 13]->setGeometry(offX, offY, btnWidth, btnHeight); + offX += btnWidth; + } + + // button RCapsLock + ctrlButtons[ctrlButtonsId++]->setGeometry(offX, offY, btnWidth*2.5, btnHeight); + offX += btnWidth*2.5; + + //------------------------------------------------ + // set geometry (position) for row 5 + + offX = lleft; + offY += btnHeight; + + //------------------- + + ctrlButtons[ctrlButtonsId++]->setGeometry(offX + btnWidth * 1 , offY, btnWidth * 2, btnHeight); + ctrlButtons[ctrlButtonsId++]->setGeometry(offX + btnWidth * 3 , offY, btnWidth * 9, btnHeight); + ctrlButtons[ctrlButtonsId++]->setGeometry(offX + btnWidth * 12, offY, btnWidth * 2, btnHeight); + + //------------------------------------------------ +} + +void UBKeyboardPalette::onDeactivated() +{ + onActivated(false); +} + + +//-----------------------------------------------------------------------// +// BTNImages Class +//-----------------------------------------------------------------------// + +BTNImages::BTNImages(QString strHeight, int width, int height) +{ + m_strHeight = strHeight; + m_width = width; + m_height = height; + + m_strLeftPassive = ":/images/virtual.keyboard/" + strHeight + "/left-passive.png"; + m_strCenterPassive = ":/images/virtual.keyboard/" + strHeight + "/centre-passive.png"; + m_strRightPassive = ":/images/virtual.keyboard/" + strHeight + "/right-passive.png"; + m_strLeftActive = ":/images/virtual.keyboard/" + strHeight + "/left-active.png"; + m_strCenterActive = ":/images/virtual.keyboard/" + strHeight + "/centre-active.png"; + m_strRightActive = ":/images/virtual.keyboard/" + strHeight + "/right-active.png"; + + m_btnLeftPassive = QImage(m_strLeftPassive); + m_btnCenterPassive = QImage(m_strCenterPassive); + m_btnRightPassive = QImage(m_strRightPassive); + m_btnLeftActive = QImage(m_strLeftActive); + m_btnCenterActive = QImage(m_strCenterActive); + m_btnRightActive = QImage(m_strRightActive); +} + +ContentImage::ContentImage(QString strHeight, int height, QString strContentName) +{ + m_strHeight = strHeight; + m_height = height; + + m_strContent = ":/images/virtual.keyboard/" + strHeight + "/" + strContentName + ".png"; + m_btnContent = QImage(m_strContent); +} + +//-----------------------------------------------------------------------// +// UBKeyboardButton Class +//-----------------------------------------------------------------------// + +UBKeyboardButton::UBKeyboardButton(UBKeyboardPalette* parent, QString contentImagePath = "") + :QWidget(parent), + keyboard(parent), + bFocused(false), + bPressed(false) +{ + m_parent = parent; + + m_contentImagePath = contentImagePath; + imgContent = NULL; + + setCursor(Qt::PointingHandCursor); +} + +UBKeyboardButton::~UBKeyboardButton() +{ + if(imgContent != NULL) + { + delete imgContent; + imgContent = NULL; + } +} + +bool UBKeyboardButton::isPressed() +{ + return bPressed; +} + +void UBKeyboardButton::paintEvent(QPaintEvent*) +{ + + QPainter painter(this); + + //-------------------------- + + if(imgContent != NULL) + { + if(imgContent->m_height != m_parent->currBtnImages->m_height) + { + delete imgContent; + if(!m_contentImagePath.isEmpty()) + imgContent = new ContentImage(m_parent->currBtnImages->m_strHeight, m_parent->currBtnImages->m_height, m_contentImagePath); + } + } + else + if(!m_contentImagePath.isEmpty()) + imgContent = new ContentImage(m_parent->currBtnImages->m_strHeight, m_parent->currBtnImages->m_height, m_contentImagePath); + + //-------------------------- + + if (isPressed()) + { + painter.drawImage( 0,0, m_parent->currBtnImages->m_btnLeftActive, 0,0, m_parent->currBtnImages->m_btnLeftActive.width(), m_parent->currBtnImages->m_btnLeftActive.height() ); + painter.drawImage( QRect(m_parent->currBtnImages->m_btnLeftActive.width(), 0, width() - m_parent->currBtnImages->m_btnLeftActive.width() - m_parent->currBtnImages->m_btnRightActive.width(), height()), m_parent->currBtnImages->m_btnCenterActive ); + painter.drawImage( width() - m_parent->currBtnImages->m_btnRightActive.width(), 0, m_parent->currBtnImages->m_btnRightActive, 0,0, m_parent->currBtnImages->m_btnRightActive.width(), m_parent->currBtnImages->m_btnRightActive.height() ); + } + else + { + painter.drawImage( 0,0, m_parent->currBtnImages->m_btnLeftPassive, 0,0, m_parent->currBtnImages->m_btnLeftPassive.width(), m_parent->currBtnImages->m_btnLeftPassive.height() ); + painter.drawImage( QRect(m_parent->currBtnImages->m_btnLeftPassive.width(), 0, width() - m_parent->currBtnImages->m_btnLeftPassive.width() - m_parent->currBtnImages->m_btnRightPassive.width(), height()), m_parent->currBtnImages->m_btnCenterPassive ); + painter.drawImage( width() - m_parent->currBtnImages->m_btnRightPassive.width(), 0, m_parent->currBtnImages->m_btnRightPassive, 0,0, m_parent->currBtnImages->m_btnRightPassive.width(), m_parent->currBtnImages->m_btnRightPassive.height() ); + } + + //-------------------------- + + this->paintContent(painter); + + //-------------------------- +} + +void UBKeyboardButton::enterEvent ( QEvent*) +{ + bFocused = true; + update(); +} + +void UBKeyboardButton::leaveEvent ( QEvent*) +{ + bFocused = false; + update(); +} + +void UBKeyboardButton::mousePressEvent ( QMouseEvent * event) +{ + event->accept(); + bPressed = true; + update(); + this->onPress(); +} + +void UBKeyboardButton::mouseReleaseEvent ( QMouseEvent * ) +{ + bPressed = false; + update(); + this->onRelease(); +} + +UBKeyButton::UBKeyButton(UBKeyboardPalette* parent) + :UBKeyboardButton(parent), + keybt(0) +{} + +UBKeyButton::~UBKeyButton() +{} + +bool UBKeyButton::shifted() +{ + bool b = keyboard->shift; + if (keybt->capsLockSwitch && keyboard->capsLock) + b = !b; + return b; +} + +void UBKeyButton::onPress() +{ + if (keybt!=NULL) + { + int codeIndex = keyboard->nSpecialModifierIndex * 2 + shifted(); + + if (keyboard->nSpecialModifierIndex) + { + if (keybt->codes[codeIndex].empty()) + { + sendUnicodeSymbol(keyboard->specialModifier); + sendUnicodeSymbol(keybt->codes[shifted()]); + } + else + { + sendUnicodeSymbol(keybt->codes[codeIndex]); + } + + keyboard->nSpecialModifierIndex = 0; + } + else + { + int nSpecialModifierIndex = shifted()? keybt->modifier2 : keybt->modifier1; + + if (nSpecialModifierIndex) + { + keyboard->nSpecialModifierIndex = nSpecialModifierIndex; + keyboard->specialModifier = keybt->codes[codeIndex]; + } + else + { + sendUnicodeSymbol(keybt->codes[codeIndex]); + } + } + } + + if (keyboard->shift) + { + keyboard->shift = false; + keyboard->update(); + } +} + +void UBKeyButton::onRelease() +{} + +void UBKeyButton::paintContent(QPainter& painter) +{ + if (keybt) + { + QString text(QChar(shifted() ? keybt->symbol2 : keybt->symbol1)); + QRect textRect(rect().x()+2, rect().y()+2, rect().width()-4, rect().height()-4); + painter.drawText(textRect, Qt::AlignCenter, text); + } +} + +UBCntrlButton::UBCntrlButton(UBKeyboardPalette* parent, int _code, const QString& _contentImagePath ) + :UBKeyboardButton(parent, _contentImagePath), + label(""), + code(_code) +{} + + +UBCntrlButton::UBCntrlButton(UBKeyboardPalette* parent, const QString& _label, int _code ) + :UBKeyboardButton(parent), + label(_label), + code(_code) +{} + +UBCntrlButton::~UBCntrlButton() +{} + +void UBCntrlButton::onPress() +{ + sendControlSymbol(code); +} + +void UBCntrlButton::onRelease() +{} + +void UBCntrlButton::paintContent(QPainter& painter) +{ + if(!label.isEmpty()) + { + painter.drawText(rect(), Qt::AlignCenter, label); + } + else + if(imgContent != NULL) + { + painter.drawImage(( rect().width() - imgContent->m_btnContent.width() ) / 2, ( rect().height() - imgContent->m_btnContent.height() ) / 2, + imgContent->m_btnContent, 0,0, imgContent->m_btnContent.width(), imgContent->m_btnContent.height()); + } +} + +UBCapsLockButton::UBCapsLockButton(UBKeyboardPalette* parent, const QString _contentImagePath) + :UBKeyboardButton(parent, _contentImagePath) +{} + +UBCapsLockButton::~UBCapsLockButton() +{} + +void UBCapsLockButton::onPress() +{ + keyboard->capsLock = !keyboard->capsLock; + keyboard->update(); +} + +void UBCapsLockButton::onRelease() +{} + +bool UBCapsLockButton::isPressed() +{ + return keyboard->capsLock; +} + +void UBCapsLockButton::paintContent(QPainter& painter) +{ + if(imgContent != NULL) + { + painter.drawImage(( rect().width() - imgContent->m_btnContent.width() ) / 2, ( rect().height() - imgContent->m_btnContent.height() ) / 2, + imgContent->m_btnContent, 0,0, imgContent->m_btnContent.width(), imgContent->m_btnContent.height()); + } + else + painter.drawText(rect(), Qt::AlignCenter, "^"); +} + +UBShiftButton::UBShiftButton(UBKeyboardPalette* parent, const QString _contentImagePath) + :UBKeyboardButton(parent, _contentImagePath) +{} + +UBShiftButton::~UBShiftButton() +{} + +void UBShiftButton::onPress() +{ + keyboard->shift = !keyboard->shift; + keyboard->update(); +} + + +void UBShiftButton::onRelease() +{} + +bool UBShiftButton::isPressed() +{ + return keyboard->shift; +} + +void UBShiftButton::paintContent(QPainter& painter) +{ + if(imgContent != NULL) + { + painter.drawImage(( rect().width() - imgContent->m_btnContent.width() ) / 2, ( rect().height() - imgContent->m_btnContent.height() ) / 2, + imgContent->m_btnContent, 0,0, imgContent->m_btnContent.width(), imgContent->m_btnContent.height()); + } + else + painter.drawText(rect(), Qt::AlignCenter, "^"); +} + + + +UBLocaleButton::UBLocaleButton(UBKeyboardPalette* parent) + :UBKeyboardButton(parent) +{ + localeMenu = new QMenu(this); + + for (int i=0; inLocalesCount; i++) + { + QAction* action = (parent->locales[i]->icon!=NULL) ? + localeMenu->addAction(*parent->locales[i]->icon, parent->locales[i]->fullName) + : localeMenu->addAction(parent->locales[i]->fullName); + action->setData(QVariant(i)); + } +} + +UBLocaleButton::~UBLocaleButton() +{ + delete localeMenu; +} + +void UBLocaleButton::onPress() +{ +} + +void UBLocaleButton::onRelease() +{ + keyboard->languagePopupActive = true; + QAction* action = localeMenu->exec(mapToGlobal(QPoint(0,0))); + keyboard->languagePopupActive = false; + if (action!=NULL) + { + int nLocale = action->data().toInt(); + keyboard->setLocale(nLocale); + } +} + +void UBLocaleButton::paintContent(QPainter& painter) +{ + const QString* localeName = keyboard->getLocaleName(); + if (localeName!=NULL) + painter.drawText(rect(), Qt::AlignCenter, *localeName); +} diff --git a/src/gui/UBKeyboardPalette.h b/src/gui/UBKeyboardPalette.h index aeb2d631..1b5d59b9 100644 --- a/src/gui/UBKeyboardPalette.h +++ b/src/gui/UBKeyboardPalette.h @@ -19,284 +19,284 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBKEYBOARDPALETTE_H -#define UBKEYBOARDPALETTE_H - -#include "UBActionPalette.h" - -#include -#include -#include -#include - -#include "frameworks/UBPlatformUtils.h" - -class UBKeyButton; -class UBKeyboardButton; - -class UBApplication; -class UBMainWindow; - -class BTNImages -{ -public: - - BTNImages(QString _strHeight, int _width, int _height); - - QString m_strHeight; - int m_width; - int m_height; - - QImage m_btnLeftPassive; - QImage m_btnCenterPassive; - QImage m_btnRightPassive; - QImage m_btnLeftActive; - QImage m_btnCenterActive; - QImage m_btnRightActive; - -private: - QString m_strLeftPassive; - QString m_strCenterPassive; - QString m_strRightPassive; - QString m_strLeftActive; - QString m_strCenterActive; - QString m_strRightActive; - -}; - -class ContentImage -{ -public: - - ContentImage(QString strHeight, int m_height, QString strContentPath); - - QString m_strHeight; - int m_height; - - QImage m_btnContent; - -private: - QString m_strContent; -}; - -class UBKeyboardPalette : public UBActionPalette -{ - Q_OBJECT - -friend class UBKeyboardButton; -friend class UBCapsLockButton; -friend class UBShiftButton; -friend class UBLocaleButton; -friend class UBKeyButton; - -public: - UBKeyboardPalette(QWidget *parent); - ~UBKeyboardPalette(); - - BTNImages *currBtnImages; - - bool isEnabled(){return locales!= NULL;} - virtual QSize sizeHint () const; - virtual void adjustSizeAndPosition(bool pUp = true); - QString getKeyButtonSize() const {QString res; res.sprintf("%dx%d", btnWidth, btnHeight); return res;} - void setKeyButtonSize(const QString& strSize); - - bool m_isVisible; - QPoint m_pos; - -signals: - void moved(const QPoint&); - void localeChanged(int); - void keyboardActivated(bool); - -private slots: - void syncPosition(const QPoint & pos); - void syncLocale(int nLocale); - void keyboardPaletteButtonSizeChanged(QVariant size); - void onActivated(bool b); - void onDeactivated(); - void showKeyboard(bool show); - void hideKeyboard(); - -protected: - bool capsLock; - bool shift; - int nCurrentLocale; - int nLocalesCount; - UBKeyboardLocale** locales; - - int nSpecialModifierIndex; - KEYCODE specialModifier; - - QString strSize; - int btnWidth; - int btnHeight; -// - bool languagePopupActive; - bool keyboardActive; -// - virtual void enterEvent ( QEvent * event ); - virtual void leaveEvent ( QEvent * event ); - virtual void paintEvent(QPaintEvent *event); - virtual void moveEvent ( QMoveEvent * event ); - - void sendKeyEvent(KEYCODE keyCode); - - void setLocale(int nLocale); - - const QString* getLocaleName(); - - void init(); - - -private: - - QRect originalRect; - - UBKeyButton** buttons; - UBKeyboardButton** ctrlButtons; - - /* - For MacOS: synchronization with system locale. - */ - void checkLayout(); - - void createCtrlButtons(); - - void setInput(const UBKeyboardLocale* locale); - - // Can be redefined under each platform - void onLocaleChanged(UBKeyboardLocale* locale); - - // Storage for platform-dependent objects (linux) - void* storage; - // Linux-related parameters - int min_keycodes, max_keycodes, byte_per_code; -}; - -class UBKeyboardButton : public QWidget -{ - Q_OBJECT - -public: - UBKeyboardButton(UBKeyboardPalette* parent, QString contentImagePath); - ~UBKeyboardButton(); - -protected: - - UBKeyboardPalette* m_parent; - ContentImage *imgContent; - QString m_contentImagePath; - - void paintEvent(QPaintEvent *event); - - virtual void enterEvent ( QEvent * event ); - virtual void leaveEvent ( QEvent * event ); - virtual void mousePressEvent ( QMouseEvent * event ); - virtual void mouseReleaseEvent ( QMouseEvent * event ); - - virtual void onPress() = 0; - virtual void onRelease() = 0; - virtual void paintContent(QPainter& painter) = 0; - - virtual bool isPressed(); - - UBKeyboardPalette* keyboard; - - void sendUnicodeSymbol(KEYCODE keycode); - void sendControlSymbol(int nSymbol); - -private: - bool bFocused; - bool bPressed; -}; - -class UBKeyButton : public UBKeyboardButton -{ - Q_OBJECT - -public: - UBKeyButton(UBKeyboardPalette* parent); - ~UBKeyButton(); - - void setKeyBt(const KEYBT* keybt){this->keybt = keybt;} - - virtual void onPress(); - virtual void onRelease(); - virtual void paintContent(QPainter& painter); - -private: - bool shifted(); - const KEYBT* keybt; -}; - -class UBCntrlButton : public UBKeyboardButton -{ - Q_OBJECT - -public: - UBCntrlButton(UBKeyboardPalette* parent, int _code, const QString& _contentImagePath ); - UBCntrlButton(UBKeyboardPalette* parent, const QString& _label, int _code ); - ~UBCntrlButton(); - - virtual void onPress(); - virtual void onRelease(); - virtual void paintContent(QPainter& painter); - -private: - QString label; - int code; -}; - -class UBCapsLockButton : public UBKeyboardButton -{ - Q_OBJECT - -public: - UBCapsLockButton(UBKeyboardPalette* parent, const QString _contentImagePath); - ~UBCapsLockButton(); - - virtual void onPress(); - virtual void onRelease(); - virtual void paintContent(QPainter& painter); - -protected: - virtual bool isPressed(); -}; - -class UBShiftButton : public UBKeyboardButton -{ - Q_OBJECT - -public: - UBShiftButton(UBKeyboardPalette* parent, const QString _contentImagePath); - ~UBShiftButton(); - - virtual void onPress(); - virtual void onRelease(); - virtual void paintContent(QPainter& painter); - -protected: - virtual bool isPressed(); -}; - - -class UBLocaleButton : public UBKeyboardButton -{ - Q_OBJECT - -public: - UBLocaleButton(UBKeyboardPalette* parent); - ~UBLocaleButton(); - - virtual void onPress(); - virtual void onRelease(); - virtual void paintContent(QPainter& painter); - -protected: - QMenu* localeMenu; -}; - -#endif // UBKEYBOARDPALETTE_H + + +#ifndef UBKEYBOARDPALETTE_H +#define UBKEYBOARDPALETTE_H + +#include "UBActionPalette.h" + +#include +#include +#include +#include + +#include "frameworks/UBPlatformUtils.h" + +class UBKeyButton; +class UBKeyboardButton; + +class UBApplication; +class UBMainWindow; + +class BTNImages +{ +public: + + BTNImages(QString _strHeight, int _width, int _height); + + QString m_strHeight; + int m_width; + int m_height; + + QImage m_btnLeftPassive; + QImage m_btnCenterPassive; + QImage m_btnRightPassive; + QImage m_btnLeftActive; + QImage m_btnCenterActive; + QImage m_btnRightActive; + +private: + QString m_strLeftPassive; + QString m_strCenterPassive; + QString m_strRightPassive; + QString m_strLeftActive; + QString m_strCenterActive; + QString m_strRightActive; + +}; + +class ContentImage +{ +public: + + ContentImage(QString strHeight, int m_height, QString strContentPath); + + QString m_strHeight; + int m_height; + + QImage m_btnContent; + +private: + QString m_strContent; +}; + +class UBKeyboardPalette : public UBActionPalette +{ + Q_OBJECT + +friend class UBKeyboardButton; +friend class UBCapsLockButton; +friend class UBShiftButton; +friend class UBLocaleButton; +friend class UBKeyButton; + +public: + UBKeyboardPalette(QWidget *parent); + ~UBKeyboardPalette(); + + BTNImages *currBtnImages; + + bool isEnabled(){return locales!= NULL;} + virtual QSize sizeHint () const; + virtual void adjustSizeAndPosition(bool pUp = true); + QString getKeyButtonSize() const {QString res; res.sprintf("%dx%d", btnWidth, btnHeight); return res;} + void setKeyButtonSize(const QString& strSize); + + bool m_isVisible; + QPoint m_pos; + +signals: + void moved(const QPoint&); + void localeChanged(int); + void keyboardActivated(bool); + +private slots: + void syncPosition(const QPoint & pos); + void syncLocale(int nLocale); + void keyboardPaletteButtonSizeChanged(QVariant size); + void onActivated(bool b); + void onDeactivated(); + void showKeyboard(bool show); + void hideKeyboard(); + +protected: + bool capsLock; + bool shift; + int nCurrentLocale; + int nLocalesCount; + UBKeyboardLocale** locales; + + int nSpecialModifierIndex; + KEYCODE specialModifier; + + QString strSize; + int btnWidth; + int btnHeight; +// + bool languagePopupActive; + bool keyboardActive; +// + virtual void enterEvent ( QEvent * event ); + virtual void leaveEvent ( QEvent * event ); + virtual void paintEvent(QPaintEvent *event); + virtual void moveEvent ( QMoveEvent * event ); + + void sendKeyEvent(KEYCODE keyCode); + + void setLocale(int nLocale); + + const QString* getLocaleName(); + + void init(); + + +private: + + QRect originalRect; + + UBKeyButton** buttons; + UBKeyboardButton** ctrlButtons; + + /* + For MacOS: synchronization with system locale. + */ + void checkLayout(); + + void createCtrlButtons(); + + void setInput(const UBKeyboardLocale* locale); + + // Can be redefined under each platform + void onLocaleChanged(UBKeyboardLocale* locale); + + // Storage for platform-dependent objects (linux) + void* storage; + // Linux-related parameters + int min_keycodes, max_keycodes, byte_per_code; +}; + +class UBKeyboardButton : public QWidget +{ + Q_OBJECT + +public: + UBKeyboardButton(UBKeyboardPalette* parent, QString contentImagePath); + ~UBKeyboardButton(); + +protected: + + UBKeyboardPalette* m_parent; + ContentImage *imgContent; + QString m_contentImagePath; + + void paintEvent(QPaintEvent *event); + + virtual void enterEvent ( QEvent * event ); + virtual void leaveEvent ( QEvent * event ); + virtual void mousePressEvent ( QMouseEvent * event ); + virtual void mouseReleaseEvent ( QMouseEvent * event ); + + virtual void onPress() = 0; + virtual void onRelease() = 0; + virtual void paintContent(QPainter& painter) = 0; + + virtual bool isPressed(); + + UBKeyboardPalette* keyboard; + + void sendUnicodeSymbol(KEYCODE keycode); + void sendControlSymbol(int nSymbol); + +private: + bool bFocused; + bool bPressed; +}; + +class UBKeyButton : public UBKeyboardButton +{ + Q_OBJECT + +public: + UBKeyButton(UBKeyboardPalette* parent); + ~UBKeyButton(); + + void setKeyBt(const KEYBT* keybt){this->keybt = keybt;} + + virtual void onPress(); + virtual void onRelease(); + virtual void paintContent(QPainter& painter); + +private: + bool shifted(); + const KEYBT* keybt; +}; + +class UBCntrlButton : public UBKeyboardButton +{ + Q_OBJECT + +public: + UBCntrlButton(UBKeyboardPalette* parent, int _code, const QString& _contentImagePath ); + UBCntrlButton(UBKeyboardPalette* parent, const QString& _label, int _code ); + ~UBCntrlButton(); + + virtual void onPress(); + virtual void onRelease(); + virtual void paintContent(QPainter& painter); + +private: + QString label; + int code; +}; + +class UBCapsLockButton : public UBKeyboardButton +{ + Q_OBJECT + +public: + UBCapsLockButton(UBKeyboardPalette* parent, const QString _contentImagePath); + ~UBCapsLockButton(); + + virtual void onPress(); + virtual void onRelease(); + virtual void paintContent(QPainter& painter); + +protected: + virtual bool isPressed(); +}; + +class UBShiftButton : public UBKeyboardButton +{ + Q_OBJECT + +public: + UBShiftButton(UBKeyboardPalette* parent, const QString _contentImagePath); + ~UBShiftButton(); + + virtual void onPress(); + virtual void onRelease(); + virtual void paintContent(QPainter& painter); + +protected: + virtual bool isPressed(); +}; + + +class UBLocaleButton : public UBKeyboardButton +{ + Q_OBJECT + +public: + UBLocaleButton(UBKeyboardPalette* parent); + ~UBLocaleButton(); + + virtual void onPress(); + virtual void onRelease(); + virtual void paintContent(QPainter& painter); + +protected: + QMenu* localeMenu; +}; + +#endif // UBKEYBOARDPALETTE_H diff --git a/src/gui/UBKeyboardPalette_win.cpp b/src/gui/UBKeyboardPalette_win.cpp index 6cd01576..d30236c2 100644 --- a/src/gui/UBKeyboardPalette_win.cpp +++ b/src/gui/UBKeyboardPalette_win.cpp @@ -19,79 +19,79 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBKeyboardPalette.h" - -#include - -#include "../core/UBApplication.h" -#include "../gui/UBMainWindow.h" - -#include "core/memcheck.h" - -void UBKeyboardButton::sendUnicodeSymbol(KEYCODE keycode) -{ - INPUT input[2]; - input[0].type = INPUT_KEYBOARD; - input[0].ki.wVk = 0; - input[0].ki.wScan = keycode.symbol; - input[0].ki.dwFlags = KEYEVENTF_UNICODE; - input[0].ki.time = 0; - input[0].ki.dwExtraInfo = 0; - - input[1].type = INPUT_KEYBOARD; - input[1].ki.wVk = 0; - input[1].ki.wScan = keycode.symbol; - input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; - input[1].ki.time = 0; - input[1].ki.dwExtraInfo = 0; - - ::SendInput(2, input, sizeof(input[0])); -} - -void UBKeyboardButton::sendControlSymbol(int nSymbol) -{ - INPUT input[2]; - input[0].type = INPUT_KEYBOARD; - input[0].ki.wVk = nSymbol; - input[0].ki.wScan = 0; - input[0].ki.dwFlags = 0; - input[0].ki.time = 0; - input[0].ki.dwExtraInfo = 0; - - input[1].type = INPUT_KEYBOARD; - input[1].ki.wVk = nSymbol; - input[1].ki.wScan = 0; - input[1].ki.dwFlags = KEYEVENTF_KEYUP; - input[1].ki.time = 0; - input[1].ki.dwExtraInfo = 0; - - ::SendInput(2, input, sizeof(input[0])); -} - -void UBKeyboardPalette::createCtrlButtons() -{ - int ctrlID = 0; - ctrlButtons = new UBKeyboardButton*[9]; - - ctrlButtons[ctrlID++] = new UBCntrlButton(this, 0x08, "backspace");// Backspace - ctrlButtons[ctrlID++] = new UBCntrlButton(this, 0x09, "tab"); // Tab - ctrlButtons[ctrlID++] = new UBCapsLockButton(this, "capslock"); // Shift - ctrlButtons[ctrlID++] = new UBCntrlButton(this, tr("Enter"), 0x0d); // Enter - ctrlButtons[ctrlID++] = new UBShiftButton(this, "shift"); // Shift - ctrlButtons[ctrlID++] = new UBShiftButton(this, "shift"); // Shift - ctrlButtons[ctrlID++] = new UBLocaleButton(this); // Language Switch - ctrlButtons[ctrlID++] = new UBCntrlButton(this, "", 0x20); // Space - ctrlButtons[ctrlID++] = new UBLocaleButton(this); // Language Switch -} - -void UBKeyboardPalette::checkLayout() -{} - -void UBKeyboardPalette::onActivated(bool) -{} - -void UBKeyboardPalette::onLocaleChanged(UBKeyboardLocale* ) -{} - + + +#include "UBKeyboardPalette.h" + +#include + +#include "../core/UBApplication.h" +#include "../gui/UBMainWindow.h" + +#include "core/memcheck.h" + +void UBKeyboardButton::sendUnicodeSymbol(KEYCODE keycode) +{ + INPUT input[2]; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = 0; + input[0].ki.wScan = keycode.symbol; + input[0].ki.dwFlags = KEYEVENTF_UNICODE; + input[0].ki.time = 0; + input[0].ki.dwExtraInfo = 0; + + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = 0; + input[1].ki.wScan = keycode.symbol; + input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; + input[1].ki.time = 0; + input[1].ki.dwExtraInfo = 0; + + ::SendInput(2, input, sizeof(input[0])); +} + +void UBKeyboardButton::sendControlSymbol(int nSymbol) +{ + INPUT input[2]; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = nSymbol; + input[0].ki.wScan = 0; + input[0].ki.dwFlags = 0; + input[0].ki.time = 0; + input[0].ki.dwExtraInfo = 0; + + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = nSymbol; + input[1].ki.wScan = 0; + input[1].ki.dwFlags = KEYEVENTF_KEYUP; + input[1].ki.time = 0; + input[1].ki.dwExtraInfo = 0; + + ::SendInput(2, input, sizeof(input[0])); +} + +void UBKeyboardPalette::createCtrlButtons() +{ + int ctrlID = 0; + ctrlButtons = new UBKeyboardButton*[9]; + + ctrlButtons[ctrlID++] = new UBCntrlButton(this, 0x08, "backspace");// Backspace + ctrlButtons[ctrlID++] = new UBCntrlButton(this, 0x09, "tab"); // Tab + ctrlButtons[ctrlID++] = new UBCapsLockButton(this, "capslock"); // Shift + ctrlButtons[ctrlID++] = new UBCntrlButton(this, tr("Enter"), 0x0d); // Enter + ctrlButtons[ctrlID++] = new UBShiftButton(this, "shift"); // Shift + ctrlButtons[ctrlID++] = new UBShiftButton(this, "shift"); // Shift + ctrlButtons[ctrlID++] = new UBLocaleButton(this); // Language Switch + ctrlButtons[ctrlID++] = new UBCntrlButton(this, "", 0x20); // Space + ctrlButtons[ctrlID++] = new UBLocaleButton(this); // Language Switch +} + +void UBKeyboardPalette::checkLayout() +{} + +void UBKeyboardPalette::onActivated(bool) +{} + +void UBKeyboardPalette::onLocaleChanged(UBKeyboardLocale* ) +{} + diff --git a/src/gui/UBMagnifer.cpp b/src/gui/UBMagnifer.cpp index 1d6a2db8..76796b77 100644 --- a/src/gui/UBMagnifer.cpp +++ b/src/gui/UBMagnifer.cpp @@ -19,386 +19,386 @@ * along with Open-Sankoré. If not, see . */ - - -#include -#include "UBMagnifer.h" - -#include "core/UBApplication.h" -#include "board/UBBoardController.h" -#include "domain/UBGraphicsScene.h" -#include "board/UBBoardView.h" - -#include "core/memcheck.h" - - -UBMagnifier::UBMagnifier(QWidget *parent, bool isInteractive) - : QWidget(parent, parent ? Qt::Widget : Qt::Tool | (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint)) - , mShouldMoveWidget(false) - , mShouldResizeWidget(false) - , borderPen(Qt::darkGray) - , gView(0) - , mView(0) -{ - isCusrsorAlreadyStored = false; - setMouseTracking(true); - - //--------------------------------------------------// - - QPixmap pix(":/images/cursors/resize.png"); - QTransform tr; - tr.rotate(45); - mResizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); - - //--------------------------------------------------// - - params.sizePercentFromScene = 20; - m_isInteractive = isInteractive; - sClosePixmap = new QPixmap(":/images/close.svg"); - sIncreasePixmap = new QPixmap(":/images/increase.svg"); - sDecreasePixmap = new QPixmap(":/images/decrease.svg"); - mResizeItem = new QPixmap(":/images/resize.svg"); - - if (parent) - { - setAttribute(Qt::WA_NoMousePropagation); - } - else - { - // standalone window - // !!!! Should be included into Windows after QT recompilation -#ifndef Q_WS_WIN -// setAttribute(Qt::WA_TranslucentBackground); - setAttribute(Qt::WA_MacAlwaysShowToolWindow); -#endif -#ifdef Q_WS_MAC - setAttribute(Qt::WA_MacAlwaysShowToolWindow); - setAttribute(Qt::WA_MacNonActivatingToolWindow); - setAttribute(Qt::WA_MacNoShadow); -#endif - } - - connect(&mRefreshTimer, SIGNAL(timeout()), this, SLOT(slot_refresh())); -} - -UBMagnifier::~UBMagnifier() -{ - if(sClosePixmap) - { - delete sClosePixmap; - sClosePixmap = NULL; - } - - if(sIncreasePixmap) - { - delete sIncreasePixmap; - sIncreasePixmap = NULL; - } - - if(sDecreasePixmap) - { - delete sDecreasePixmap; - sDecreasePixmap = NULL; - } -} - -void UBMagnifier::setSize(qreal percentFromScene) -{ - if(gView == NULL || mView == NULL) return; - - // calculate object size - params.sizePercentFromScene = percentFromScene; - QSize sceneSize = mView->size(); - qreal size = params.sizePercentFromScene * sceneSize.width() / 100; - - QRect currGeom = geometry(); - if(currGeom.width() == currGeom.height()) - { - QPoint newPos = mView->mapFromGlobal(updPointMove); - setGeometry(newPos.x() - size / 2, newPos.y() - size / 2, size, size); - } - else - setGeometry(0, 0, size, size); - - // prepare transparent bit mask - QImage mask_img(width(), height(), QImage::Format_Mono); - mask_img.fill(0xff); - QPainter mask_ptr(&mask_img); - mask_ptr.setBrush( QBrush( QColor(0, 0, 0) ) ); - mask_ptr.drawEllipse(QPointF(size/2, size/2), size / 2 - sClosePixmap->width(), size / 2 - sClosePixmap->width()); - bmpMask = QBitmap::fromImage(mask_img); - - // prepare general image - pMap = QPixmap(width(), height()); - pMap.fill(Qt::transparent); - pMap.setMask(bmpMask); -} - -void UBMagnifier::setZoom(qreal zoom) -{ - params.zoom = zoom; -} - -void UBMagnifier::paintEvent(QPaintEvent * event) -{ - Q_UNUSED(event); - QPainter painter(this); - - painter.setRenderHint(QPainter::Antialiasing); - painter.setPen(Qt::NoPen); - - if (m_isInteractive) - { - painter.setBrush(QColor(127, 127, 127, 127)); - painter.drawRoundedRect(QRectF(size().width() / 2, size().height() / 2, ( size().width() - sClosePixmap->width() ) / 2, ( size().height() - sClosePixmap->width() ) / 2), 15, 15); - - painter.setBrush(QColor(190, 190, 190, 255)); - painter.drawEllipse(QPoint( size().width() / 2, size().height() / 2), ( size().width() - sClosePixmap->width() ) / 2, ( size().height() - sClosePixmap->height() ) / 2); - - painter.drawPixmap(size().width() - sClosePixmap->width(), size().height() / 2 + sClosePixmap->height() * 1, *sClosePixmap); - painter.drawPixmap(size().width() - sIncreasePixmap->width(), size().height() / 2 + sIncreasePixmap->height() * 2.5, *sIncreasePixmap); - painter.drawPixmap(size().width() - sDecreasePixmap->width(), size().height() / 2 + sDecreasePixmap->height() * 3.6, *sDecreasePixmap); - - painter.drawPixmap(size().width() - mResizeItem->width() - 20, size().height() - mResizeItem->height() - 20, *mResizeItem); - } - else - { - painter.setBrush(QColor(127, 127, 127, 127)); - painter.drawEllipse(QPoint( size().width() / 2, size().height() / 2), ( size().width() - sClosePixmap->width() ) / 2, ( size().height() - sClosePixmap->height() ) / 2); - } - - painter.drawPixmap(0, 0, pMap); -} - -void UBMagnifier::mousePressEvent ( QMouseEvent * event ) -{ - if(m_isInteractive) - { - - QWidget::mousePressEvent(event); - - if (event->pos().x() >= size().width() - mResizeItem->width() - 20 && - event->pos().x() < size().width() - 20 && - event->pos().y() >= size().height() - mResizeItem->height() - 20 && - event->pos().y() < size().height() - - 20) - { - mShouldResizeWidget = true; - } - else - { - mShouldMoveWidget = !event->isAccepted() && (event->buttons() & Qt::LeftButton); - } - - mMousePressPos = event->pos(); - mMousePressDelta = (qreal)updPointGrab.x() + (qreal)size().width() / 2 - (qreal)event->globalPos().x(); - - event->accept(); - - update(); - } - else - event->ignore(); -} - -void UBMagnifier::mouseMoveEvent ( QMouseEvent * event ) -{ - if(m_isInteractive) - { - if(mShouldMoveWidget && (event->buttons() & Qt::LeftButton)) - { - move(pos() - mMousePressPos + event->pos()); - event->accept(); - - QWidget::mouseMoveEvent(event); - emit magnifierMoved_Signal(QPoint(this->pos().x() + size().width() / 2, this->pos().y() + size().height() / 2 )); - return; - } - - if(mShouldResizeWidget && (event->buttons() & Qt::LeftButton)) - { - - QPoint currGlobalPos = event->globalPos(); - qreal cvW = mView->width(); - - qreal newXSize = ( currGlobalPos.x() + mMousePressDelta - updPointGrab.x() ) * 2; - qreal newPercentSize = newXSize * 100 / cvW; - - emit magnifierResized_Signal(newPercentSize); - - event->ignore(); - return; - } - - if (event->pos().x() >= size().width() - mResizeItem->width() - 20 && - event->pos().x() < size().width() - 20 && - event->pos().y() >= size().height() - mResizeItem->height() - 20 && - event->pos().y() < size().height() - - 20 && - isCusrsorAlreadyStored == false - ) - { - mOldCursor = cursor(); - isCusrsorAlreadyStored = true; - setCursor(mResizeCursor); - } - - } - else - event->ignore(); -} - - -void UBMagnifier::mouseReleaseEvent(QMouseEvent * event) -{ - if(m_isInteractive) - { - mShouldMoveWidget = false; - mShouldResizeWidget = false; - - if (event->pos().x() >= size().width() - sClosePixmap->width() && - event->pos().x() < size().width()&& - event->pos().y() >= size().height() / 2 + sClosePixmap->height() * 1 && - event->pos().y() < size().height() / 2 + sClosePixmap->height() * 2) - { - event->accept(); - emit magnifierClose_Signal(); - } - else - if (event->pos().x() >= size().width() - sIncreasePixmap->width() && - event->pos().x() < size().width()&& - event->pos().y() >= size().height() / 2 + sIncreasePixmap->height() * 2.5 && - event->pos().y() < size().height() / 2 + sIncreasePixmap->height() * 3.5) - { - event->accept(); - emit magnifierZoomIn_Signal(); - } - else - if (event->pos().x() >= size().width() - sDecreasePixmap->width() && - event->pos().x() < size().width()&& - event->pos().y() >= size().height() / 2 + sDecreasePixmap->height() * 3.6 && - event->pos().y() < size().height() / 2 + sDecreasePixmap->height() * 4.6) - { - event->accept(); - emit magnifierZoomOut_Signal(); - } - else - QWidget::mouseReleaseEvent(event); // don't propgate to parent, the widget is deleted in UBApplication::boardController->removeTool - } - else - event->ignore(); - -} - -void UBMagnifier::slot_refresh() -{ - if(!(updPointGrab.isNull())) - grabPoint(updPointGrab); - - if(isCusrsorAlreadyStored) - { - QPoint globalCursorPos = QCursor::pos(); - QPoint cursorPos = mapFromGlobal(globalCursorPos); - if (cursorPos.x() < size().width() - mResizeItem->width() - 20 || - cursorPos.x() > size().width() - 20 || - cursorPos.y() < size().height() - mResizeItem->height() - 20 || - cursorPos.y() > size().height() - - 20 - ) - { - isCusrsorAlreadyStored = false; - setCursor(mOldCursor); - } - } -} - -void UBMagnifier::grabPoint() -{ - QMatrix transM = UBApplication::boardController->controlView()->matrix(); - QPointF itemPos = gView->mapFromGlobal(updPointGrab); - - qreal zWidth = width() / (params.zoom * transM.m11()); - qreal zWidthHalf = zWidth / 2; - qreal zHeight = height() / (params.zoom * transM.m22()); - qreal zHeightHalf = zHeight / 2; - - - QPointF pfScLtF(UBApplication::boardController->controlView()->mapToScene(QPoint(itemPos.x(), itemPos.y()))); - - float x = pfScLtF.x() - zWidthHalf; - float y = pfScLtF.y() - zHeightHalf; - - QPointF leftTop(x,y); - QPointF rightBottom(x + zWidth, y + zHeight); - QRectF srcRect(leftTop, rightBottom); - - QPixmap newPixMap(QSize(width(), height())); - QPainter painter(&newPixMap); - - UBApplication::boardController->activeScene()->render(&painter, QRectF(0,0,width(),height()), srcRect); - painter.end(); - - pMap.fill(Qt::transparent); - pMap = newPixMap.scaled(QSize(width(), height())); - pMap.setMask(bmpMask); - - update(); -} - -void UBMagnifier::grabPoint(const QPoint &pGrab) -{ - QMatrix transM = UBApplication::boardController->controlView()->matrix(); - updPointGrab = pGrab; - QPointF itemPos = gView->mapFromGlobal(pGrab); - - qreal zWidth = width() / (params.zoom * transM.m11()); - qreal zWidthHalf = zWidth / 2; - qreal zHeight = height() / (params.zoom * transM.m22()); - qreal zHeightHalf = zHeight / 2; - - - QPointF pfScLtF(UBApplication::boardController->controlView()->mapToScene(QPoint(itemPos.x(), itemPos.y()))); - - float x = pfScLtF.x() - zWidthHalf; - float y = pfScLtF.y() - zHeightHalf; - - QPointF leftTop(x,y); - QPointF rightBottom(x + zWidth, y + zHeight); - QRectF srcRect(leftTop, rightBottom); - - QPixmap newPixMap(QSize(width(), height())); - QPainter painter(&newPixMap); - - UBApplication::boardController->activeScene()->render(&painter, QRectF(0,0,width(),height()), srcRect); - painter.end(); - - // pMap.fill(Qt::transparent); - pMap = newPixMap; - pMap.setMask(bmpMask); - - update(); -} - - - -// from global -void UBMagnifier::grabNMove(const QPoint &pGrab, const QPoint &pMove, bool needGrab, bool needMove) -{ - updPointGrab = pGrab; - updPointMove = pMove; - - if(needGrab) - grabPoint(pGrab); - - if(needMove) - { - QPoint movePos = mView->mapFromGlobal(pMove); - move(movePos.x() - width()/2, movePos.y() - height()/2); - // move(itemPos.x(), itemPos.y()); - } -} - -void UBMagnifier::setGrabView(QWidget *view) -{ - gView = view; - mRefreshTimer.setInterval(40); - mRefreshTimer.start(); -} - + + +#include +#include "UBMagnifer.h" + +#include "core/UBApplication.h" +#include "board/UBBoardController.h" +#include "domain/UBGraphicsScene.h" +#include "board/UBBoardView.h" + +#include "core/memcheck.h" + + +UBMagnifier::UBMagnifier(QWidget *parent, bool isInteractive) + : QWidget(parent, parent ? Qt::Widget : Qt::Tool | (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint)) + , mShouldMoveWidget(false) + , mShouldResizeWidget(false) + , borderPen(Qt::darkGray) + , gView(0) + , mView(0) +{ + isCusrsorAlreadyStored = false; + setMouseTracking(true); + + //--------------------------------------------------// + + QPixmap pix(":/images/cursors/resize.png"); + QTransform tr; + tr.rotate(45); + mResizeCursor = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); + + //--------------------------------------------------// + + params.sizePercentFromScene = 20; + m_isInteractive = isInteractive; + sClosePixmap = new QPixmap(":/images/close.svg"); + sIncreasePixmap = new QPixmap(":/images/increase.svg"); + sDecreasePixmap = new QPixmap(":/images/decrease.svg"); + mResizeItem = new QPixmap(":/images/resize.svg"); + + if (parent) + { + setAttribute(Qt::WA_NoMousePropagation); + } + else + { + // standalone window + // !!!! Should be included into Windows after QT recompilation +#ifndef Q_WS_WIN +// setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_MacAlwaysShowToolWindow); +#endif +#ifdef Q_WS_MAC + setAttribute(Qt::WA_MacAlwaysShowToolWindow); + setAttribute(Qt::WA_MacNonActivatingToolWindow); + setAttribute(Qt::WA_MacNoShadow); +#endif + } + + connect(&mRefreshTimer, SIGNAL(timeout()), this, SLOT(slot_refresh())); +} + +UBMagnifier::~UBMagnifier() +{ + if(sClosePixmap) + { + delete sClosePixmap; + sClosePixmap = NULL; + } + + if(sIncreasePixmap) + { + delete sIncreasePixmap; + sIncreasePixmap = NULL; + } + + if(sDecreasePixmap) + { + delete sDecreasePixmap; + sDecreasePixmap = NULL; + } +} + +void UBMagnifier::setSize(qreal percentFromScene) +{ + if(gView == NULL || mView == NULL) return; + + // calculate object size + params.sizePercentFromScene = percentFromScene; + QSize sceneSize = mView->size(); + qreal size = params.sizePercentFromScene * sceneSize.width() / 100; + + QRect currGeom = geometry(); + if(currGeom.width() == currGeom.height()) + { + QPoint newPos = mView->mapFromGlobal(updPointMove); + setGeometry(newPos.x() - size / 2, newPos.y() - size / 2, size, size); + } + else + setGeometry(0, 0, size, size); + + // prepare transparent bit mask + QImage mask_img(width(), height(), QImage::Format_Mono); + mask_img.fill(0xff); + QPainter mask_ptr(&mask_img); + mask_ptr.setBrush( QBrush( QColor(0, 0, 0) ) ); + mask_ptr.drawEllipse(QPointF(size/2, size/2), size / 2 - sClosePixmap->width(), size / 2 - sClosePixmap->width()); + bmpMask = QBitmap::fromImage(mask_img); + + // prepare general image + pMap = QPixmap(width(), height()); + pMap.fill(Qt::transparent); + pMap.setMask(bmpMask); +} + +void UBMagnifier::setZoom(qreal zoom) +{ + params.zoom = zoom; +} + +void UBMagnifier::paintEvent(QPaintEvent * event) +{ + Q_UNUSED(event); + QPainter painter(this); + + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(Qt::NoPen); + + if (m_isInteractive) + { + painter.setBrush(QColor(127, 127, 127, 127)); + painter.drawRoundedRect(QRectF(size().width() / 2, size().height() / 2, ( size().width() - sClosePixmap->width() ) / 2, ( size().height() - sClosePixmap->width() ) / 2), 15, 15); + + painter.setBrush(QColor(190, 190, 190, 255)); + painter.drawEllipse(QPoint( size().width() / 2, size().height() / 2), ( size().width() - sClosePixmap->width() ) / 2, ( size().height() - sClosePixmap->height() ) / 2); + + painter.drawPixmap(size().width() - sClosePixmap->width(), size().height() / 2 + sClosePixmap->height() * 1, *sClosePixmap); + painter.drawPixmap(size().width() - sIncreasePixmap->width(), size().height() / 2 + sIncreasePixmap->height() * 2.5, *sIncreasePixmap); + painter.drawPixmap(size().width() - sDecreasePixmap->width(), size().height() / 2 + sDecreasePixmap->height() * 3.6, *sDecreasePixmap); + + painter.drawPixmap(size().width() - mResizeItem->width() - 20, size().height() - mResizeItem->height() - 20, *mResizeItem); + } + else + { + painter.setBrush(QColor(127, 127, 127, 127)); + painter.drawEllipse(QPoint( size().width() / 2, size().height() / 2), ( size().width() - sClosePixmap->width() ) / 2, ( size().height() - sClosePixmap->height() ) / 2); + } + + painter.drawPixmap(0, 0, pMap); +} + +void UBMagnifier::mousePressEvent ( QMouseEvent * event ) +{ + if(m_isInteractive) + { + + QWidget::mousePressEvent(event); + + if (event->pos().x() >= size().width() - mResizeItem->width() - 20 && + event->pos().x() < size().width() - 20 && + event->pos().y() >= size().height() - mResizeItem->height() - 20 && + event->pos().y() < size().height() - - 20) + { + mShouldResizeWidget = true; + } + else + { + mShouldMoveWidget = !event->isAccepted() && (event->buttons() & Qt::LeftButton); + } + + mMousePressPos = event->pos(); + mMousePressDelta = (qreal)updPointGrab.x() + (qreal)size().width() / 2 - (qreal)event->globalPos().x(); + + event->accept(); + + update(); + } + else + event->ignore(); +} + +void UBMagnifier::mouseMoveEvent ( QMouseEvent * event ) +{ + if(m_isInteractive) + { + if(mShouldMoveWidget && (event->buttons() & Qt::LeftButton)) + { + move(pos() - mMousePressPos + event->pos()); + event->accept(); + + QWidget::mouseMoveEvent(event); + emit magnifierMoved_Signal(QPoint(this->pos().x() + size().width() / 2, this->pos().y() + size().height() / 2 )); + return; + } + + if(mShouldResizeWidget && (event->buttons() & Qt::LeftButton)) + { + + QPoint currGlobalPos = event->globalPos(); + qreal cvW = mView->width(); + + qreal newXSize = ( currGlobalPos.x() + mMousePressDelta - updPointGrab.x() ) * 2; + qreal newPercentSize = newXSize * 100 / cvW; + + emit magnifierResized_Signal(newPercentSize); + + event->ignore(); + return; + } + + if (event->pos().x() >= size().width() - mResizeItem->width() - 20 && + event->pos().x() < size().width() - 20 && + event->pos().y() >= size().height() - mResizeItem->height() - 20 && + event->pos().y() < size().height() - - 20 && + isCusrsorAlreadyStored == false + ) + { + mOldCursor = cursor(); + isCusrsorAlreadyStored = true; + setCursor(mResizeCursor); + } + + } + else + event->ignore(); +} + + +void UBMagnifier::mouseReleaseEvent(QMouseEvent * event) +{ + if(m_isInteractive) + { + mShouldMoveWidget = false; + mShouldResizeWidget = false; + + if (event->pos().x() >= size().width() - sClosePixmap->width() && + event->pos().x() < size().width()&& + event->pos().y() >= size().height() / 2 + sClosePixmap->height() * 1 && + event->pos().y() < size().height() / 2 + sClosePixmap->height() * 2) + { + event->accept(); + emit magnifierClose_Signal(); + } + else + if (event->pos().x() >= size().width() - sIncreasePixmap->width() && + event->pos().x() < size().width()&& + event->pos().y() >= size().height() / 2 + sIncreasePixmap->height() * 2.5 && + event->pos().y() < size().height() / 2 + sIncreasePixmap->height() * 3.5) + { + event->accept(); + emit magnifierZoomIn_Signal(); + } + else + if (event->pos().x() >= size().width() - sDecreasePixmap->width() && + event->pos().x() < size().width()&& + event->pos().y() >= size().height() / 2 + sDecreasePixmap->height() * 3.6 && + event->pos().y() < size().height() / 2 + sDecreasePixmap->height() * 4.6) + { + event->accept(); + emit magnifierZoomOut_Signal(); + } + else + QWidget::mouseReleaseEvent(event); // don't propgate to parent, the widget is deleted in UBApplication::boardController->removeTool + } + else + event->ignore(); + +} + +void UBMagnifier::slot_refresh() +{ + if(!(updPointGrab.isNull())) + grabPoint(updPointGrab); + + if(isCusrsorAlreadyStored) + { + QPoint globalCursorPos = QCursor::pos(); + QPoint cursorPos = mapFromGlobal(globalCursorPos); + if (cursorPos.x() < size().width() - mResizeItem->width() - 20 || + cursorPos.x() > size().width() - 20 || + cursorPos.y() < size().height() - mResizeItem->height() - 20 || + cursorPos.y() > size().height() - - 20 + ) + { + isCusrsorAlreadyStored = false; + setCursor(mOldCursor); + } + } +} + +void UBMagnifier::grabPoint() +{ + QMatrix transM = UBApplication::boardController->controlView()->matrix(); + QPointF itemPos = gView->mapFromGlobal(updPointGrab); + + qreal zWidth = width() / (params.zoom * transM.m11()); + qreal zWidthHalf = zWidth / 2; + qreal zHeight = height() / (params.zoom * transM.m22()); + qreal zHeightHalf = zHeight / 2; + + + QPointF pfScLtF(UBApplication::boardController->controlView()->mapToScene(QPoint(itemPos.x(), itemPos.y()))); + + float x = pfScLtF.x() - zWidthHalf; + float y = pfScLtF.y() - zHeightHalf; + + QPointF leftTop(x,y); + QPointF rightBottom(x + zWidth, y + zHeight); + QRectF srcRect(leftTop, rightBottom); + + QPixmap newPixMap(QSize(width(), height())); + QPainter painter(&newPixMap); + + UBApplication::boardController->activeScene()->render(&painter, QRectF(0,0,width(),height()), srcRect); + painter.end(); + + pMap.fill(Qt::transparent); + pMap = newPixMap.scaled(QSize(width(), height())); + pMap.setMask(bmpMask); + + update(); +} + +void UBMagnifier::grabPoint(const QPoint &pGrab) +{ + QMatrix transM = UBApplication::boardController->controlView()->matrix(); + updPointGrab = pGrab; + QPointF itemPos = gView->mapFromGlobal(pGrab); + + qreal zWidth = width() / (params.zoom * transM.m11()); + qreal zWidthHalf = zWidth / 2; + qreal zHeight = height() / (params.zoom * transM.m22()); + qreal zHeightHalf = zHeight / 2; + + + QPointF pfScLtF(UBApplication::boardController->controlView()->mapToScene(QPoint(itemPos.x(), itemPos.y()))); + + float x = pfScLtF.x() - zWidthHalf; + float y = pfScLtF.y() - zHeightHalf; + + QPointF leftTop(x,y); + QPointF rightBottom(x + zWidth, y + zHeight); + QRectF srcRect(leftTop, rightBottom); + + QPixmap newPixMap(QSize(width(), height())); + QPainter painter(&newPixMap); + + UBApplication::boardController->activeScene()->render(&painter, QRectF(0,0,width(),height()), srcRect); + painter.end(); + + // pMap.fill(Qt::transparent); + pMap = newPixMap; + pMap.setMask(bmpMask); + + update(); +} + + + +// from global +void UBMagnifier::grabNMove(const QPoint &pGrab, const QPoint &pMove, bool needGrab, bool needMove) +{ + updPointGrab = pGrab; + updPointMove = pMove; + + if(needGrab) + grabPoint(pGrab); + + if(needMove) + { + QPoint movePos = mView->mapFromGlobal(pMove); + move(movePos.x() - width()/2, movePos.y() - height()/2); + // move(itemPos.x(), itemPos.y()); + } +} + +void UBMagnifier::setGrabView(QWidget *view) +{ + gView = view; + mRefreshTimer.setInterval(40); + mRefreshTimer.start(); +} + diff --git a/src/gui/UBMagnifer.h b/src/gui/UBMagnifer.h index 6c581ee9..f69a4610 100644 --- a/src/gui/UBMagnifer.h +++ b/src/gui/UBMagnifer.h @@ -19,87 +19,87 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBMAGNIFIER_H -#define UBMAGNIFIER_H - -#include - -class UBMagnifierParams -{ -public : - int x; - int y; - qreal zoom; - qreal sizePercentFromScene; -}; - -class UBMagnifier : public QWidget -{ - Q_OBJECT - -public: - UBMagnifier(QWidget *parent = 0, bool isInteractive = false); - ~UBMagnifier(); - - void setSize(qreal percentFromScene); - void setZoom(qreal zoom); - - void setGrabView(QWidget *view); - void setMoveView(QWidget *view) {mView = view;} - - void grabPoint(); - void grabPoint(const QPoint &point); - void grabNMove(const QPoint &pGrab, const QPoint &pMove, bool needGrab = true, bool needMove = true); - - UBMagnifierParams params; - -signals: - void magnifierMoved_Signal(QPoint newPos); - void magnifierClose_Signal(); - void magnifierZoomIn_Signal(); - void magnifierZoomOut_Signal(); - void magnifierResized_Signal(qreal newPercentSize); - -public slots: - void slot_refresh(); - -protected: - void paintEvent(QPaintEvent *); - - virtual void mousePressEvent ( QMouseEvent * event ); - virtual void mouseMoveEvent ( QMouseEvent * event ); - virtual void mouseReleaseEvent ( QMouseEvent * event ); - - QPoint mMousePressPos; - qreal mMousePressDelta; - bool mShouldMoveWidget; - bool mShouldResizeWidget; - - - QPixmap *sClosePixmap; - QPixmap *sIncreasePixmap; - QPixmap *sDecreasePixmap; - QPixmap *mResizeItem; - - bool isCusrsorAlreadyStored; - QCursor mOldCursor; - QCursor mResizeCursor; - -private: - QTimer mRefreshTimer; - bool m_isInteractive; - - QPoint updPointGrab; - QPoint updPointMove; - - QPixmap pMap; - QBitmap bmpMask; - QPen borderPen; - - QWidget *gView; - QWidget *mView; -}; - -#endif // UBMAGNIFIER_H + + +#ifndef UBMAGNIFIER_H +#define UBMAGNIFIER_H + +#include + +class UBMagnifierParams +{ +public : + int x; + int y; + qreal zoom; + qreal sizePercentFromScene; +}; + +class UBMagnifier : public QWidget +{ + Q_OBJECT + +public: + UBMagnifier(QWidget *parent = 0, bool isInteractive = false); + ~UBMagnifier(); + + void setSize(qreal percentFromScene); + void setZoom(qreal zoom); + + void setGrabView(QWidget *view); + void setMoveView(QWidget *view) {mView = view;} + + void grabPoint(); + void grabPoint(const QPoint &point); + void grabNMove(const QPoint &pGrab, const QPoint &pMove, bool needGrab = true, bool needMove = true); + + UBMagnifierParams params; + +signals: + void magnifierMoved_Signal(QPoint newPos); + void magnifierClose_Signal(); + void magnifierZoomIn_Signal(); + void magnifierZoomOut_Signal(); + void magnifierResized_Signal(qreal newPercentSize); + +public slots: + void slot_refresh(); + +protected: + void paintEvent(QPaintEvent *); + + virtual void mousePressEvent ( QMouseEvent * event ); + virtual void mouseMoveEvent ( QMouseEvent * event ); + virtual void mouseReleaseEvent ( QMouseEvent * event ); + + QPoint mMousePressPos; + qreal mMousePressDelta; + bool mShouldMoveWidget; + bool mShouldResizeWidget; + + + QPixmap *sClosePixmap; + QPixmap *sIncreasePixmap; + QPixmap *sDecreasePixmap; + QPixmap *mResizeItem; + + bool isCusrsorAlreadyStored; + QCursor mOldCursor; + QCursor mResizeCursor; + +private: + QTimer mRefreshTimer; + bool m_isInteractive; + + QPoint updPointGrab; + QPoint updPointMove; + + QPixmap pMap; + QBitmap bmpMask; + QPen borderPen; + + QWidget *gView; + QWidget *mView; +}; + +#endif // UBMAGNIFIER_H diff --git a/src/gui/UBNavigatorPalette.cpp b/src/gui/UBNavigatorPalette.cpp index 1c5c84e4..f29f69e6 100644 --- a/src/gui/UBNavigatorPalette.cpp +++ b/src/gui/UBNavigatorPalette.cpp @@ -19,135 +19,135 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBNavigatorPalette.h" -#include "core/UBApplication.h" -#include "board/UBBoardController.h" - -#include "core/memcheck.h" - -/** - * \brief Constructor - * @param parent as the parent widget - * @param name as the object name - */ -UBNavigatorPalette::UBNavigatorPalette(QWidget *parent, const char *name): - UBDockPalette(eUBDockPaletteType_LEFT, parent, name) - , mNavigator(NULL) - , mLayout(NULL) - , mHLayout(NULL) - , mPageNbr(NULL) - , mClock(NULL) -{ - // Build the gui - mLayout = new QVBoxLayout(this); - mLayout->setContentsMargins(customMargin(), customMargin(), 2*border() + customMargin(), customMargin()); - setLayout(mLayout); - - mNavigator = new UBDocumentNavigator(this); - mNavigator->setStyleSheet(QString("background-color : transparent;")); - mLayout->addWidget(mNavigator, 1); - - mHLayout = new QHBoxLayout(); - mLayout->addLayout(mHLayout, 0); - - mPageNbr = new QLabel(this); - mClock = new QLabel(this); - mHLayout->addWidget(mPageNbr); - mHLayout->addWidget(mClock); - - // Configure the page number indicator - mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); - setPageNumber(0, 0); - mPageNbr->setAlignment(Qt::AlignHCenter); - - // Configure the clock - mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); - mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); - mClock->setAlignment(Qt::AlignHCenter); - - //strip seconds - mTimeFormat = mTimeFormat.remove(":ss"); - mTimeFormat = mTimeFormat.remove(":s"); - mTimerID = startTimer(1000); - -} - -/** - * \brief Destructor - */ -UBNavigatorPalette::~UBNavigatorPalette() -{ - killTimer(mTimerID); - - if(NULL != mClock) - { - delete mClock; - mClock = NULL; - } - if(NULL != mPageNbr) - { - delete mPageNbr; - mPageNbr = NULL; - } - if(NULL != mHLayout) - { - delete mHLayout; - mHLayout = NULL; - } - if(NULL != mLayout) - { - delete mLayout; - mLayout = NULL; - } - if(NULL != mNavigator) - { - delete mNavigator; - mNavigator = NULL; - } -} - -/** - * \brief Set the current document in the navigator - * @param document as the given document - */ - -/** - * \brief Refresh the thumbnails widget - */ -void UBNavigatorPalette::refresh() -{ -} - -/** - * \brief Handle the resize event - * @param event as the resize event - */ -void UBNavigatorPalette::resizeEvent(QResizeEvent *event) -{ - UBDockPalette::resizeEvent(event); - if(NULL != mNavigator) - { - mNavigator->setMinimumHeight(height() - 2*border()); - } -} - -void UBNavigatorPalette::timerEvent(QTimerEvent *event) -{ - Q_UNUSED(event); - updateTime(); -} - -void UBNavigatorPalette::updateTime() -{ - if (mClock) - { - mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); - } -} - -void UBNavigatorPalette::setPageNumber(int current, int total) -{ - mPageNbr->setText(QString("%1 / %2").arg(current).arg(total)); -} + + +#include "UBNavigatorPalette.h" +#include "core/UBApplication.h" +#include "board/UBBoardController.h" + +#include "core/memcheck.h" + +/** + * \brief Constructor + * @param parent as the parent widget + * @param name as the object name + */ +UBNavigatorPalette::UBNavigatorPalette(QWidget *parent, const char *name): + UBDockPalette(eUBDockPaletteType_LEFT, parent, name) + , mNavigator(NULL) + , mLayout(NULL) + , mHLayout(NULL) + , mPageNbr(NULL) + , mClock(NULL) +{ + // Build the gui + mLayout = new QVBoxLayout(this); + mLayout->setContentsMargins(customMargin(), customMargin(), 2*border() + customMargin(), customMargin()); + setLayout(mLayout); + + mNavigator = new UBDocumentNavigator(this); + mNavigator->setStyleSheet(QString("background-color : transparent;")); + mLayout->addWidget(mNavigator, 1); + + mHLayout = new QHBoxLayout(); + mLayout->addLayout(mHLayout, 0); + + mPageNbr = new QLabel(this); + mClock = new QLabel(this); + mHLayout->addWidget(mPageNbr); + mHLayout->addWidget(mClock); + + // Configure the page number indicator + mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); + setPageNumber(0, 0); + mPageNbr->setAlignment(Qt::AlignHCenter); + + // Configure the clock + mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); + mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); + mClock->setAlignment(Qt::AlignHCenter); + + //strip seconds + mTimeFormat = mTimeFormat.remove(":ss"); + mTimeFormat = mTimeFormat.remove(":s"); + mTimerID = startTimer(1000); + +} + +/** + * \brief Destructor + */ +UBNavigatorPalette::~UBNavigatorPalette() +{ + killTimer(mTimerID); + + if(NULL != mClock) + { + delete mClock; + mClock = NULL; + } + if(NULL != mPageNbr) + { + delete mPageNbr; + mPageNbr = NULL; + } + if(NULL != mHLayout) + { + delete mHLayout; + mHLayout = NULL; + } + if(NULL != mLayout) + { + delete mLayout; + mLayout = NULL; + } + if(NULL != mNavigator) + { + delete mNavigator; + mNavigator = NULL; + } +} + +/** + * \brief Set the current document in the navigator + * @param document as the given document + */ + +/** + * \brief Refresh the thumbnails widget + */ +void UBNavigatorPalette::refresh() +{ +} + +/** + * \brief Handle the resize event + * @param event as the resize event + */ +void UBNavigatorPalette::resizeEvent(QResizeEvent *event) +{ + UBDockPalette::resizeEvent(event); + if(NULL != mNavigator) + { + mNavigator->setMinimumHeight(height() - 2*border()); + } +} + +void UBNavigatorPalette::timerEvent(QTimerEvent *event) +{ + Q_UNUSED(event); + updateTime(); +} + +void UBNavigatorPalette::updateTime() +{ + if (mClock) + { + mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); + } +} + +void UBNavigatorPalette::setPageNumber(int current, int total) +{ + mPageNbr->setText(QString("%1 / %2").arg(current).arg(total)); +} diff --git a/src/gui/UBNavigatorPalette.h b/src/gui/UBNavigatorPalette.h index bb818f2f..060252e3 100644 --- a/src/gui/UBNavigatorPalette.h +++ b/src/gui/UBNavigatorPalette.h @@ -19,55 +19,55 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBNAVIGATORPALETTE_H -#define UBNAVIGATORPALETTE_H - -#include -#include -#include -#include -#include -#include -#include - -#include "UBDockPalette.h" -#include "UBDocumentNavigator.h" -#include "document/UBDocumentProxy.h" - - -class UBNavigatorPalette : public UBDockPalette -{ - Q_OBJECT -public: - UBNavigatorPalette(QWidget* parent=0, const char* name="navigatorPalette"); - ~UBNavigatorPalette(); - - void setDocument(UBDocumentProxy* document); - void refresh(); - -public slots: - void setPageNumber(int current, int total); - -protected: - virtual void resizeEvent(QResizeEvent *event); - virtual void timerEvent(QTimerEvent *event); - -private: - void updateTime(); - - /** The thumbnails navigator widget */ - UBDocumentNavigator* mNavigator; - /** The layout */ - QVBoxLayout* mLayout; - QHBoxLayout* mHLayout; - QLabel* mPageNbr; - QLabel* mClock; - QString mTimeFormat; - int mTimerID; - -}; - - -#endif // UBNAVIGATORPALETTE_H + + +#ifndef UBNAVIGATORPALETTE_H +#define UBNAVIGATORPALETTE_H + +#include +#include +#include +#include +#include +#include +#include + +#include "UBDockPalette.h" +#include "UBDocumentNavigator.h" +#include "document/UBDocumentProxy.h" + + +class UBNavigatorPalette : public UBDockPalette +{ + Q_OBJECT +public: + UBNavigatorPalette(QWidget* parent=0, const char* name="navigatorPalette"); + ~UBNavigatorPalette(); + + void setDocument(UBDocumentProxy* document); + void refresh(); + +public slots: + void setPageNumber(int current, int total); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void timerEvent(QTimerEvent *event); + +private: + void updateTime(); + + /** The thumbnails navigator widget */ + UBDocumentNavigator* mNavigator; + /** The layout */ + QVBoxLayout* mLayout; + QHBoxLayout* mHLayout; + QLabel* mPageNbr; + QLabel* mClock; + QString mTimeFormat; + int mTimerID; + +}; + + +#endif // UBNAVIGATORPALETTE_H diff --git a/src/gui/UBPageNavigationWidget.cpp b/src/gui/UBPageNavigationWidget.cpp index c8ff553f..7366709e 100644 --- a/src/gui/UBPageNavigationWidget.cpp +++ b/src/gui/UBPageNavigationWidget.cpp @@ -19,162 +19,162 @@ * along with Open-Sankoré. If not, see . */ - - -#include "UBPageNavigationWidget.h" -#include "core/UBApplication.h" - -#include "board/UBBoardController.h" - -#include "document/UBDocumentContainer.h" - -#include "globals/UBGlobals.h" - -#include "core/memcheck.h" - -/** - * \brief Constructor - * @param parent as the parent widget - * @param name as the object name - */ -UBPageNavigationWidget::UBPageNavigationWidget(QWidget *parent, const char *name):UBDockPaletteWidget(parent) - , mNavigator(NULL) - , mLayout(NULL) - , mHLayout(NULL) - , mPageNbr(NULL) - , mClock(NULL) -{ - setObjectName(name); - mName = "PageNavigator"; - mVisibleState = true; - - SET_STYLE_SHEET(); - - mIconToRight = QPixmap(":images/pages_open.png"); - mIconToLeft = QPixmap(":images/pages_close.png"); - - // Build the gui - mLayout = new QVBoxLayout(this); - setLayout(mLayout); - - mNavigator = new UBDocumentNavigator(this); - mLayout->addWidget(mNavigator, 1); - - mHLayout = new QHBoxLayout(); - mLayout->addLayout(mHLayout, 0); - - mPageNbr = new QLabel(this); - mClock = new QLabel(this); - mHLayout->addWidget(mPageNbr); - mHLayout->addWidget(mClock); - - // Configure the page number indicator - mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); - setPageNumber(0, 0); - mPageNbr->setAlignment(Qt::AlignHCenter); - - // Configure the clock - mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); - mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); - mClock->setAlignment(Qt::AlignHCenter); - - //strip seconds - mTimeFormat = mTimeFormat.remove(":ss"); - mTimeFormat = mTimeFormat.remove(":s"); - mTimerID = startTimer(1000); - -} - -/** - * \brief Destructor - */ -UBPageNavigationWidget::~UBPageNavigationWidget() -{ - killTimer(mTimerID); - - if(NULL != mClock) - { - delete mClock; - mClock = NULL; - } - if(NULL != mPageNbr) - { - delete mPageNbr; - mPageNbr = NULL; - } - if(NULL != mHLayout) - { - delete mHLayout; - mHLayout = NULL; - } - if(NULL != mLayout) - { - delete mLayout; - mLayout = NULL; - } - if(NULL != mNavigator) - { - delete mNavigator; - mNavigator = NULL; - } -} - - -/** - * \brief Refresh the thumbnails widget - */ -void UBPageNavigationWidget::refresh() -{ - // TOLIK!!! - // mNavigator->setDocument(UBApplication::boardController->activeDocument()); -} - -/** - * \brief Notify a timer event - * @param event as the timer event - */ -void UBPageNavigationWidget::timerEvent(QTimerEvent *event) -{ - Q_UNUSED(event); - updateTime(); -} - -/** - * \brief Update the current time - */ -void UBPageNavigationWidget::updateTime() -{ - if (mClock) - { - mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); - } -} - -/** - * \brief Set the page number - * @param current as the current page - * @param total as the total number of pages - */ -void UBPageNavigationWidget::setPageNumber(int current, int total) -{ - mPageNbr->setText(QString("%1 / %2").arg(current).arg(UBDocumentContainer::sceneIndexFromPage(total))); -} - -/** - * \brief Get the custom margin value - * @return the custom margin value - */ -int UBPageNavigationWidget::customMargin() -{ - return 5; -} - -/** - * \brief Get the border value - * @return the border value - */ -int UBPageNavigationWidget::border() -{ - return 15; -} - + + +#include "UBPageNavigationWidget.h" +#include "core/UBApplication.h" + +#include "board/UBBoardController.h" + +#include "document/UBDocumentContainer.h" + +#include "globals/UBGlobals.h" + +#include "core/memcheck.h" + +/** + * \brief Constructor + * @param parent as the parent widget + * @param name as the object name + */ +UBPageNavigationWidget::UBPageNavigationWidget(QWidget *parent, const char *name):UBDockPaletteWidget(parent) + , mNavigator(NULL) + , mLayout(NULL) + , mHLayout(NULL) + , mPageNbr(NULL) + , mClock(NULL) +{ + setObjectName(name); + mName = "PageNavigator"; + mVisibleState = true; + + SET_STYLE_SHEET(); + + mIconToRight = QPixmap(":images/pages_open.png"); + mIconToLeft = QPixmap(":images/pages_close.png"); + + // Build the gui + mLayout = new QVBoxLayout(this); + setLayout(mLayout); + + mNavigator = new UBDocumentNavigator(this); + mLayout->addWidget(mNavigator, 1); + + mHLayout = new QHBoxLayout(); + mLayout->addLayout(mHLayout, 0); + + mPageNbr = new QLabel(this); + mClock = new QLabel(this); + mHLayout->addWidget(mPageNbr); + mHLayout->addWidget(mClock); + + // Configure the page number indicator + mPageNbr->setStyleSheet(QString("QLabel { color: white; background-color: transparent; border: none; font-family: Arial; font-weight: bold; font-size: 20px }")); + setPageNumber(0, 0); + mPageNbr->setAlignment(Qt::AlignHCenter); + + // Configure the clock + mClock->setStyleSheet(QString("QLabel {color: white; background-color: transparent; text-align: center; font-family: Arial; font-weight: bold; font-size: 20px}")); + mTimeFormat = QLocale::system().timeFormat(QLocale::ShortFormat); + mClock->setAlignment(Qt::AlignHCenter); + + //strip seconds + mTimeFormat = mTimeFormat.remove(":ss"); + mTimeFormat = mTimeFormat.remove(":s"); + mTimerID = startTimer(1000); + +} + +/** + * \brief Destructor + */ +UBPageNavigationWidget::~UBPageNavigationWidget() +{ + killTimer(mTimerID); + + if(NULL != mClock) + { + delete mClock; + mClock = NULL; + } + if(NULL != mPageNbr) + { + delete mPageNbr; + mPageNbr = NULL; + } + if(NULL != mHLayout) + { + delete mHLayout; + mHLayout = NULL; + } + if(NULL != mLayout) + { + delete mLayout; + mLayout = NULL; + } + if(NULL != mNavigator) + { + delete mNavigator; + mNavigator = NULL; + } +} + + +/** + * \brief Refresh the thumbnails widget + */ +void UBPageNavigationWidget::refresh() +{ + // TOLIK!!! + // mNavigator->setDocument(UBApplication::boardController->activeDocument()); +} + +/** + * \brief Notify a timer event + * @param event as the timer event + */ +void UBPageNavigationWidget::timerEvent(QTimerEvent *event) +{ + Q_UNUSED(event); + updateTime(); +} + +/** + * \brief Update the current time + */ +void UBPageNavigationWidget::updateTime() +{ + if (mClock) + { + mClock->setText(QLocale::system().toString (QTime::currentTime(), mTimeFormat)); + } +} + +/** + * \brief Set the page number + * @param current as the current page + * @param total as the total number of pages + */ +void UBPageNavigationWidget::setPageNumber(int current, int total) +{ + mPageNbr->setText(QString("%1 / %2").arg(current).arg(UBDocumentContainer::sceneIndexFromPage(total))); +} + +/** + * \brief Get the custom margin value + * @return the custom margin value + */ +int UBPageNavigationWidget::customMargin() +{ + return 5; +} + +/** + * \brief Get the border value + * @return the border value + */ +int UBPageNavigationWidget::border() +{ + return 15; +} + diff --git a/src/gui/UBPageNavigationWidget.h b/src/gui/UBPageNavigationWidget.h index 98e38b10..1ff4aab0 100644 --- a/src/gui/UBPageNavigationWidget.h +++ b/src/gui/UBPageNavigationWidget.h @@ -19,62 +19,62 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBPAGENAVIGATIONWIDGET_H -#define UBPAGENAVIGATIONWIDGET_H - -#include -#include -#include -#include -#include -#include -#include - -#include "UBDocumentNavigator.h" -#include "UBDockPaletteWidget.h" -#include "document/UBDocumentProxy.h" - -class UBPageNavigationWidget : public UBDockPaletteWidget -{ - Q_OBJECT -public: - UBPageNavigationWidget(QWidget* parent=0, const char* name="UBPageNavigationWidget"); - ~UBPageNavigationWidget(); - //void setDocument(UBDocumentProxy* document); - void refresh(); - - bool visibleInMode(eUBDockPaletteWidgetMode mode) - { - return mode == eUBDockPaletteWidget_BOARD; - } - -signals: - void resizeRequest(QResizeEvent* event); - -public slots: - void setPageNumber(int current, int total); - -protected: - virtual void timerEvent(QTimerEvent *event); - - -private: - void updateTime(); - int customMargin(); - int border(); - - /** The thumbnails navigator widget */ - UBDocumentNavigator* mNavigator; - /** The layout */ - QVBoxLayout* mLayout; - QHBoxLayout* mHLayout; - QLabel* mPageNbr; - QLabel* mClock; - QString mTimeFormat; - int mTimerID; - -}; - -#endif // UBPAGENAVIGATIONWIDGET_H + + +#ifndef UBPAGENAVIGATIONWIDGET_H +#define UBPAGENAVIGATIONWIDGET_H + +#include +#include +#include +#include +#include +#include +#include + +#include "UBDocumentNavigator.h" +#include "UBDockPaletteWidget.h" +#include "document/UBDocumentProxy.h" + +class UBPageNavigationWidget : public UBDockPaletteWidget +{ + Q_OBJECT +public: + UBPageNavigationWidget(QWidget* parent=0, const char* name="UBPageNavigationWidget"); + ~UBPageNavigationWidget(); + //void setDocument(UBDocumentProxy* document); + void refresh(); + + bool visibleInMode(eUBDockPaletteWidgetMode mode) + { + return mode == eUBDockPaletteWidget_BOARD; + } + +signals: + void resizeRequest(QResizeEvent* event); + +public slots: + void setPageNumber(int current, int total); + +protected: + virtual void timerEvent(QTimerEvent *event); + + +private: + void updateTime(); + int customMargin(); + int border(); + + /** The thumbnails navigator widget */ + UBDocumentNavigator* mNavigator; + /** The layout */ + QVBoxLayout* mLayout; + QHBoxLayout* mHLayout; + QLabel* mPageNbr; + QLabel* mClock; + QString mTimeFormat; + int mTimerID; + +}; + +#endif // UBPAGENAVIGATIONWIDGET_H diff --git a/src/gui/UBThumbnailWidget.cpp b/src/gui/UBThumbnailWidget.cpp index 09d96663..c67f14f8 100644 --- a/src/gui/UBThumbnailWidget.cpp +++ b/src/gui/UBThumbnailWidget.cpp @@ -19,922 +19,923 @@ * along with Open-Sankoré. If not, see . */ -#include -#include - -#include "UBThumbnailWidget.h" -#include "UBRubberBand.h" -#include "UBMainWindow.h" - -#include "board/UBBoardController.h" - -#include "core/UBSettings.h" -#include "core/UBApplication.h" - -#include "document/UBDocumentProxy.h" -#include "document/UBDocumentController.h" - -#include "core/memcheck.h" - -UBThumbnailWidget::UBThumbnailWidget(QWidget* parent) - : QGraphicsView(parent) - , mThumbnailWidth(UBSettings::defaultThumbnailWidth) - , mSpacing(UBSettings::thumbnailSpacing) - , mLastSelectedThumbnail(0) - , mSelectionSpan(0) - , mPrevLassoRect(QRect()) - , mLassoRectItem(0) - -{ - // By default, the drag is possible - bCanDrag = true; - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); - setFrameShape(QFrame::NoFrame); - setScene(&mThumbnailsScene); - - setAlignment(Qt::AlignLeft | Qt::AlignTop); - - connect(&mThumbnailsScene, SIGNAL(selectionChanged()), this, SLOT(sceneSelectionChanged())); -} - - -UBThumbnailWidget::~UBThumbnailWidget() -{ - disconnect(&mThumbnailsScene, SIGNAL(selectionChanged())); -} - - -void UBThumbnailWidget::setThumbnailWidth(qreal pThumbnailWidth) -{ - mThumbnailWidth = pThumbnailWidth; - - refreshScene(); -} - - -void UBThumbnailWidget::setSpacing(qreal pSpacing) -{ - mSpacing = pSpacing; - - refreshScene(); -} - - -void UBThumbnailWidget::setGraphicsItems(const QList& pGraphicsItems - , const QList& pItemsPaths - , const QStringList pLabels - , const QString& pMimeType) -{ - mGraphicItems = pGraphicsItems; - mItemsPaths = pItemsPaths; - mMimeType = pMimeType; - mLabels = pLabels; - - foreach(QGraphicsItem* it, mThumbnailsScene.items()) - { - mThumbnailsScene.removeItem(it, true); - } - - // set lasso to 0 as it has been cleared as well - mLassoRectItem = 0; - - foreach (QGraphicsItem* item, pGraphicsItems) - { - if (item->scene() != &mThumbnailsScene) - { - mThumbnailsScene.addItem(item); - } - } - - mLabelsItems.clear(); - - foreach (const QString label, pLabels) - { - QFontMetrics fm(font()); - UBThumbnailTextItem *labelItem = - new UBThumbnailTextItem(label); // deleted while replace or by the scene destruction - - mThumbnailsScene.addItem(labelItem); - mLabelsItems << labelItem; - } - - refreshScene(); - - mLastSelectedThumbnail = 0; -} - - -void UBThumbnailWidget::refreshScene() -{ - int nbColumns = (geometry().width() - mSpacing) / (mThumbnailWidth + mSpacing); - - int labelSpacing = 0; - - if (mLabelsItems.size() > 0) - { - QFontMetrics fm(mLabelsItems.at(0)->font()); - labelSpacing = UBSettings::thumbnailSpacing + fm.height(); // TODO UB 4.x where is 20 from ??? configure ?? compute based on mSpacing ?? JBA Is it the font height? - } - nbColumns = qMax(nbColumns, 1); - - qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio; - - for (int i = 0; i < mGraphicItems.size(); i++) - { - QGraphicsItem* item = mGraphicItems.at(i); - - qreal scaleWidth = mThumbnailWidth / item->boundingRect().width(); - qreal scaleHeight = thumbnailHeight / item->boundingRect().height(); - - qreal scaleFactor = qMin(scaleWidth, scaleHeight); - - //bitmap should not be stretched - UBThumbnail* pix = dynamic_cast(item); - if (pix) - scaleFactor = qMin(scaleFactor, 1.0); - - QTransform transform; - transform.scale(scaleFactor, scaleFactor); - - item->setTransform(transform); - - item->setFlag(QGraphicsItem::ItemIsSelectable, true); - - int columnIndex = i % nbColumns; - int rowIndex = i / nbColumns; - - if (pix) - { - pix->setColumn(columnIndex); - pix->setRow(rowIndex); - } - - int w = item->boundingRect().width(); - int h = item->boundingRect().height(); - QPointF pos( - mSpacing + (mThumbnailWidth - w * scaleFactor) / 2 + columnIndex * (mThumbnailWidth + mSpacing), - mSpacing + rowIndex * (thumbnailHeight + mSpacing + labelSpacing) + (thumbnailHeight - h * scaleFactor) / 2); - - item->setPos(pos); - - if (mLabelsItems.size() > i) - { - QFontMetrics fm(mLabelsItems.at(i)->font(), this); - QString elidedText = fm.elidedText(mLabels.at(i), Qt::ElideRight, mThumbnailWidth); - - mLabelsItems.at(i)->setPlainText(elidedText); - mLabelsItems.at(i)->setWidth(fm.width(elidedText) + 2 * mLabelsItems.at(i)->document()->documentMargin()); - - pos.setY(pos.y() + (thumbnailHeight + h * scaleFactor) / 2 + 5); - qreal labelWidth = fm.width(elidedText); - pos.setX(mSpacing + (mThumbnailWidth - labelWidth) / 2 + columnIndex * (mThumbnailWidth + mSpacing)); - mLabelsItems.at(i)->setPos(pos); - } - } - - QScrollBar *vertScrollBar = verticalScrollBar(); - int scrollBarThickness = 0; - if (vertScrollBar && vertScrollBar->isVisible()) - scrollBarThickness = vertScrollBar->width(); - - setSceneRect(0, 0, - geometry().width() - scrollBarThickness, - mSpacing + ((((mGraphicItems.size() - 1) / nbColumns) + 1) * (thumbnailHeight + mSpacing + labelSpacing))); -} - - -QList UBThumbnailWidget::selectedItems() -{ - QList sortedSelectedItems = mThumbnailsScene.selectedItems(); - qSort(sortedSelectedItems.begin(), sortedSelectedItems.end(), thumbnailLessThan); - return sortedSelectedItems; -} - - -void UBThumbnailWidget::mousePressEvent(QMouseEvent *event) -{ - mClickTime = QTime::currentTime(); - mMousePressPos = event->pos(); - - UBSceneThumbnailPixmap* sceneItem = dynamic_cast(itemAt(mMousePressPos)); - if(sceneItem==NULL) - { - event->ignore(); - return; - } - //if(sceneItem){ - // int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneItem->sceneIndex()); - // if(pageIndex == 0){ - // event->ignore(); - // return; - // } - //} - - mMousePressScenePos = mapToScene(mMousePressPos); - QGraphicsItem* underlyingItem = itemAt(mMousePressPos); - UBThumbnail *previousSelectedThumbnail = mLastSelectedThumbnail; - - if (!dynamic_cast(underlyingItem)) - { - deleteLasso(); - - UBRubberBand rubberBand(QRubberBand::Rectangle); - QStyleOption option; - option.initFrom(&rubberBand); - - mPrevLassoRect = QRect(); - mLassoRectItem = new QGraphicsRectItem(0, scene()); - -#ifdef Q_WS_MAC - // The following code must stay in synch with \src\gui\styles\qmacstyle_mac.mm - QColor strokeColor; - strokeColor.setHsvF(0, 0, 0.86, 1.0); - mLassoRectItem->setPen(QPen(strokeColor)); - QColor fillColor(option.palette.color(QPalette::Disabled, QPalette::Highlight)); - fillColor.setHsvF(0, 0, 0.53, 0.25); - mLassoRectItem->setBrush(fillColor); -#else - // The following code must stay in synch with \src\gui\styles\qwindowsxpstyle.cpp - QColor highlight = option.palette.color(QPalette::Active, QPalette::Highlight); - mLassoRectItem->setPen(highlight.darker(120)); - QColor dimHighlight(qMin(highlight.red() / 2 + 110, 255), - qMin(highlight.green() / 2 + 110, 255), - qMin(highlight.blue() / 2 + 110, 255), - 127); - mLassoRectItem->setBrush(dimHighlight); -#endif - - mLassoRectItem->setZValue(10000); - mLassoRectItem->setRect(QRectF(mMousePressScenePos, QSizeF())); - - if (Qt::ControlModifier & event->modifiers() || Qt::ShiftModifier & event->modifiers()) - { - // mSelectedThumbnailItems = selectedItems().toSet(); - return; - } - - mSelectedThumbnailItems.clear(); - mPreviouslyIncrementalSelectedItemsX.clear(); - mPreviouslyIncrementalSelectedItemsY.clear(); - QGraphicsView::mousePressEvent(event); - } - else if (Qt::ShiftModifier & event->modifiers()) - { - if (previousSelectedThumbnail) - { - QGraphicsItem* previousSelectedItem = dynamic_cast(previousSelectedThumbnail); - if (previousSelectedItem) - { - int index1 = mGraphicItems.indexOf(previousSelectedItem); - int index2 = mGraphicItems.indexOf(underlyingItem); - if (-1 == index2) - { - mSelectedThumbnailItems = selectedItems().toSet(); - return; - } - mSelectionSpan = index2 - index1; - selectItems(qMin(index1, index2), mSelectionSpan < 0 ? - mSelectionSpan + 1 : mSelectionSpan + 1); - return; - } - } - } - else - { - mLastSelectedThumbnail = dynamic_cast(underlyingItem); - if (!underlyingItem->isSelected()) - { - int index = mGraphicItems.indexOf(underlyingItem); - selectItemAt(index, Qt::ControlModifier & event->modifiers()); - } - else - { - QGraphicsView::mousePressEvent(event); - } - if (!mLastSelectedThumbnail && mGraphicItems.count() > 0) - mLastSelectedThumbnail = dynamic_cast(mGraphicItems.at(0)); - mSelectionSpan = 0; - return; - } -} - - -void UBThumbnailWidget::mouseMoveEvent(QMouseEvent *event) -{ - int distance = (mMousePressPos - event->pos()).manhattanLength(); - - if (0 == (event->buttons() & Qt::LeftButton) || distance < QApplication::startDragDistance()) - return; - - if (mLassoRectItem) - { - bSelectionInProgress = true; - int incrementLassoMinWidth = 2; - QPointF currentScenePos = mapToScene(event->pos()); - QRectF lassoRect( - qMin(mMousePressScenePos.x(), currentScenePos.x()), qMin(mMousePressScenePos.y(), currentScenePos.y()), - qAbs(mMousePressScenePos.x() - currentScenePos.x()), qAbs(mMousePressScenePos.y() - currentScenePos.y())); - if (QPoint() == prevMoveMousePos) - prevMoveMousePos = currentScenePos; - QRectF incrementXSelection( - qMin(prevMoveMousePos.x(), currentScenePos.x()), qMin(mMousePressScenePos.y(), currentScenePos.y()), - qAbs(prevMoveMousePos.x() - currentScenePos.x())+incrementLassoMinWidth, qAbs(mMousePressScenePos.y() - currentScenePos.y())); - QRectF incrementYSelection( - qMin(mMousePressScenePos.x(), currentScenePos.x()), qMin(prevMoveMousePos.y(), currentScenePos.y()), - qAbs(mMousePressScenePos.x() - currentScenePos.x()), qAbs(prevMoveMousePos.y() - currentScenePos.y())+incrementLassoMinWidth); - - prevMoveMousePos = currentScenePos; - mLassoRectItem->setRect(lassoRect); - - QSet lassoSelectedThumbnailItems; - - QSet toUnset; - QSet toSet; - - // for horizontal moving - QSet incSelectedItemsX = scene()->items(incrementXSelection, Qt::IntersectsItemBoundingRect).toSet(); - foreach (QGraphicsItem *lassoSelectedItem, incSelectedItemsX) - { - if (lassoSelectedItem) - { - UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast(lassoSelectedItem); - if (thumbnailItem) - lassoSelectedThumbnailItems += lassoSelectedItem; - } - } - - if(lassoRect.width() < mPrevLassoRect.width()) - { - if (!lassoSelectedThumbnailItems.contains(mPreviouslyIncrementalSelectedItemsX)) - toUnset += mPreviouslyIncrementalSelectedItemsX - lassoSelectedThumbnailItems; - - } - mPreviouslyIncrementalSelectedItemsX = lassoSelectedThumbnailItems; - - toSet += lassoSelectedThumbnailItems + mPreviouslyIncrementalSelectedItemsX; - - - lassoSelectedThumbnailItems.clear(); - - // for vertical moving - - QSet incSelectedItemsY = scene()->items(incrementYSelection, Qt::IntersectsItemBoundingRect).toSet(); - foreach (QGraphicsItem *lassoSelectedItem, incSelectedItemsY) - { - if (lassoSelectedItem) - { - UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast(lassoSelectedItem); - - if (thumbnailItem) - lassoSelectedThumbnailItems += lassoSelectedItem; - } - } - - if(lassoRect.height() < mPrevLassoRect.height()) - { - if (!lassoSelectedThumbnailItems.contains(mPreviouslyIncrementalSelectedItemsY)) - toUnset += mPreviouslyIncrementalSelectedItemsY - lassoSelectedThumbnailItems; - - } - mPreviouslyIncrementalSelectedItemsY = lassoSelectedThumbnailItems; - - - toSet += lassoSelectedThumbnailItems + mPreviouslyIncrementalSelectedItemsY; - - - toSet -= toUnset; - - foreach (QGraphicsItem *item, toSet) - { - item->setSelected(true); - } - - foreach (QGraphicsItem *item, toUnset) - { - item->setSelected(false); - } - - mSelectedThumbnailItems += lassoSelectedThumbnailItems; - mPrevLassoRect = lassoRect; - - if (Qt::ControlModifier & event->modifiers()) - { - for (int i = 0; i < mSelectedThumbnailItems.count()-1; i++) - { - mSelectedThumbnailItems.values().at(i)->setSelected(true); - } - } - } - else - { - bSelectionInProgress = false; - if (0 == selectedItems().size()) - return; - - if(bCanDrag) - { - QDrag *drag = new QDrag(this); - QMimeData *mime = new QMimeData(); - - if (mMimeType.length() > 0) - mime->setData(mMimeType, QByteArray()); // trick the d&d system to register our own mime type - - drag->setMimeData(mime); - - QList qlElements; - - foreach (QGraphicsItem* item, selectedItems()) - { - if (mGraphicItems.contains(item)) - { - if (mGraphicItems.indexOf(item) <= mItemsPaths.size()){ - qlElements << mItemsPaths.at(mGraphicItems.indexOf(item)); - } - } - } - - if (qlElements.size() > 0){ - mime->setUrls(qlElements); - drag->setMimeData(mime); - drag->exec(Qt::CopyAction); - } - } - } - - QGraphicsView::mouseMoveEvent(event); -} - - -void UBThumbnailWidget::mouseReleaseEvent(QMouseEvent *event) -{ - int elapsedTimeSincePress = mClickTime.elapsed(); - prevMoveMousePos = QPoint(); - deleteLasso(); - QGraphicsView::mouseReleaseEvent(event); - - if(elapsedTimeSincePress < STARTDRAGTIME) { - emit mouseClick(itemAt(event->pos()), 0); - } -} - - -void UBThumbnailWidget::keyPressEvent(QKeyEvent *event) -{ - if (mLastSelectedThumbnail) - { - QGraphicsItem *lastSelectedGraphicsItem = dynamic_cast(mLastSelectedThumbnail); - if (!lastSelectedGraphicsItem) return; - int startSelectionIndex = mGraphicItems.indexOf(lastSelectedGraphicsItem); - int previousSelectedThumbnailIndex = startSelectionIndex + mSelectionSpan; - - switch (event->key()) - { - case Qt::Key_Down: - case Qt::Key_Up: - { - if (rowCount() <= 1) break; - if (Qt::ShiftModifier & event->modifiers()) - { - int endSelectionIndex; - if (Qt::Key_Down == event->key()) - { - endSelectionIndex = previousSelectedThumbnailIndex + columnCount(); - if (endSelectionIndex >= mGraphicItems.count()) break; - } - else - { - endSelectionIndex = previousSelectedThumbnailIndex - columnCount(); - if (endSelectionIndex < 0) break; - } - - int startIndex = startSelectionIndex < endSelectionIndex ? startSelectionIndex : endSelectionIndex; - int count = startSelectionIndex < endSelectionIndex ? endSelectionIndex - startSelectionIndex + 1 : startSelectionIndex - endSelectionIndex + 1; - mSelectionSpan = startSelectionIndex < endSelectionIndex ? (count - 1) : - (count - 1); - selectItems(startIndex, count); - } - else - { - int toSelectIndex; - if (Qt::Key_Down == event->key()) - { - toSelectIndex = previousSelectedThumbnailIndex + columnCount(); - if (toSelectIndex >= mGraphicItems.count()) break; - } - else - { - toSelectIndex = previousSelectedThumbnailIndex - columnCount(); - if (toSelectIndex < 0) break; - } - - selectItemAt(toSelectIndex, Qt::ControlModifier & event->modifiers()); - mSelectionSpan = 0; - } - } - break; - - case Qt::Key_Left: - case Qt::Key_Right: - { - QGraphicsItem *previousSelectedItem = mGraphicItems.at(previousSelectedThumbnailIndex); - UBThumbnail *previousSelectedThumbnail = dynamic_cast(previousSelectedItem); - if (!previousSelectedThumbnail) break; - - if (Qt::Key_Left == event->key()) - { - if (0 == previousSelectedThumbnail->column()) break; - } - else - { - if (previousSelectedThumbnail->column() == columnCount() - 1 || - previousSelectedThumbnailIndex == mGraphicItems.count() - 1) break; - } - - if (Qt::ShiftModifier & event->modifiers()) - { - int endSelectionIndex; - if (Qt::Key_Left == event->key()) - { - endSelectionIndex = previousSelectedThumbnailIndex - 1; - if (endSelectionIndex < 0) break; - } - else - { - endSelectionIndex = previousSelectedThumbnailIndex + 1; - if (endSelectionIndex >= mGraphicItems.count()) break; - } - - int startIndex = startSelectionIndex < endSelectionIndex ? startSelectionIndex : endSelectionIndex; - int count = startSelectionIndex < endSelectionIndex ? endSelectionIndex - startSelectionIndex + 1 : startSelectionIndex - endSelectionIndex + 1; - mSelectionSpan = startSelectionIndex < endSelectionIndex ? (count - 1) : - (count - 1); - selectItems(startIndex, count); - } - else - { - if (Qt::Key_Left == event->key()) - selectItemAt(previousSelectedThumbnailIndex - 1, Qt::ControlModifier & event->modifiers()); - else - selectItemAt(previousSelectedThumbnailIndex + 1, Qt::ControlModifier & event->modifiers()); - - mSelectionSpan = 0; - } - } - break; - - case Qt::Key_Home: - { - if (Qt::ShiftModifier & event->modifiers()) - { - mSelectionSpan = - startSelectionIndex; - selectItems(0, startSelectionIndex + 1); - } - else - { - selectItemAt(0, Qt::ControlModifier & event->modifiers()); - mSelectionSpan = 0; - } - } - break; - - case Qt::Key_End: - { - if (Qt::ShiftModifier & event->modifiers()) - { - mSelectionSpan = mGraphicItems.count() - startSelectionIndex - 1; - selectItems(startSelectionIndex, mSelectionSpan + 1); - } - else - { - selectItemAt(mGraphicItems.count() - 1, Qt::ControlModifier & event->modifiers()); - mSelectionSpan = 0; - } - } - break; - case Qt::Key_A: - { - if (Qt::ControlModifier & event->modifiers()) - selectAll(); - } - break; - } - } - QGraphicsView::keyPressEvent(event); -} - - -void UBThumbnailWidget::focusInEvent(QFocusEvent *event) -{ - Q_UNUSED(event); - - if (0 == selectedItems().count() && mGraphicItems.count() > 0 && Qt::TabFocusReason == event->reason()) - { - selectItemAt(0); - mSelectionSpan = 0; - } -} - - -void UBThumbnailWidget::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event); - - refreshScene(); - - emit resized(); -} - - -void UBThumbnailWidget::sceneSelectionChanged() -{ - emit selectionChanged(); -} - - -void UBThumbnailWidget::selectItemAt(int pIndex, bool extend) -{ - QGraphicsItem* itemToSelect = 0; - - if (pIndex >= 0 && pIndex < mGraphicItems.size()) - itemToSelect = mGraphicItems.at(pIndex); - - foreach (QGraphicsItem* item, items()) - { - if (item == itemToSelect) - { - mLastSelectedThumbnail = dynamic_cast(item); - item->setSelected(true); - ensureVisible(item); - } - else if (!extend) - { - item->setSelected(false); - } - } -} - -void UBThumbnailWidget::unselectItemAt(int pIndex) -{ - if (pIndex >= 0 && pIndex < mGraphicItems.size()) - { - QGraphicsItem *itemToUnselect = mGraphicItems.at(pIndex); - itemToUnselect->setSelected(false); - } -} - - -void UBThumbnailWidget::selectItems(int startIndex, int count) -{ - for (int i = 0; i < mGraphicItems.count(); i++) - { - mGraphicItems.at(i)->setSelected(i >= startIndex && i < startIndex + count); - } -} - - -void UBThumbnailWidget::selectAll() -{ - foreach (QGraphicsItem* item, mGraphicItems) - { - item->setSelected(true); - } -} - -int UBThumbnailWidget::rowCount() const -{ - UBThumbnail *lastThumbnail = dynamic_cast(mGraphicItems.last()); - return lastThumbnail ? lastThumbnail->row() + 1 : 0; -} - -int UBThumbnailWidget::columnCount() const -{ - UBThumbnail *lastThumbnail = dynamic_cast(mGraphicItems.last()); - if (!lastThumbnail) return 0; - int lastRow = lastThumbnail->row(); - int lastColumn = lastThumbnail->column(); - return lastRow > 0 ? (mGraphicItems.count() - lastColumn - 1) / lastRow : mGraphicItems.count(); -} - - -void UBThumbnailWidget::mouseDoubleClickEvent(QMouseEvent * event) -{ - QGraphicsItem* item = itemAt(event->pos()); - - if (item) - { - int index = mGraphicItems.indexOf(item); - emit mouseDoubleClick(item, index); - } -} - - -bool UBThumbnailWidget::thumbnailLessThan(QGraphicsItem* item1, QGraphicsItem* item2) -{ - UBThumbnail *thumbnail1 = dynamic_cast(item1); - UBThumbnail *thumbnail2 = dynamic_cast(item2); - if (thumbnail1 && thumbnail2) - { - if (thumbnail1->row() != thumbnail2->row()) - return thumbnail1->row() < thumbnail2->row(); - else - return thumbnail1->column() < thumbnail2->column(); - } - return false; -} - -void UBThumbnailWidget::deleteLasso() -{ - if (mLassoRectItem && scene()) - { - scene()->removeItem(mLassoRectItem); - delete mLassoRectItem; - mLassoRectItem = 0; - } -} - - -UBThumbnail::UBThumbnail() - : mAddedToScene(false) -{ - mSelectionItem = new QGraphicsRectItem(0, 0, 0, 0); - mSelectionItem->setPen(QPen(UBSettings::treeViewBackgroundColor, 8)); - // TODO UB 4.x fix nasty dependencies : 8 is a bit less than half of UBThumbnailWidget.mSpacing -} - -UBThumbnail::~UBThumbnail() -{ - if (mSelectionItem && !mAddedToScene) - delete mSelectionItem; -} - - -UBSceneThumbnailNavigPixmap::UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex) - : UBSceneThumbnailPixmap(pix, proxy, pSceneIndex) - , bButtonsVisible(false) - , bCanDelete(false) - , bCanMoveUp(false) - , bCanMoveDown(false) - , bCanDuplicate(false) -{ - if(0 <= UBDocumentContainer::pageFromSceneIndex(pSceneIndex)){ - setAcceptsHoverEvents(true); - setFlag(QGraphicsItem::ItemIsSelectable, true); - } -} - -UBSceneThumbnailNavigPixmap::~UBSceneThumbnailNavigPixmap() -{ - -} - -void UBSceneThumbnailNavigPixmap::hoverEnterEvent(QGraphicsSceneHoverEvent *event) -{ - event->accept(); - updateButtonsState(); - update(); -} - -void UBSceneThumbnailNavigPixmap::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) -{ - event->accept(); - bButtonsVisible = false; - update(); -} - -void UBSceneThumbnailNavigPixmap::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - Q_UNUSED(option); - Q_UNUSED(widget); - - UBSceneThumbnailPixmap::paint(painter, option, widget); - if(bButtonsVisible) - { - if(bCanDelete) - painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/close.svg")); - else - painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/closeDisabled.svg")); - if(bCanDuplicate) - painter->drawPixmap(BUTTONSIZE + BUTTONSPACING, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/duplicate.svg")); - else - painter->drawPixmap(BUTTONSIZE + BUTTONSPACING, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/duplicateDisabled.svg")); - if(bCanMoveUp) - painter->drawPixmap(2*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/moveUp.svg")); - else - painter->drawPixmap(2*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/moveUpDisabled.svg")); - if(bCanMoveDown) - painter->drawPixmap(3*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/menu.svg")); - else - painter->drawPixmap(3*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/menuDisabled.svg")); - } -} - -void UBSceneThumbnailNavigPixmap::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - QPointF p = event->pos(); - - // Here we check the position of the click and verify if it has to trig an action or not. - if(bCanDelete && p.x() >= 0 && p.x() <= BUTTONSIZE && p.y() >= 0 && p.y() <= BUTTONSIZE) - deletePage(); - if(bCanDuplicate && p.x() >= BUTTONSIZE + BUTTONSPACING && p.x() <= 2*BUTTONSIZE + BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE) - duplicatePage(); - if(bCanMoveUp && p.x() >= 2*(BUTTONSIZE + BUTTONSPACING) && p.x() <= 3*BUTTONSIZE + 2*BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE) - moveUpPage(); - if(bCanMoveDown && p.x() >= 3*(BUTTONSIZE + BUTTONSPACING) && p.x() <= 4*BUTTONSIZE + 3*BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE) - moveDownPage(); - - event->accept(); -} - -void UBSceneThumbnailNavigPixmap::updateButtonsState() -{ - - bCanDelete = false; - bCanMoveUp = false; - bCanMoveDown = false; - bCanDuplicate = false; - - if(proxy()){ - int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneIndex()); - UBDocumentController* documentController = UBApplication::documentController; - bCanDelete = documentController->pageCanBeDeleted(pageIndex); - bCanMoveUp = documentController->pageCanBeMovedUp(pageIndex); - bCanMoveDown = documentController->pageCanBeMovedDown(pageIndex); - bCanDuplicate = documentController->pageCanBeDuplicated(pageIndex); - } - - if(bCanDelete || bCanMoveUp || bCanMoveDown || bCanDuplicate) - bButtonsVisible = true; -} - -void UBSceneThumbnailNavigPixmap::deletePage() -{ - if(UBApplication::mainWindow->yesNoQuestion(QObject::tr("Remove Page"), QObject::tr("Are you sure you want to remove 1 page from the selected document '%0'?").arg(UBApplication::documentController->selectedDocument()->metaData(UBSettings::documentName).toString()))){ - UBApplication::boardController->deleteScene(sceneIndex()); - } -} - -void UBSceneThumbnailNavigPixmap::duplicatePage() -{ - UBApplication::boardController->duplicateScene(sceneIndex()); -} - -void UBSceneThumbnailNavigPixmap::moveUpPage() -{ - if (sceneIndex()!=0) - UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() - 1); -} - -void UBSceneThumbnailNavigPixmap::moveDownPage() -{ - if (sceneIndex() < UBApplication::boardController->selectedDocument()->pageCount()-1) - UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() + 1); -} - -void UBImgTextThumbnailElement::Place(int row, int col, qreal width, qreal height) -{ - int labelSpacing = 0; - if(this->caption) - { - QFontMetrics fm(this->caption->font()); - labelSpacing = UBSettings::thumbnailSpacing + fm.height(); - } - if(this->thumbnail) - { - int w = this->thumbnail->boundingRect().width(); - int h = this->thumbnail->boundingRect().height(); - - qreal scaleWidth = width / w; - qreal scaleHeight = height / h; - qreal scaleFactor = qMin(scaleWidth, scaleHeight); - UBThumbnail* pix = dynamic_cast(this->thumbnail); - - QTransform transform; - transform.scale(scaleFactor, scaleFactor); - - // Apply the scaling - this->thumbnail->setTransform(transform); - this->thumbnail->setFlag(QGraphicsItem::ItemIsSelectable, true); - - if(pix) - { - pix->setColumn(col); - pix->setRow(row); - } - - QPointF pos(border + (width - w * scaleFactor) / 2 + col * (width + border), - border + row * (height + border + labelSpacing) + (height - h * scaleFactor) / 2); - - this->thumbnail->setPos(pos); - - if(this->caption) - { - QFontMetrics fm(this->caption->font()); - QString elidedText = fm.elidedText(this->caption->toPlainText(), Qt::ElideRight, width); - - this->caption->setPlainText(elidedText); - this->caption->setWidth(fm.width(elidedText) + 2 * this->caption->document()->documentMargin()); - pos.setY(pos.y() + (height + h * scaleFactor) / 2 + 5); // What is this 5 ?? - qreal labelWidth = fm.width(elidedText); - pos.setX(border + (width - labelWidth) / 2 + col * (width + border)); - this->caption->setPos(pos); - } - } -} + +#include +#include + +#include "UBThumbnailWidget.h" +#include "UBRubberBand.h" +#include "UBMainWindow.h" + +#include "board/UBBoardController.h" + +#include "core/UBSettings.h" +#include "core/UBApplication.h" + +#include "document/UBDocumentProxy.h" +#include "document/UBDocumentController.h" + +#include "core/memcheck.h" + +UBThumbnailWidget::UBThumbnailWidget(QWidget* parent) + : QGraphicsView(parent) + , mThumbnailWidth(UBSettings::defaultThumbnailWidth) + , mSpacing(UBSettings::thumbnailSpacing) + , mLastSelectedThumbnail(0) + , mSelectionSpan(0) + , mPrevLassoRect(QRect()) + , mLassoRectItem(0) + +{ + // By default, the drag is possible + bCanDrag = true; + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); + setFrameShape(QFrame::NoFrame); + setScene(&mThumbnailsScene); + + setAlignment(Qt::AlignLeft | Qt::AlignTop); + + connect(&mThumbnailsScene, SIGNAL(selectionChanged()), this, SLOT(sceneSelectionChanged())); +} + + +UBThumbnailWidget::~UBThumbnailWidget() +{ + disconnect(&mThumbnailsScene, SIGNAL(selectionChanged())); +} + + +void UBThumbnailWidget::setThumbnailWidth(qreal pThumbnailWidth) +{ + mThumbnailWidth = pThumbnailWidth; + + refreshScene(); +} + + +void UBThumbnailWidget::setSpacing(qreal pSpacing) +{ + mSpacing = pSpacing; + + refreshScene(); +} + + +void UBThumbnailWidget::setGraphicsItems(const QList& pGraphicsItems + , const QList& pItemsPaths + , const QStringList pLabels + , const QString& pMimeType) +{ + mGraphicItems = pGraphicsItems; + mItemsPaths = pItemsPaths; + mMimeType = pMimeType; + mLabels = pLabels; + + foreach(QGraphicsItem* it, mThumbnailsScene.items()) + { + mThumbnailsScene.removeItem(it, true); + } + + // set lasso to 0 as it has been cleared as well + mLassoRectItem = 0; + + foreach (QGraphicsItem* item, pGraphicsItems) + { + if (item->scene() != &mThumbnailsScene) + { + mThumbnailsScene.addItem(item); + } + } + + mLabelsItems.clear(); + + foreach (const QString label, pLabels) + { + QFontMetrics fm(font()); + UBThumbnailTextItem *labelItem = + new UBThumbnailTextItem(label); // deleted while replace or by the scene destruction + + mThumbnailsScene.addItem(labelItem); + mLabelsItems << labelItem; + } + + refreshScene(); + + mLastSelectedThumbnail = 0; +} + + +void UBThumbnailWidget::refreshScene() +{ + int nbColumns = (geometry().width() - mSpacing) / (mThumbnailWidth + mSpacing); + + int labelSpacing = 0; + + if (mLabelsItems.size() > 0) + { + QFontMetrics fm(mLabelsItems.at(0)->font()); + labelSpacing = UBSettings::thumbnailSpacing + fm.height(); // TODO UB 4.x where is 20 from ??? configure ?? compute based on mSpacing ?? JBA Is it the font height? + } + nbColumns = qMax(nbColumns, 1); + + qreal thumbnailHeight = mThumbnailWidth / UBSettings::minScreenRatio; + + for (int i = 0; i < mGraphicItems.size(); i++) + { + QGraphicsItem* item = mGraphicItems.at(i); + + qreal scaleWidth = mThumbnailWidth / item->boundingRect().width(); + qreal scaleHeight = thumbnailHeight / item->boundingRect().height(); + + qreal scaleFactor = qMin(scaleWidth, scaleHeight); + + //bitmap should not be stretched + UBThumbnail* pix = dynamic_cast(item); + if (pix) + scaleFactor = qMin(scaleFactor, 1.0); + + QTransform transform; + transform.scale(scaleFactor, scaleFactor); + + item->setTransform(transform); + + item->setFlag(QGraphicsItem::ItemIsSelectable, true); + + int columnIndex = i % nbColumns; + int rowIndex = i / nbColumns; + + if (pix) + { + pix->setColumn(columnIndex); + pix->setRow(rowIndex); + } + + int w = item->boundingRect().width(); + int h = item->boundingRect().height(); + QPointF pos( + mSpacing + (mThumbnailWidth - w * scaleFactor) / 2 + columnIndex * (mThumbnailWidth + mSpacing), + mSpacing + rowIndex * (thumbnailHeight + mSpacing + labelSpacing) + (thumbnailHeight - h * scaleFactor) / 2); + + item->setPos(pos); + + if (mLabelsItems.size() > i) + { + QFontMetrics fm(mLabelsItems.at(i)->font(), this); + QString elidedText = fm.elidedText(mLabels.at(i), Qt::ElideRight, mThumbnailWidth); + + mLabelsItems.at(i)->setPlainText(elidedText); + mLabelsItems.at(i)->setWidth(fm.width(elidedText) + 2 * mLabelsItems.at(i)->document()->documentMargin()); + + pos.setY(pos.y() + (thumbnailHeight + h * scaleFactor) / 2 + 5); + qreal labelWidth = fm.width(elidedText); + pos.setX(mSpacing + (mThumbnailWidth - labelWidth) / 2 + columnIndex * (mThumbnailWidth + mSpacing)); + mLabelsItems.at(i)->setPos(pos); + } + } + + QScrollBar *vertScrollBar = verticalScrollBar(); + int scrollBarThickness = 0; + if (vertScrollBar && vertScrollBar->isVisible()) + scrollBarThickness = vertScrollBar->width(); + + setSceneRect(0, 0, + geometry().width() - scrollBarThickness, + mSpacing + ((((mGraphicItems.size() - 1) / nbColumns) + 1) * (thumbnailHeight + mSpacing + labelSpacing))); +} + + +QList UBThumbnailWidget::selectedItems() +{ + QList sortedSelectedItems = mThumbnailsScene.selectedItems(); + qSort(sortedSelectedItems.begin(), sortedSelectedItems.end(), thumbnailLessThan); + return sortedSelectedItems; +} + + +void UBThumbnailWidget::mousePressEvent(QMouseEvent *event) +{ + mClickTime = QTime::currentTime(); + mMousePressPos = event->pos(); + + UBSceneThumbnailPixmap* sceneItem = dynamic_cast(itemAt(mMousePressPos)); + if(sceneItem==NULL) + { + event->ignore(); + return; + } + //if(sceneItem){ + // int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneItem->sceneIndex()); + // if(pageIndex == 0){ + // event->ignore(); + // return; + // } + //} + + mMousePressScenePos = mapToScene(mMousePressPos); + QGraphicsItem* underlyingItem = itemAt(mMousePressPos); + UBThumbnail *previousSelectedThumbnail = mLastSelectedThumbnail; + + if (!dynamic_cast(underlyingItem)) + { + deleteLasso(); + + UBRubberBand rubberBand(QRubberBand::Rectangle); + QStyleOption option; + option.initFrom(&rubberBand); + + mPrevLassoRect = QRect(); + mLassoRectItem = new QGraphicsRectItem(0, scene()); + +#ifdef Q_WS_MAC + // The following code must stay in synch with \src\gui\styles\qmacstyle_mac.mm + QColor strokeColor; + strokeColor.setHsvF(0, 0, 0.86, 1.0); + mLassoRectItem->setPen(QPen(strokeColor)); + QColor fillColor(option.palette.color(QPalette::Disabled, QPalette::Highlight)); + fillColor.setHsvF(0, 0, 0.53, 0.25); + mLassoRectItem->setBrush(fillColor); +#else + // The following code must stay in synch with \src\gui\styles\qwindowsxpstyle.cpp + QColor highlight = option.palette.color(QPalette::Active, QPalette::Highlight); + mLassoRectItem->setPen(highlight.darker(120)); + QColor dimHighlight(qMin(highlight.red() / 2 + 110, 255), + qMin(highlight.green() / 2 + 110, 255), + qMin(highlight.blue() / 2 + 110, 255), + 127); + mLassoRectItem->setBrush(dimHighlight); +#endif + + mLassoRectItem->setZValue(10000); + mLassoRectItem->setRect(QRectF(mMousePressScenePos, QSizeF())); + + if (Qt::ControlModifier & event->modifiers() || Qt::ShiftModifier & event->modifiers()) + { + // mSelectedThumbnailItems = selectedItems().toSet(); + return; + } + + mSelectedThumbnailItems.clear(); + mPreviouslyIncrementalSelectedItemsX.clear(); + mPreviouslyIncrementalSelectedItemsY.clear(); + QGraphicsView::mousePressEvent(event); + } + else if (Qt::ShiftModifier & event->modifiers()) + { + if (previousSelectedThumbnail) + { + QGraphicsItem* previousSelectedItem = dynamic_cast(previousSelectedThumbnail); + if (previousSelectedItem) + { + int index1 = mGraphicItems.indexOf(previousSelectedItem); + int index2 = mGraphicItems.indexOf(underlyingItem); + if (-1 == index2) + { + mSelectedThumbnailItems = selectedItems().toSet(); + return; + } + mSelectionSpan = index2 - index1; + selectItems(qMin(index1, index2), mSelectionSpan < 0 ? - mSelectionSpan + 1 : mSelectionSpan + 1); + return; + } + } + } + else + { + mLastSelectedThumbnail = dynamic_cast(underlyingItem); + if (!underlyingItem->isSelected()) + { + int index = mGraphicItems.indexOf(underlyingItem); + selectItemAt(index, Qt::ControlModifier & event->modifiers()); + } + else + { + QGraphicsView::mousePressEvent(event); + } + if (!mLastSelectedThumbnail && mGraphicItems.count() > 0) + mLastSelectedThumbnail = dynamic_cast(mGraphicItems.at(0)); + mSelectionSpan = 0; + return; + } +} + + +void UBThumbnailWidget::mouseMoveEvent(QMouseEvent *event) +{ + int distance = (mMousePressPos - event->pos()).manhattanLength(); + + if (0 == (event->buttons() & Qt::LeftButton) || distance < QApplication::startDragDistance()) + return; + + if (mLassoRectItem) + { + bSelectionInProgress = true; + int incrementLassoMinWidth = 2; + QPointF currentScenePos = mapToScene(event->pos()); + QRectF lassoRect( + qMin(mMousePressScenePos.x(), currentScenePos.x()), qMin(mMousePressScenePos.y(), currentScenePos.y()), + qAbs(mMousePressScenePos.x() - currentScenePos.x()), qAbs(mMousePressScenePos.y() - currentScenePos.y())); + if (QPoint() == prevMoveMousePos) + prevMoveMousePos = currentScenePos; + QRectF incrementXSelection( + qMin(prevMoveMousePos.x(), currentScenePos.x()), qMin(mMousePressScenePos.y(), currentScenePos.y()), + qAbs(prevMoveMousePos.x() - currentScenePos.x())+incrementLassoMinWidth, qAbs(mMousePressScenePos.y() - currentScenePos.y())); + QRectF incrementYSelection( + qMin(mMousePressScenePos.x(), currentScenePos.x()), qMin(prevMoveMousePos.y(), currentScenePos.y()), + qAbs(mMousePressScenePos.x() - currentScenePos.x()), qAbs(prevMoveMousePos.y() - currentScenePos.y())+incrementLassoMinWidth); + + prevMoveMousePos = currentScenePos; + mLassoRectItem->setRect(lassoRect); + + QSet lassoSelectedThumbnailItems; + + QSet toUnset; + QSet toSet; + + // for horizontal moving + QSet incSelectedItemsX = scene()->items(incrementXSelection, Qt::IntersectsItemBoundingRect).toSet(); + foreach (QGraphicsItem *lassoSelectedItem, incSelectedItemsX) + { + if (lassoSelectedItem) + { + UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast(lassoSelectedItem); + if (thumbnailItem) + lassoSelectedThumbnailItems += lassoSelectedItem; + } + } + + if(lassoRect.width() < mPrevLassoRect.width()) + { + if (!lassoSelectedThumbnailItems.contains(mPreviouslyIncrementalSelectedItemsX)) + toUnset += mPreviouslyIncrementalSelectedItemsX - lassoSelectedThumbnailItems; + + } + mPreviouslyIncrementalSelectedItemsX = lassoSelectedThumbnailItems; + + toSet += lassoSelectedThumbnailItems + mPreviouslyIncrementalSelectedItemsX; + + + lassoSelectedThumbnailItems.clear(); + + // for vertical moving + + QSet incSelectedItemsY = scene()->items(incrementYSelection, Qt::IntersectsItemBoundingRect).toSet(); + foreach (QGraphicsItem *lassoSelectedItem, incSelectedItemsY) + { + if (lassoSelectedItem) + { + UBSceneThumbnailPixmap *thumbnailItem = dynamic_cast(lassoSelectedItem); + + if (thumbnailItem) + lassoSelectedThumbnailItems += lassoSelectedItem; + } + } + + if(lassoRect.height() < mPrevLassoRect.height()) + { + if (!lassoSelectedThumbnailItems.contains(mPreviouslyIncrementalSelectedItemsY)) + toUnset += mPreviouslyIncrementalSelectedItemsY - lassoSelectedThumbnailItems; + + } + mPreviouslyIncrementalSelectedItemsY = lassoSelectedThumbnailItems; + + + toSet += lassoSelectedThumbnailItems + mPreviouslyIncrementalSelectedItemsY; + + + toSet -= toUnset; + + foreach (QGraphicsItem *item, toSet) + { + item->setSelected(true); + } + + foreach (QGraphicsItem *item, toUnset) + { + item->setSelected(false); + } + + mSelectedThumbnailItems += lassoSelectedThumbnailItems; + mPrevLassoRect = lassoRect; + + if (Qt::ControlModifier & event->modifiers()) + { + for (int i = 0; i < mSelectedThumbnailItems.count()-1; i++) + { + mSelectedThumbnailItems.values().at(i)->setSelected(true); + } + } + } + else + { + bSelectionInProgress = false; + if (0 == selectedItems().size()) + return; + + if(bCanDrag) + { + QDrag *drag = new QDrag(this); + QMimeData *mime = new QMimeData(); + + if (mMimeType.length() > 0) + mime->setData(mMimeType, QByteArray()); // trick the d&d system to register our own mime type + + drag->setMimeData(mime); + + QList qlElements; + + foreach (QGraphicsItem* item, selectedItems()) + { + if (mGraphicItems.contains(item)) + { + if (mGraphicItems.indexOf(item) <= mItemsPaths.size()){ + qlElements << mItemsPaths.at(mGraphicItems.indexOf(item)); + } + } + } + + if (qlElements.size() > 0){ + mime->setUrls(qlElements); + drag->setMimeData(mime); + drag->exec(Qt::CopyAction); + } + } + } + + QGraphicsView::mouseMoveEvent(event); +} + + +void UBThumbnailWidget::mouseReleaseEvent(QMouseEvent *event) +{ + int elapsedTimeSincePress = mClickTime.elapsed(); + prevMoveMousePos = QPoint(); + deleteLasso(); + QGraphicsView::mouseReleaseEvent(event); + + if(elapsedTimeSincePress < STARTDRAGTIME) { + emit mouseClick(itemAt(event->pos()), 0); + } +} + + +void UBThumbnailWidget::keyPressEvent(QKeyEvent *event) +{ + if (mLastSelectedThumbnail) + { + QGraphicsItem *lastSelectedGraphicsItem = dynamic_cast(mLastSelectedThumbnail); + if (!lastSelectedGraphicsItem) return; + int startSelectionIndex = mGraphicItems.indexOf(lastSelectedGraphicsItem); + int previousSelectedThumbnailIndex = startSelectionIndex + mSelectionSpan; + + switch (event->key()) + { + case Qt::Key_Down: + case Qt::Key_Up: + { + if (rowCount() <= 1) break; + if (Qt::ShiftModifier & event->modifiers()) + { + int endSelectionIndex; + if (Qt::Key_Down == event->key()) + { + endSelectionIndex = previousSelectedThumbnailIndex + columnCount(); + if (endSelectionIndex >= mGraphicItems.count()) break; + } + else + { + endSelectionIndex = previousSelectedThumbnailIndex - columnCount(); + if (endSelectionIndex < 0) break; + } + + int startIndex = startSelectionIndex < endSelectionIndex ? startSelectionIndex : endSelectionIndex; + int count = startSelectionIndex < endSelectionIndex ? endSelectionIndex - startSelectionIndex + 1 : startSelectionIndex - endSelectionIndex + 1; + mSelectionSpan = startSelectionIndex < endSelectionIndex ? (count - 1) : - (count - 1); + selectItems(startIndex, count); + } + else + { + int toSelectIndex; + if (Qt::Key_Down == event->key()) + { + toSelectIndex = previousSelectedThumbnailIndex + columnCount(); + if (toSelectIndex >= mGraphicItems.count()) break; + } + else + { + toSelectIndex = previousSelectedThumbnailIndex - columnCount(); + if (toSelectIndex < 0) break; + } + + selectItemAt(toSelectIndex, Qt::ControlModifier & event->modifiers()); + mSelectionSpan = 0; + } + } + break; + + case Qt::Key_Left: + case Qt::Key_Right: + { + QGraphicsItem *previousSelectedItem = mGraphicItems.at(previousSelectedThumbnailIndex); + UBThumbnail *previousSelectedThumbnail = dynamic_cast(previousSelectedItem); + if (!previousSelectedThumbnail) break; + + if (Qt::Key_Left == event->key()) + { + if (0 == previousSelectedThumbnail->column()) break; + } + else + { + if (previousSelectedThumbnail->column() == columnCount() - 1 || + previousSelectedThumbnailIndex == mGraphicItems.count() - 1) break; + } + + if (Qt::ShiftModifier & event->modifiers()) + { + int endSelectionIndex; + if (Qt::Key_Left == event->key()) + { + endSelectionIndex = previousSelectedThumbnailIndex - 1; + if (endSelectionIndex < 0) break; + } + else + { + endSelectionIndex = previousSelectedThumbnailIndex + 1; + if (endSelectionIndex >= mGraphicItems.count()) break; + } + + int startIndex = startSelectionIndex < endSelectionIndex ? startSelectionIndex : endSelectionIndex; + int count = startSelectionIndex < endSelectionIndex ? endSelectionIndex - startSelectionIndex + 1 : startSelectionIndex - endSelectionIndex + 1; + mSelectionSpan = startSelectionIndex < endSelectionIndex ? (count - 1) : - (count - 1); + selectItems(startIndex, count); + } + else + { + if (Qt::Key_Left == event->key()) + selectItemAt(previousSelectedThumbnailIndex - 1, Qt::ControlModifier & event->modifiers()); + else + selectItemAt(previousSelectedThumbnailIndex + 1, Qt::ControlModifier & event->modifiers()); + + mSelectionSpan = 0; + } + } + break; + + case Qt::Key_Home: + { + if (Qt::ShiftModifier & event->modifiers()) + { + mSelectionSpan = - startSelectionIndex; + selectItems(0, startSelectionIndex + 1); + } + else + { + selectItemAt(0, Qt::ControlModifier & event->modifiers()); + mSelectionSpan = 0; + } + } + break; + + case Qt::Key_End: + { + if (Qt::ShiftModifier & event->modifiers()) + { + mSelectionSpan = mGraphicItems.count() - startSelectionIndex - 1; + selectItems(startSelectionIndex, mSelectionSpan + 1); + } + else + { + selectItemAt(mGraphicItems.count() - 1, Qt::ControlModifier & event->modifiers()); + mSelectionSpan = 0; + } + } + break; + case Qt::Key_A: + { + if (Qt::ControlModifier & event->modifiers()) + selectAll(); + } + break; + } + } + QGraphicsView::keyPressEvent(event); +} + + +void UBThumbnailWidget::focusInEvent(QFocusEvent *event) +{ + Q_UNUSED(event); + + if (0 == selectedItems().count() && mGraphicItems.count() > 0 && Qt::TabFocusReason == event->reason()) + { + selectItemAt(0); + mSelectionSpan = 0; + } +} + + +void UBThumbnailWidget::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + + refreshScene(); + + emit resized(); +} + + +void UBThumbnailWidget::sceneSelectionChanged() +{ + emit selectionChanged(); +} + + +void UBThumbnailWidget::selectItemAt(int pIndex, bool extend) +{ + QGraphicsItem* itemToSelect = 0; + + if (pIndex >= 0 && pIndex < mGraphicItems.size()) + itemToSelect = mGraphicItems.at(pIndex); + + foreach (QGraphicsItem* item, items()) + { + if (item == itemToSelect) + { + mLastSelectedThumbnail = dynamic_cast(item); + item->setSelected(true); + ensureVisible(item); + } + else if (!extend) + { + item->setSelected(false); + } + } +} + +void UBThumbnailWidget::unselectItemAt(int pIndex) +{ + if (pIndex >= 0 && pIndex < mGraphicItems.size()) + { + QGraphicsItem *itemToUnselect = mGraphicItems.at(pIndex); + itemToUnselect->setSelected(false); + } +} + + +void UBThumbnailWidget::selectItems(int startIndex, int count) +{ + for (int i = 0; i < mGraphicItems.count(); i++) + { + mGraphicItems.at(i)->setSelected(i >= startIndex && i < startIndex + count); + } +} + + +void UBThumbnailWidget::selectAll() +{ + foreach (QGraphicsItem* item, mGraphicItems) + { + item->setSelected(true); + } +} + +int UBThumbnailWidget::rowCount() const +{ + UBThumbnail *lastThumbnail = dynamic_cast(mGraphicItems.last()); + return lastThumbnail ? lastThumbnail->row() + 1 : 0; +} + +int UBThumbnailWidget::columnCount() const +{ + UBThumbnail *lastThumbnail = dynamic_cast(mGraphicItems.last()); + if (!lastThumbnail) return 0; + int lastRow = lastThumbnail->row(); + int lastColumn = lastThumbnail->column(); + return lastRow > 0 ? (mGraphicItems.count() - lastColumn - 1) / lastRow : mGraphicItems.count(); +} + + +void UBThumbnailWidget::mouseDoubleClickEvent(QMouseEvent * event) +{ + QGraphicsItem* item = itemAt(event->pos()); + + if (item) + { + int index = mGraphicItems.indexOf(item); + emit mouseDoubleClick(item, index); + } +} + + +bool UBThumbnailWidget::thumbnailLessThan(QGraphicsItem* item1, QGraphicsItem* item2) +{ + UBThumbnail *thumbnail1 = dynamic_cast(item1); + UBThumbnail *thumbnail2 = dynamic_cast(item2); + if (thumbnail1 && thumbnail2) + { + if (thumbnail1->row() != thumbnail2->row()) + return thumbnail1->row() < thumbnail2->row(); + else + return thumbnail1->column() < thumbnail2->column(); + } + return false; +} + +void UBThumbnailWidget::deleteLasso() +{ + if (mLassoRectItem && scene()) + { + scene()->removeItem(mLassoRectItem); + delete mLassoRectItem; + mLassoRectItem = 0; + } +} + + +UBThumbnail::UBThumbnail() + : mAddedToScene(false) +{ + mSelectionItem = new QGraphicsRectItem(0, 0, 0, 0); + mSelectionItem->setPen(QPen(UBSettings::treeViewBackgroundColor, 8)); + // TODO UB 4.x fix nasty dependencies : 8 is a bit less than half of UBThumbnailWidget.mSpacing +} + +UBThumbnail::~UBThumbnail() +{ + if (mSelectionItem && !mAddedToScene) + delete mSelectionItem; +} + + +UBSceneThumbnailNavigPixmap::UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex) + : UBSceneThumbnailPixmap(pix, proxy, pSceneIndex) + , bButtonsVisible(false) + , bCanDelete(false) + , bCanMoveUp(false) + , bCanMoveDown(false) + , bCanDuplicate(false) +{ + if(0 <= UBDocumentContainer::pageFromSceneIndex(pSceneIndex)){ + setAcceptsHoverEvents(true); + setFlag(QGraphicsItem::ItemIsSelectable, true); + } +} + +UBSceneThumbnailNavigPixmap::~UBSceneThumbnailNavigPixmap() +{ + +} + +void UBSceneThumbnailNavigPixmap::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + event->accept(); + updateButtonsState(); + update(); +} + +void UBSceneThumbnailNavigPixmap::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + event->accept(); + bButtonsVisible = false; + update(); +} + +void UBSceneThumbnailNavigPixmap::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + UBSceneThumbnailPixmap::paint(painter, option, widget); + if(bButtonsVisible) + { + if(bCanDelete) + painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/close.svg")); + else + painter->drawPixmap(0, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/closeDisabled.svg")); + if(bCanDuplicate) + painter->drawPixmap(BUTTONSIZE + BUTTONSPACING, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/duplicate.svg")); + else + painter->drawPixmap(BUTTONSIZE + BUTTONSPACING, 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/duplicateDisabled.svg")); + if(bCanMoveUp) + painter->drawPixmap(2*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/moveUp.svg")); + else + painter->drawPixmap(2*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/moveUpDisabled.svg")); + if(bCanMoveDown) + painter->drawPixmap(3*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/menu.svg")); + else + painter->drawPixmap(3*(BUTTONSIZE + BUTTONSPACING), 0, BUTTONSIZE, BUTTONSIZE, QPixmap(":images/menuDisabled.svg")); + } +} + +void UBSceneThumbnailNavigPixmap::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QPointF p = event->pos(); + + // Here we check the position of the click and verify if it has to trig an action or not. + if(bCanDelete && p.x() >= 0 && p.x() <= BUTTONSIZE && p.y() >= 0 && p.y() <= BUTTONSIZE) + deletePage(); + if(bCanDuplicate && p.x() >= BUTTONSIZE + BUTTONSPACING && p.x() <= 2*BUTTONSIZE + BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE) + duplicatePage(); + if(bCanMoveUp && p.x() >= 2*(BUTTONSIZE + BUTTONSPACING) && p.x() <= 3*BUTTONSIZE + 2*BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE) + moveUpPage(); + if(bCanMoveDown && p.x() >= 3*(BUTTONSIZE + BUTTONSPACING) && p.x() <= 4*BUTTONSIZE + 3*BUTTONSPACING && p.y() >= 0 && p.y() <= BUTTONSIZE) + moveDownPage(); + + event->accept(); +} + +void UBSceneThumbnailNavigPixmap::updateButtonsState() +{ + + bCanDelete = false; + bCanMoveUp = false; + bCanMoveDown = false; + bCanDuplicate = false; + + if(proxy()){ + int pageIndex = UBDocumentContainer::pageFromSceneIndex(sceneIndex()); + UBDocumentController* documentController = UBApplication::documentController; + bCanDelete = documentController->pageCanBeDeleted(pageIndex); + bCanMoveUp = documentController->pageCanBeMovedUp(pageIndex); + bCanMoveDown = documentController->pageCanBeMovedDown(pageIndex); + bCanDuplicate = documentController->pageCanBeDuplicated(pageIndex); + } + + if(bCanDelete || bCanMoveUp || bCanMoveDown || bCanDuplicate) + bButtonsVisible = true; +} + +void UBSceneThumbnailNavigPixmap::deletePage() +{ + if(UBApplication::mainWindow->yesNoQuestion(QObject::tr("Remove Page"), QObject::tr("Are you sure you want to remove 1 page from the selected document '%0'?").arg(UBApplication::documentController->selectedDocument()->metaData(UBSettings::documentName).toString()))){ + UBApplication::boardController->deleteScene(sceneIndex()); + } +} + +void UBSceneThumbnailNavigPixmap::duplicatePage() +{ + UBApplication::boardController->duplicateScene(sceneIndex()); +} + +void UBSceneThumbnailNavigPixmap::moveUpPage() +{ + if (sceneIndex()!=0) + UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() - 1); +} + +void UBSceneThumbnailNavigPixmap::moveDownPage() +{ + if (sceneIndex() < UBApplication::boardController->selectedDocument()->pageCount()-1) + UBApplication::boardController->moveSceneToIndex(sceneIndex(), sceneIndex() + 1); +} + +void UBImgTextThumbnailElement::Place(int row, int col, qreal width, qreal height) +{ + int labelSpacing = 0; + if(this->caption) + { + QFontMetrics fm(this->caption->font()); + labelSpacing = UBSettings::thumbnailSpacing + fm.height(); + } + if(this->thumbnail) + { + int w = this->thumbnail->boundingRect().width(); + int h = this->thumbnail->boundingRect().height(); + + qreal scaleWidth = width / w; + qreal scaleHeight = height / h; + qreal scaleFactor = qMin(scaleWidth, scaleHeight); + UBThumbnail* pix = dynamic_cast(this->thumbnail); + + QTransform transform; + transform.scale(scaleFactor, scaleFactor); + + // Apply the scaling + this->thumbnail->setTransform(transform); + this->thumbnail->setFlag(QGraphicsItem::ItemIsSelectable, true); + + if(pix) + { + pix->setColumn(col); + pix->setRow(row); + } + + QPointF pos(border + (width - w * scaleFactor) / 2 + col * (width + border), + border + row * (height + border + labelSpacing) + (height - h * scaleFactor) / 2); + + this->thumbnail->setPos(pos); + + if(this->caption) + { + QFontMetrics fm(this->caption->font()); + QString elidedText = fm.elidedText(this->caption->toPlainText(), Qt::ElideRight, width); + + this->caption->setPlainText(elidedText); + this->caption->setWidth(fm.width(elidedText) + 2 * this->caption->document()->documentMargin()); + pos.setY(pos.y() + (height + h * scaleFactor) / 2 + 5); // What is this 5 ?? + qreal labelWidth = fm.width(elidedText); + pos.setX(border + (width - labelWidth) / 2 + col * (width + border)); + this->caption->setPos(pos); + } + } +} diff --git a/src/gui/UBThumbnailWidget.h b/src/gui/UBThumbnailWidget.h index 4c4b6b09..bf235c61 100644 --- a/src/gui/UBThumbnailWidget.h +++ b/src/gui/UBThumbnailWidget.h @@ -19,417 +19,417 @@ * along with Open-Sankoré. If not, see . */ - - -#ifndef UBTHUMBNAILWIDGET_H_ -#define UBTHUMBNAILWIDGET_H_ - -#include -#include -#include -#include - -#include "frameworks/UBCoreGraphicsScene.h" -#include "core/UBSettings.h" -#include "domain/UBItem.h" - -#define STARTDRAGTIME 1000000 -#define BUTTONSIZE 48 -#define BUTTONSPACING 5 - -class UBDocumentProxy; -class UBThumbnailTextItem; -class UBThumbnail; - -class UBThumbnailWidget : public QGraphicsView -{ - Q_OBJECT; - - public: - UBThumbnailWidget(QWidget* parent); - virtual ~UBThumbnailWidget(); - - QList selectedItems(); - void selectItemAt(int pIndex, bool extend = false); - void unselectItemAt(int pIndex); - - qreal thumbnailWidth() - { - return mThumbnailWidth; - } - - void setBackgroundBrush(const QBrush& brush) - { - mThumbnailsScene.setBackgroundBrush(brush); - } - - public slots: - void setThumbnailWidth(qreal pThumbnailWidth); - void setSpacing(qreal pSpacing); - virtual void setGraphicsItems(const QList& pGraphicsItems, const QList& pItemPaths, const QStringList pLabels = QStringList(), const QString& pMimeType = QString("")); - void refreshScene(); - void sceneSelectionChanged(); - - signals: - void resized(); - void selectionChanged(); - void mouseDoubleClick(QGraphicsItem* item, int index); - void mouseClick(QGraphicsItem* item, int index); - - - protected: - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void resizeEvent(QResizeEvent * event); - void mouseDoubleClickEvent(QMouseEvent * event); - - virtual void keyPressEvent(QKeyEvent *event); - virtual void focusInEvent(QFocusEvent *event); - - QList mGraphicItems; - QList mLabelsItems; - QPointF mMousePressScenePos; - QPoint mMousePressPos; - - protected: - qreal spacing() { return mSpacing; } - QList mItemsPaths; - QStringList mLabels; - bool bSelectionInProgress; - bool bCanDrag; - - private: - void selectAll(); - void selectItems(int startIndex, int count); - int rowCount() const; - int columnCount() const; - - static bool thumbnailLessThan(QGraphicsItem* item1, QGraphicsItem* item2); - - void deleteLasso(); - - UBCoreGraphicsScene mThumbnailsScene; - - QString mMimeType; - - QPointF prevMoveMousePos; - - qreal mThumbnailWidth; - qreal mThumbnailHeight; - qreal mSpacing; - - UBThumbnail *mLastSelectedThumbnail; - int mSelectionSpan; - QRectF mPrevLassoRect; - QGraphicsRectItem *mLassoRectItem; - QSet mSelectedThumbnailItems; - QSet mPreviouslyIncrementalSelectedItemsX; - QSet mPreviouslyIncrementalSelectedItemsY; - QTime mClickTime; -}; - - -class UBThumbnail -{ - public: - UBThumbnail(); - - virtual ~UBThumbnail(); - - QStyleOptionGraphicsItem muteStyleOption(const QStyleOptionGraphicsItem *option) - { - // Never draw the rubber band, we draw our custom selection with the DelegateFrame - QStyleOptionGraphicsItem styleOption = QStyleOptionGraphicsItem(*option); - styleOption.state &= ~QStyle::State_Selected; - - return styleOption; - } - - virtual void itemChange(QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) - { - Q_UNUSED(value); - - if ((change == QGraphicsItem::ItemSelectedHasChanged - || change == QGraphicsItem::ItemTransformHasChanged - || change == QGraphicsItem::ItemPositionHasChanged) - && item->scene()) - { - if (item->isSelected()) - { - if (!mSelectionItem->scene()) - { - item->scene()->addItem(mSelectionItem); - mSelectionItem->setZValue(item->zValue() - 1); -// UBGraphicsItem::assignZValue(mSelectionItem, item->zValue() - 1); - mAddedToScene = true; - } - - mSelectionItem->setRect( - item->sceneBoundingRect().x() - 5, - item->sceneBoundingRect().y() - 5, - item->sceneBoundingRect().width() + 10, - item->sceneBoundingRect().height() + 10); - - mSelectionItem->show(); - - } - else - { - mSelectionItem->hide(); - } - } - } - - int column() { return mColumn; } - void setColumn(int column) { mColumn = column; } - int row() { return mRow; } - void setRow(int row) { mRow = row; } - - protected: - QGraphicsRectItem *mSelectionItem; - private: - bool mAddedToScene; - - int mColumn; - int mRow; -}; - - -class UBThumbnailSvg : public QGraphicsSvgItem, public UBThumbnail -{ - public: - UBThumbnailSvg(const QString& path) - : QGraphicsSvgItem(path) - { - setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); - } - - virtual ~UBThumbnailSvg() - { - // NOOP - } - - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - QStyleOptionGraphicsItem styleOption = UBThumbnail::muteStyleOption(option); - QGraphicsSvgItem::paint(painter, &styleOption, widget); - } - - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) - { - UBThumbnail::itemChange(this, change, value); - return QGraphicsSvgItem::itemChange(change, value); - } - -}; - - -class UBThumbnailPixmap : public QGraphicsPixmapItem, public UBThumbnail -{ - public: - UBThumbnailPixmap(const QPixmap& pix) - : QGraphicsPixmapItem(pix) - { - setTransformationMode(Qt::SmoothTransformation); // UB 4.3 may be expensive -- make configurable - setShapeMode(QGraphicsPixmapItem::BoundingRectShape); - setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); - } - - virtual ~UBThumbnailPixmap() - { - // NOOP - } - - virtual QPainterPath shape () const - { - QPainterPath path; - path.addRect(boundingRect()); - return path; - } - - - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - QStyleOptionGraphicsItem styleOption = UBThumbnail::muteStyleOption(option); - QGraphicsPixmapItem::paint(painter, &styleOption, widget); - } - - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) - { - UBThumbnail::itemChange(this, change, value); - return QGraphicsPixmapItem::itemChange(change, value); - } -}; - - -class UBSceneThumbnailPixmap : public UBThumbnailPixmap -{ - public: - UBSceneThumbnailPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex) - : UBThumbnailPixmap(pix) - , mProxy(proxy) - , mSceneIndex(pSceneIndex) - { - // NOOP - } - - virtual ~UBSceneThumbnailPixmap() - { - // NOOP - } - - UBDocumentProxy* proxy() - { - return mProxy; - } - - int sceneIndex() - { - return mSceneIndex; - } - - void highlight() - { - //NOOP - } - - private: - UBDocumentProxy* mProxy; - int mSceneIndex; -}; - -class UBSceneThumbnailNavigPixmap : public UBSceneThumbnailPixmap -{ - public: - UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex); - ~UBSceneThumbnailNavigPixmap(); - - protected: - void hoverEnterEvent(QGraphicsSceneHoverEvent *event); - void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - void mousePressEvent(QGraphicsSceneMouseEvent *event); - - private: - void updateButtonsState(); - void deletePage(); - void duplicatePage(); - void moveUpPage(); - void moveDownPage(); - - bool bButtonsVisible; - bool bCanDelete; - bool bCanMoveUp; - bool bCanMoveDown; - bool bCanDuplicate; -}; - -class UBThumbnailVideo : public UBThumbnailPixmap -{ - public: - UBThumbnailVideo(const QUrl &path) - : UBThumbnailPixmap(QPixmap(":/images/movie.svg")) - , mPath(path) - { - // NOOP - } - - virtual ~UBThumbnailVideo() - { - // NOOP - } - - QUrl path() - { - return mPath; - } - - private: - - QUrl mPath; -}; - -class UBThumbnailTextItem : public QGraphicsTextItem -{ - public: - UBThumbnailTextItem(const QString& text) - : QGraphicsTextItem(text) - , mUnelidedText(text) - , mIsHighlighted(false) - { - setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); - } - - QRectF boundingRect() const { return QRectF(QPointF(0.0, 0.0), QSize(mWidth, QFontMetricsF(font()).height() + 5));} - - void setWidth(qreal pWidth) - { - if (mWidth != pWidth) - { - prepareGeometryChange(); - mWidth = pWidth; - computeText(); - } - }; - - qreal width() {return mWidth;} - - void highlight() - { - if (!mIsHighlighted) - { - mIsHighlighted = true; - computeText(); - } - } - - void computeText() - { - QFontMetricsF fm(font()); - QString elidedText = fm.elidedText(mUnelidedText, Qt::ElideRight, mWidth); - - if (mIsHighlighted) - { - setHtml("" + elidedText + ""); - } - else - { - setPlainText(elidedText); - } - } - - private: - qreal mWidth; - QString mUnelidedText; - bool mIsHighlighted; -}; - -class UBImgTextThumbnailElement -{ -private: - UBSceneThumbnailNavigPixmap* thumbnail; - UBThumbnailTextItem* caption; - int border; - -public: - UBImgTextThumbnailElement(UBSceneThumbnailNavigPixmap* thumb, UBThumbnailTextItem* text): border(0) - { - this->thumbnail = thumb; - this->caption = text; - } - - UBSceneThumbnailNavigPixmap* getThumbnail() const { return this->thumbnail; } - void setThumbnail(UBSceneThumbnailNavigPixmap* newGItem) { this->thumbnail = newGItem; } - - UBThumbnailTextItem* getCaption() const { return this->caption; } - void setCaption(UBThumbnailTextItem* newcaption) { this->caption = newcaption; } - - void Place(int row, int col, qreal width, qreal height); - - int getBorder() const { return this->border; } - void setBorder(int newBorder) { this->border = newBorder; } -}; - - -#endif /* UBTHUMBNAILWIDGET_H_ */ + + +#ifndef UBTHUMBNAILWIDGET_H_ +#define UBTHUMBNAILWIDGET_H_ + +#include +#include +#include +#include + +#include "frameworks/UBCoreGraphicsScene.h" +#include "core/UBSettings.h" +#include "domain/UBItem.h" + +#define STARTDRAGTIME 1000000 +#define BUTTONSIZE 48 +#define BUTTONSPACING 5 + +class UBDocumentProxy; +class UBThumbnailTextItem; +class UBThumbnail; + +class UBThumbnailWidget : public QGraphicsView +{ + Q_OBJECT; + + public: + UBThumbnailWidget(QWidget* parent); + virtual ~UBThumbnailWidget(); + + QList selectedItems(); + void selectItemAt(int pIndex, bool extend = false); + void unselectItemAt(int pIndex); + + qreal thumbnailWidth() + { + return mThumbnailWidth; + } + + void setBackgroundBrush(const QBrush& brush) + { + mThumbnailsScene.setBackgroundBrush(brush); + } + + public slots: + void setThumbnailWidth(qreal pThumbnailWidth); + void setSpacing(qreal pSpacing); + virtual void setGraphicsItems(const QList& pGraphicsItems, const QList& pItemPaths, const QStringList pLabels = QStringList(), const QString& pMimeType = QString("")); + void refreshScene(); + void sceneSelectionChanged(); + + signals: + void resized(); + void selectionChanged(); + void mouseDoubleClick(QGraphicsItem* item, int index); + void mouseClick(QGraphicsItem* item, int index); + + + protected: + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void resizeEvent(QResizeEvent * event); + void mouseDoubleClickEvent(QMouseEvent * event); + + virtual void keyPressEvent(QKeyEvent *event); + virtual void focusInEvent(QFocusEvent *event); + + QList mGraphicItems; + QList mLabelsItems; + QPointF mMousePressScenePos; + QPoint mMousePressPos; + + protected: + qreal spacing() { return mSpacing; } + QList mItemsPaths; + QStringList mLabels; + bool bSelectionInProgress; + bool bCanDrag; + + private: + void selectAll(); + void selectItems(int startIndex, int count); + int rowCount() const; + int columnCount() const; + + static bool thumbnailLessThan(QGraphicsItem* item1, QGraphicsItem* item2); + + void deleteLasso(); + + UBCoreGraphicsScene mThumbnailsScene; + + QString mMimeType; + + QPointF prevMoveMousePos; + + qreal mThumbnailWidth; + qreal mThumbnailHeight; + qreal mSpacing; + + UBThumbnail *mLastSelectedThumbnail; + int mSelectionSpan; + QRectF mPrevLassoRect; + QGraphicsRectItem *mLassoRectItem; + QSet mSelectedThumbnailItems; + QSet mPreviouslyIncrementalSelectedItemsX; + QSet mPreviouslyIncrementalSelectedItemsY; + QTime mClickTime; +}; + + +class UBThumbnail +{ + public: + UBThumbnail(); + + virtual ~UBThumbnail(); + + QStyleOptionGraphicsItem muteStyleOption(const QStyleOptionGraphicsItem *option) + { + // Never draw the rubber band, we draw our custom selection with the DelegateFrame + QStyleOptionGraphicsItem styleOption = QStyleOptionGraphicsItem(*option); + styleOption.state &= ~QStyle::State_Selected; + + return styleOption; + } + + virtual void itemChange(QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) + { + Q_UNUSED(value); + + if ((change == QGraphicsItem::ItemSelectedHasChanged + || change == QGraphicsItem::ItemTransformHasChanged + || change == QGraphicsItem::ItemPositionHasChanged) + && item->scene()) + { + if (item->isSelected()) + { + if (!mSelectionItem->scene()) + { + item->scene()->addItem(mSelectionItem); + mSelectionItem->setZValue(item->zValue() - 1); +// UBGraphicsItem::assignZValue(mSelectionItem, item->zValue() - 1); + mAddedToScene = true; + } + + mSelectionItem->setRect( + item->sceneBoundingRect().x() - 5, + item->sceneBoundingRect().y() - 5, + item->sceneBoundingRect().width() + 10, + item->sceneBoundingRect().height() + 10); + + mSelectionItem->show(); + + } + else + { + mSelectionItem->hide(); + } + } + } + + int column() { return mColumn; } + void setColumn(int column) { mColumn = column; } + int row() { return mRow; } + void setRow(int row) { mRow = row; } + + protected: + QGraphicsRectItem *mSelectionItem; + private: + bool mAddedToScene; + + int mColumn; + int mRow; +}; + + +class UBThumbnailSvg : public QGraphicsSvgItem, public UBThumbnail +{ + public: + UBThumbnailSvg(const QString& path) + : QGraphicsSvgItem(path) + { + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + } + + virtual ~UBThumbnailSvg() + { + // NOOP + } + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + QStyleOptionGraphicsItem styleOption = UBThumbnail::muteStyleOption(option); + QGraphicsSvgItem::paint(painter, &styleOption, widget); + } + + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) + { + UBThumbnail::itemChange(this, change, value); + return QGraphicsSvgItem::itemChange(change, value); + } + +}; + + +class UBThumbnailPixmap : public QGraphicsPixmapItem, public UBThumbnail +{ + public: + UBThumbnailPixmap(const QPixmap& pix) + : QGraphicsPixmapItem(pix) + { + setTransformationMode(Qt::SmoothTransformation); // UB 4.3 may be expensive -- make configurable + setShapeMode(QGraphicsPixmapItem::BoundingRectShape); + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + } + + virtual ~UBThumbnailPixmap() + { + // NOOP + } + + virtual QPainterPath shape () const + { + QPainterPath path; + path.addRect(boundingRect()); + return path; + } + + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + QStyleOptionGraphicsItem styleOption = UBThumbnail::muteStyleOption(option); + QGraphicsPixmapItem::paint(painter, &styleOption, widget); + } + + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) + { + UBThumbnail::itemChange(this, change, value); + return QGraphicsPixmapItem::itemChange(change, value); + } +}; + + +class UBSceneThumbnailPixmap : public UBThumbnailPixmap +{ + public: + UBSceneThumbnailPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex) + : UBThumbnailPixmap(pix) + , mProxy(proxy) + , mSceneIndex(pSceneIndex) + { + // NOOP + } + + virtual ~UBSceneThumbnailPixmap() + { + // NOOP + } + + UBDocumentProxy* proxy() + { + return mProxy; + } + + int sceneIndex() + { + return mSceneIndex; + } + + void highlight() + { + //NOOP + } + + private: + UBDocumentProxy* mProxy; + int mSceneIndex; +}; + +class UBSceneThumbnailNavigPixmap : public UBSceneThumbnailPixmap +{ + public: + UBSceneThumbnailNavigPixmap(const QPixmap& pix, UBDocumentProxy* proxy, int pSceneIndex); + ~UBSceneThumbnailNavigPixmap(); + + protected: + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + + private: + void updateButtonsState(); + void deletePage(); + void duplicatePage(); + void moveUpPage(); + void moveDownPage(); + + bool bButtonsVisible; + bool bCanDelete; + bool bCanMoveUp; + bool bCanMoveDown; + bool bCanDuplicate; +}; + +class UBThumbnailVideo : public UBThumbnailPixmap +{ + public: + UBThumbnailVideo(const QUrl &path) + : UBThumbnailPixmap(QPixmap(":/images/movie.svg")) + , mPath(path) + { + // NOOP + } + + virtual ~UBThumbnailVideo() + { + // NOOP + } + + QUrl path() + { + return mPath; + } + + private: + + QUrl mPath; +}; + +class UBThumbnailTextItem : public QGraphicsTextItem +{ + public: + UBThumbnailTextItem(const QString& text) + : QGraphicsTextItem(text) + , mUnelidedText(text) + , mIsHighlighted(false) + { + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + } + + QRectF boundingRect() const { return QRectF(QPointF(0.0, 0.0), QSize(mWidth, QFontMetricsF(font()).height() + 5));} + + void setWidth(qreal pWidth) + { + if (mWidth != pWidth) + { + prepareGeometryChange(); + mWidth = pWidth; + computeText(); + } + }; + + qreal width() {return mWidth;} + + void highlight() + { + if (!mIsHighlighted) + { + mIsHighlighted = true; + computeText(); + } + } + + void computeText() + { + QFontMetricsF fm(font()); + QString elidedText = fm.elidedText(mUnelidedText, Qt::ElideRight, mWidth); + + if (mIsHighlighted) + { + setHtml("" + elidedText + ""); + } + else + { + setPlainText(elidedText); + } + } + + private: + qreal mWidth; + QString mUnelidedText; + bool mIsHighlighted; +}; + +class UBImgTextThumbnailElement +{ +private: + UBSceneThumbnailNavigPixmap* thumbnail; + UBThumbnailTextItem* caption; + int border; + +public: + UBImgTextThumbnailElement(UBSceneThumbnailNavigPixmap* thumb, UBThumbnailTextItem* text): border(0) + { + this->thumbnail = thumb; + this->caption = text; + } + + UBSceneThumbnailNavigPixmap* getThumbnail() const { return this->thumbnail; } + void setThumbnail(UBSceneThumbnailNavigPixmap* newGItem) { this->thumbnail = newGItem; } + + UBThumbnailTextItem* getCaption() const { return this->caption; } + void setCaption(UBThumbnailTextItem* newcaption) { this->caption = newcaption; } + + void Place(int row, int col, qreal width, qreal height); + + int getBorder() const { return this->border; } + void setBorder(int newBorder) { this->border = newBorder; } +}; + + +#endif /* UBTHUMBNAILWIDGET_H_ */ diff --git a/tools/CrashReportViewer/CrashReporterSymbolSupplier.cpp b/tools/CrashReportViewer/CrashReporterSymbolSupplier.cpp index bf66d736..4b126d98 100644 --- a/tools/CrashReportViewer/CrashReporterSymbolSupplier.cpp +++ b/tools/CrashReportViewer/CrashReporterSymbolSupplier.cpp @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ @@ -34,39 +33,39 @@ CrashReporterSymbolSupplier::CrashReporterSymbolSupplier(QString pUniboardSymFiles) { - mUniboardSymFile.setFileName(pUniboardSymFiles); + mUniboardSymFile.setFileName(pUniboardSymFiles); } // Returns the path to the symbol file for the given module. google_breakpad::SymbolSupplier::SymbolResult CrashReporterSymbolSupplier::GetSymbolFile(const google_breakpad::CodeModule *module, - const google_breakpad::SystemInfo *system_info, - string *symbol_file) + const google_breakpad::SystemInfo *system_info, + string *symbol_file) { - QString moduleName = QString::fromStdString(module->code_file()); - if (moduleName.contains("Uniboard")) - { - *symbol_file = mUniboardSymFile.fileName().toStdString(); - return FOUND; - } + QString moduleName = QString::fromStdString(module->code_file()); + if (moduleName.contains("Uniboard")) + { + *symbol_file = mUniboardSymFile.fileName().toStdString(); + return FOUND; + } return NOT_FOUND; } // Returns the path to the symbol file for the given module. google_breakpad::SymbolSupplier::SymbolResult CrashReporterSymbolSupplier::GetSymbolFile(const google_breakpad::CodeModule *module, - const google_breakpad::SystemInfo *system_info, - string *symbol_file, - string *symbol_data) + const google_breakpad::SystemInfo *system_info, + string *symbol_file, + string *symbol_data) { - SymbolSupplier::SymbolResult s = GetSymbolFile(module, - system_info, - symbol_file); + SymbolSupplier::SymbolResult s = GetSymbolFile(module, + system_info, + symbol_file); - if (s == FOUND) { - std::ifstream in(symbol_file->c_str()); - getline(in, *symbol_data, std::string::traits_type::to_char_type( - std::string::traits_type::eof())); - in.close(); - } + if (s == FOUND) { + std::ifstream in(symbol_file->c_str()); + getline(in, *symbol_data, std::string::traits_type::to_char_type( + std::string::traits_type::eof())); + in.close(); + } - return s; + return s; } diff --git a/tools/CrashReportViewer/CrashReporterSymbolSupplier.h b/tools/CrashReportViewer/CrashReporterSymbolSupplier.h index ae7ebb61..db0095df 100644 --- a/tools/CrashReportViewer/CrashReporterSymbolSupplier.h +++ b/tools/CrashReportViewer/CrashReporterSymbolSupplier.h @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ @@ -32,22 +31,22 @@ using std::string; class CrashReporterSymbolSupplier : public google_breakpad::SymbolSupplier { public: - CrashReporterSymbolSupplier(QString pUniboardSymFiles); - virtual ~CrashReporterSymbolSupplier() {} + CrashReporterSymbolSupplier(QString pUniboardSymFiles); + virtual ~CrashReporterSymbolSupplier() {} - // Returns the path to the symbol file for the given module. - SymbolResult GetSymbolFile(const google_breakpad::CodeModule *module, - const google_breakpad::SystemInfo *system_info, - string *symbol_file); + // Returns the path to the symbol file for the given module. + SymbolResult GetSymbolFile(const google_breakpad::CodeModule *module, + const google_breakpad::SystemInfo *system_info, + string *symbol_file); - // Returns the path to the symbol file for the given module. - SymbolResult GetSymbolFile(const google_breakpad::CodeModule *module, - const google_breakpad::SystemInfo *system_info, - string *symbol_file, - string *symbol_data); + // Returns the path to the symbol file for the given module. + SymbolResult GetSymbolFile(const google_breakpad::CodeModule *module, + const google_breakpad::SystemInfo *system_info, + string *symbol_file, + string *symbol_data); private: - QFile mUniboardSymFile; + QFile mUniboardSymFile; }; #endif /* CRASHREPORTERSYMBOLSUPPLIER_H_ */ diff --git a/tools/CrashReportViewer/CrashWindow.cpp b/tools/CrashReportViewer/CrashWindow.cpp index f7ca2c17..d5c93f0c 100644 --- a/tools/CrashReportViewer/CrashWindow.cpp +++ b/tools/CrashReportViewer/CrashWindow.cpp @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ @@ -31,14 +30,14 @@ CrashWindow::CrashWindow(QWidget* parent) : QDialog(parent) mCrashReporterUi->setupUi(this); mCrashReporterUi->crashReportResult->setFont(QFont("Monaco", 11)); - connect(mCrashReporterUi->viewReportButton, SIGNAL(clicked(bool)), this, SLOT(showReport())); - connect(mCrashReporterUi->dumpFileButton, SIGNAL(clicked(bool)), this, SLOT(chooseDumpFile())); - connect(mCrashReporterUi->symFileButton, SIGNAL(clicked(bool)), this, SLOT(chooseSymboleFile())); + connect(mCrashReporterUi->viewReportButton, SIGNAL(clicked(bool)), this, SLOT(showReport())); + connect(mCrashReporterUi->dumpFileButton, SIGNAL(clicked(bool)), this, SLOT(chooseDumpFile())); + connect(mCrashReporterUi->symFileButton, SIGNAL(clicked(bool)), this, SLOT(chooseSymboleFile())); } CrashWindow::~CrashWindow() { - // NOOP + // NOOP } void CrashWindow::setDumpFilePath(const QString &fileName) @@ -48,47 +47,47 @@ void CrashWindow::setDumpFilePath(const QString &fileName) void CrashWindow::chooseDumpFile() { - QSettings settings("Mnemis", "CrashReporter"); - QString dumpFileName = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); - if (settings.contains("DumpFileName")) - { - dumpFileName = settings.value("DumpFileName").toString(); - } - QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), - dumpFileName, - tr("Dump file (*.dmp)")); - settings.setValue("DumpFileName", QVariant(fileName)); + QSettings settings("Mnemis", "CrashReporter"); + QString dumpFileName = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); + if (settings.contains("DumpFileName")) + { + dumpFileName = settings.value("DumpFileName").toString(); + } + QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), + dumpFileName, + tr("Dump file (*.dmp)")); + settings.setValue("DumpFileName", QVariant(fileName)); setDumpFilePath(fileName); } void CrashWindow::chooseSymboleFile() { - QSettings settings("Mnemis", "CrashReporter"); - QString symFileName = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); - if (settings.contains("SymFileName")) - { - symFileName = settings.value("SymFileName").toString(); - } - QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), - symFileName, - tr("Symbol file (*.sym)")); - settings.setValue("SymFileName", QVariant(fileName)); - mCrashReporterUi->symFilePath->setText(fileName); + QSettings settings("Mnemis", "CrashReporter"); + QString symFileName = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); + if (settings.contains("SymFileName")) + { + symFileName = settings.value("SymFileName").toString(); + } + QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), + symFileName, + tr("Symbol file (*.sym)")); + settings.setValue("SymFileName", QVariant(fileName)); + mCrashReporterUi->symFilePath->setText(fileName); } //============================================================================= int CrashWindow::PrintRegister(const char *name, u_int32_t value, int sequence) { - if (sequence % 4 == 0) { - mReport.append("\n"); - } + if (sequence % 4 == 0) { + mReport.append("\n"); + } // string should not exceed 200 byte!!! size_t BufSize = 2000; - char buf[BufSize]; + char buf[BufSize]; - snprintf(buf, BufSize, "%6s = 0x%08x ", name, value); - QString str = QString::fromAscii(buf); - mReport.append(str); - return ++sequence; + snprintf(buf, BufSize, "%6s = 0x%08x ", name, value); + QString str = QString::fromAscii(buf); + mReport.append(str); + return ++sequence; } //============================================================================= @@ -101,9 +100,9 @@ void CrashWindow::PrintStack(const CallStack* stack, const string &cpu) { const CodeModule *module = frame->module; // string should not exceed 200 byte!!! size_t BufSize = 2000; - char buf[BufSize]; - snprintf(buf, BufSize, "%2d ", frame_index); - mReport.append(QString::fromAscii(buf)); + char buf[BufSize]; + snprintf(buf, BufSize, "%2d ", frame_index); + mReport.append(QString::fromAscii(buf)); if (module) { // Module name (20 chars max) @@ -229,98 +228,98 @@ void CrashWindow::PrintModules(const CodeModules *modules) { u_int64_t base_address = module->base_address(); // string should not exceed 200 byte!!! size_t BufSize = 2000; - char buf[BufSize]; - - snprintf(buf, BufSize, "0x%08llx - 0x%08llx %s %s%s %s\n", - base_address, base_address + module->size() - 1, - PathnameStripper::File(module->code_file()).c_str(), - module->version().empty() ? "???" : module->version().c_str(), - main_module != NULL && base_address == main_address ? - " (main)" : "", - module->code_file().c_str()); - mReport.append(QString::fromAscii(buf)); + char buf[BufSize]; + + snprintf(buf, BufSize, "0x%08llx - 0x%08llx %s %s%s %s\n", + base_address, base_address + module->size() - 1, + PathnameStripper::File(module->code_file()).c_str(), + module->version().empty() ? "???" : module->version().c_str(), + main_module != NULL && base_address == main_address ? + " (main)" : "", + module->code_file().c_str()); + mReport.append(QString::fromAscii(buf)); } } void CrashWindow::showReport() { - qDebug() << "compute report"; - mReport.clear(); - QString minidump_file = mCrashReporterUi->dumpFilePath->text(); - BasicSourceLineResolver resolver; - - scoped_ptr symbol_supplier( - - new CrashReporterSymbolSupplier(mCrashReporterUi->symFilePath->text())); - scoped_ptr - minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver)); - ProcessState process_state; - if (minidump_processor->Process(minidump_file.toStdString(), &process_state) != - MinidumpProcessor::PROCESS_OK) { - mReport += "MinidumpProcessor::Process failed\n"; - return; - } - const SystemInfo *system_info = process_state.system_info(); - string cpu = system_info->cpu; - // Convert the time to a string - u_int32_t time_date_stamp = process_state.time_date_stamp(); - struct tm timestruct; - gmtime_r(reinterpret_cast(&time_date_stamp), ×truct); - char timestr[20]; - // string should not exceed 200 byte!!! - size_t BufSize = 2000; - char buf[BufSize]; - strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); - snprintf(buf, BufSize, "Date: %s GMT\n", timestr); - mReport.append(QString::fromAscii(buf)); - snprintf(buf, BufSize, "Operating system: %s (%s)\n", system_info->os.c_str(), - system_info->os_version.c_str()); - mReport.append(QString::fromAscii(buf)); - snprintf(buf, BufSize, "Architecture: %s\n", cpu.c_str()); - mReport.append(QString::fromAscii(buf)); - - if (process_state.crashed()) { - snprintf(buf, BufSize, "Crash reason: %s\n", process_state.crash_reason().c_str()); - mReport.append(QString::fromAscii(buf)); - snprintf(buf, BufSize, "Crash address: 0x%llx\n", process_state.crash_address()); - mReport.append(QString::fromAscii(buf)); - } else { - mReport.append("No crash\n"); - } - - int requesting_thread = process_state.requesting_thread(); - if (requesting_thread != -1) { - mReport.append("\n"); - snprintf(buf, BufSize, "Thread %d (%s)\n", - requesting_thread, - process_state.crashed() ? "crashed" : - "requested dump, did not crash"); - mReport.append(QString::fromAscii(buf)); - PrintStack(process_state.threads()->at(requesting_thread), cpu); - } - - // Print all of the threads in the dump. - int thread_count = process_state.threads()->size(); - for (int thread_index = 0; thread_index < thread_count; ++thread_index) { - if (thread_index != requesting_thread) { - // Don't print the crash thread again, it was already printed. - mReport.append("\n"); - snprintf(buf, BufSize,"Thread %d\n", thread_index); - mReport.append(QString::fromAscii(buf)); - PrintStack(process_state.threads()->at(thread_index), cpu); - } - } - - // Print the crashed registers - if (requesting_thread != -1) { - snprintf(buf, BufSize,"\nThread %d:", requesting_thread); - mReport.append(QString::fromAscii(buf)); - PrintRegisters(process_state.threads()->at(requesting_thread), cpu); - } - - // Print information about modules - PrintModules(process_state.modules()); - mCrashReporterUi->crashReportResult->setPlainText(mReport); + qDebug() << "compute report"; + mReport.clear(); + QString minidump_file = mCrashReporterUi->dumpFilePath->text(); + BasicSourceLineResolver resolver; + + scoped_ptr symbol_supplier( + + new CrashReporterSymbolSupplier(mCrashReporterUi->symFilePath->text())); + scoped_ptr + minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver)); + ProcessState process_state; + if (minidump_processor->Process(minidump_file.toStdString(), &process_state) != + MinidumpProcessor::PROCESS_OK) { + mReport += "MinidumpProcessor::Process failed\n"; + return; + } + const SystemInfo *system_info = process_state.system_info(); + string cpu = system_info->cpu; + // Convert the time to a string + u_int32_t time_date_stamp = process_state.time_date_stamp(); + struct tm timestruct; + gmtime_r(reinterpret_cast(&time_date_stamp), ×truct); + char timestr[20]; + // string should not exceed 200 byte!!! + size_t BufSize = 2000; + char buf[BufSize]; + strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); + snprintf(buf, BufSize, "Date: %s GMT\n", timestr); + mReport.append(QString::fromAscii(buf)); + snprintf(buf, BufSize, "Operating system: %s (%s)\n", system_info->os.c_str(), + system_info->os_version.c_str()); + mReport.append(QString::fromAscii(buf)); + snprintf(buf, BufSize, "Architecture: %s\n", cpu.c_str()); + mReport.append(QString::fromAscii(buf)); + + if (process_state.crashed()) { + snprintf(buf, BufSize, "Crash reason: %s\n", process_state.crash_reason().c_str()); + mReport.append(QString::fromAscii(buf)); + snprintf(buf, BufSize, "Crash address: 0x%llx\n", process_state.crash_address()); + mReport.append(QString::fromAscii(buf)); + } else { + mReport.append("No crash\n"); + } + + int requesting_thread = process_state.requesting_thread(); + if (requesting_thread != -1) { + mReport.append("\n"); + snprintf(buf, BufSize, "Thread %d (%s)\n", + requesting_thread, + process_state.crashed() ? "crashed" : + "requested dump, did not crash"); + mReport.append(QString::fromAscii(buf)); + PrintStack(process_state.threads()->at(requesting_thread), cpu); + } + + // Print all of the threads in the dump. + int thread_count = process_state.threads()->size(); + for (int thread_index = 0; thread_index < thread_count; ++thread_index) { + if (thread_index != requesting_thread) { + // Don't print the crash thread again, it was already printed. + mReport.append("\n"); + snprintf(buf, BufSize,"Thread %d\n", thread_index); + mReport.append(QString::fromAscii(buf)); + PrintStack(process_state.threads()->at(thread_index), cpu); + } + } + + // Print the crashed registers + if (requesting_thread != -1) { + snprintf(buf, BufSize,"\nThread %d:", requesting_thread); + mReport.append(QString::fromAscii(buf)); + PrintRegisters(process_state.threads()->at(requesting_thread), cpu); + } + + // Print information about modules + PrintModules(process_state.modules()); + mCrashReporterUi->crashReportResult->setPlainText(mReport); } diff --git a/tools/CrashReportViewer/CrashWindow.h b/tools/CrashReportViewer/CrashWindow.h index d7e5c578..89a5907a 100644 --- a/tools/CrashReportViewer/CrashWindow.h +++ b/tools/CrashReportViewer/CrashWindow.h @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ @@ -59,23 +58,23 @@ namespace Ui class CrashWindow : public QDialog { - Q_OBJECT; + Q_OBJECT; public: - CrashWindow(QWidget* parent = 0); - virtual ~CrashWindow(); + CrashWindow(QWidget* parent = 0); + virtual ~CrashWindow(); void setDumpFilePath(const QString &fileName); private slots: - void showReport(); - void chooseDumpFile(); - void chooseSymboleFile(); + void showReport(); + void chooseDumpFile(); + void chooseSymboleFile(); private: - int PrintRegister(const char *name, u_int32_t value, int sequence); - void PrintStack(const CallStack* stack, const string &cpu); - void PrintRegisters(const CallStack *stack, const string &cpu); - void PrintModules(const CodeModules *modules); + int PrintRegister(const char *name, u_int32_t value, int sequence); + void PrintStack(const CallStack* stack, const string &cpu); + void PrintRegisters(const CallStack *stack, const string &cpu); + void PrintModules(const CodeModules *modules); Ui::UniboardCrashreporter* mCrashReporterUi; QString mReport; }; diff --git a/tools/CrashReportViewer/main.cpp b/tools/CrashReportViewer/main.cpp index f05ec801..a3a00122 100644 --- a/tools/CrashReportViewer/main.cpp +++ b/tools/CrashReportViewer/main.cpp @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ diff --git a/tools/pdf2image/core/UBPlatformUtils.cpp b/tools/pdf2image/core/UBPlatformUtils.cpp index 5e7404d6..8a09fd5e 100644 --- a/tools/pdf2image/core/UBPlatformUtils.cpp +++ b/tools/pdf2image/core/UBPlatformUtils.cpp @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ diff --git a/tools/pdf2image/core/UBPlatformUtils.h b/tools/pdf2image/core/UBPlatformUtils.h index 67f91769..58739593 100644 --- a/tools/pdf2image/core/UBPlatformUtils.h +++ b/tools/pdf2image/core/UBPlatformUtils.h @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ diff --git a/tools/pdf2image/pdf2image.cpp b/tools/pdf2image/pdf2image.cpp index 289cc061..ae47b5f8 100644 --- a/tools/pdf2image/pdf2image.cpp +++ b/tools/pdf2image/pdf2image.cpp @@ -3,21 +3,20 @@ * * This file is part of Open-Sankoré. * - * Open-Sankoré is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation, version 2, + * Open-Sankoré 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 3 of the License, * with a specific linking exception for the OpenSSL project's * "OpenSSL" library (or with modified versions of it that use the * same license as the "OpenSSL" library). * * Open-Sankoré 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 - * Library General Public License for more details. + * 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 Library General Public - * License along with Open-Sankoré; if not, see - * . + * You should have received a copy of the GNU General Public License + * along with Open-Sankoré. If not, see . */ @@ -79,7 +78,7 @@ int main(int argc, char *argv[]) return 1; } - //qDebug() << "Converting" << pdfFile << "(" << pageNumber << ") into" << imageFormat; + //qDebug() << "Converting" << pdfFile << "(" << pageNumber << ") into" << imageFormat; QImage image(width, height, QImage::Format_ARGB32);