nextExtendedIwbElement(mExtendedElements);
- while (nextExtendedIwbElement.hasNext()) {
- writeQDomElementToXML(nextExtendedIwbElement.next());
- //TODO write iwb extended element to mIWBContentWriter
- }
-
- return true;
-}
-
-// extended element options
-// editable, background, locked are supported for now
-
-QDomElement UBCFFAdaptor::UBToCFFConverter::parseGroupsPageSection(const QDomElement &groupRoot)
-{
-// First sankore side implementation needed. TODO in Sankore 1.5
- if (!groupRoot.hasChildNodes()) {
- qDebug() << "Group root is empty";
- return QDomElement();
- }
-
- QDomElement groupElement = groupRoot.firstChildElement();
-
- while (!groupElement.isNull()) {
- QDomElement extendedElement = mDataModel->createElementNS(iwbNS, groupElement.tagName());
- QDomElement groupChildElement = groupElement.firstChildElement();
- while (!groupChildElement.isNull()) {
- QDomElement extSubElement = mDataModel->createElementNS(iwbNS, groupChildElement.tagName());
- extSubElement.setAttribute(aRef, groupChildElement.attribute(aID, QUuid().toString()));
- extendedElement.appendChild(extSubElement);
-
- groupChildElement = groupChildElement.nextSiblingElement();
- }
-
- mExtendedElements.append(extendedElement);
-
- groupElement = groupElement.nextSiblingElement();
- }
-
- qDebug() << "parsing ubz group section";
- return groupRoot;
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::getDstContentFolderName(const QString &elementType)
-{
- QString sRet;
- QString sDstContentFolderName;
-
- // widgets must be saved as .png images.
- if ((tIWBImage == elementType) || (tUBZForeignObject == elementType))
- sDstContentFolderName = cfImages;
- else
- if (tIWBVideo == elementType)
- sDstContentFolderName = cfVideos;
- else
- if (tIWBAudio == elementType)
- sDstContentFolderName = cfAudios;
-
- sRet = sDstContentFolderName;
-
- return sRet;
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::getSrcContentFolderName(QString href)
-{
- QString sRet;
-
- QStringList ls = href.split("/");
- for (int i = 0; i < ls.count()-1; i++)
- {
- QString sPart = ls.at(i);
- if (ubzContentFolders.contains(sPart))
- {
- sRet = sPart;
- }
- }
-
-// if (0 < ls.count())
-// sRet = ls.at(ls.count()-1);
-//
-// sRet = href.remove(sRet);
-//
-// if (sRet.endsWith("/"))
-// sRet.remove("/");
-
- return sRet;
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::getFileNameFromPath(const QString sPath)
-{
- QString sRet;
- QStringList sl = sPath.split("/",UB::SplitBehavior::SkipEmptyParts);
-
- if (0 < sl.count())
- {
- QString name = sl.at(sl.count()-1);
- QString extention = getExtentionFromFileName(name);
-
- if (feWgt == extention)
- {
- name.remove("{");
- name.remove("}");
- }
-
- name.remove(name.length()-extention.length(), extention.length());
- name += convertExtention(extention);
-
- sRet = name;
- }
- return sRet;
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::getExtentionFromFileName(const QString &filename)
-{
- QStringList sl = filename.split("/",UB::SplitBehavior::SkipEmptyParts);
-
- if (0 < sl.count())
- {
- QString name = sl.at(sl.count()-1);
- QStringList tl = name.split(".");
- return tl.at(tl.count()-1);
- }
- return QString();
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::convertExtention(const QString &ext)
-{
- QString sRet;
-
- if (feSvg == ext)
- sRet = fePng;
- else
- if (feWgt == ext)
- sRet = fePng;
- else
- sRet = ext;
-
- return sRet;
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::getElementTypeFromUBZ(const QDomElement &element)
-{
- QString sRet;
- if (tUBZForeignObject == element.tagName())
- {
- QString sPath;
- if (element.hasAttribute(aUBZType))
- {
- if (avUBZText == element.attribute(aUBZType))
- sRet = tIWBTextArea;
- else
- sRet = element.attribute(aUBZType);
- }
- else
- {
- if (element.hasAttribute(aSrc))
- sPath = element.attribute(aSrc);
- else
- if (element.hasAttribute(aUBZHref))
- sPath = element.attribute(aUBZHref);
-
- QStringList tsl = sPath.split(".", UB::SplitBehavior::SkipEmptyParts);
- if (0 < tsl.count())
- {
- QString elementType = tsl.at(tsl.count()-1);
- if (iwbElementImage.contains(elementType))
- sRet = tIWBImage;
- else
- if (iwbElementAudio.contains(elementType))
- sRet = tIWBAudio;
- else
- if (iwbElementVideo.contains(elementType))
- sRet = tIWBVideo;
- }
- }
- }
- else
- sRet = element.tagName();
-
- return sRet;
-}
-
-int UBCFFAdaptor::UBToCFFConverter::getElementLayer(const QDomElement &element)
-{
- int iRetLayer = 0;
- if (element.hasAttribute(aZLayer))
- iRetLayer = (int)element.attribute(aZLayer).toDouble();
- else
- iRetLayer = DEFAULT_LAYER;
-
- return iRetLayer;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::itIsSupportedFormat(const QString &format) const
-{
- bool bRet;
-
- QStringList tsl = format.split(".", UB::SplitBehavior::SkipEmptyParts);
- if (0 < tsl.count())
- bRet = cffSupportedFileFormats.contains(tsl.at(tsl.count()-1).toLower());
- else
- bRet = false;
-
- return bRet;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::itIsFormatToConvert(const QString &format) const
-{
- foreach (QString f, ubzFormatsToConvert.split(","))
- {
- if (format == f)
- return true;
- }
- return false;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::itIsSVGElementAttribute(const QString ItemType, const QString &AttrName)
-{
- QString allowedElementAttributes = iwbSVGItemsAttributes[ItemType];
-
- allowedElementAttributes.remove("/t");
- allowedElementAttributes.remove(" ");
- foreach(QString attr, allowedElementAttributes.split(","))
- {
- if (AttrName == attr.trimmed())
- return true;
- }
- return false;
-}
-
-
-bool UBCFFAdaptor::UBToCFFConverter::itIsIWBAttribute(const QString &attribute) const
-{
- foreach (QString attr, iwbElementAttributes.split(","))
- {
- if (attribute == attr.trimmed())
- return true;
- }
- return false;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::itIsUBZAttributeToConvert(const QString &attribute) const
-{
- foreach (QString attr, ubzElementAttributesToConvert.split(","))
- {
- if (attribute == attr.trimmed())
- return true;
- }
- return false;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::ibwAddLine(int x1, int y1, int x2, int y2, QString color, int width, bool isBackground)
-{
- bool bRet = true;
-
- QDomDocument doc;
-
- QDomElement svgBackgroundCrossPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":line");
- QDomElement iwbBackgroundCrossPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- QString sUUID = QUuid::createUuid().toString();
-
- svgBackgroundCrossPart.setTagName(tIWBLine);
-
- svgBackgroundCrossPart.setAttribute(aX+"1", x1);
- svgBackgroundCrossPart.setAttribute(aY+"1", y1);
- svgBackgroundCrossPart.setAttribute(aX+"2", x2);
- svgBackgroundCrossPart.setAttribute(aY+"2", y2);
-
- svgBackgroundCrossPart.setAttribute(aStroke, color);
- svgBackgroundCrossPart.setAttribute(aStrokeWidth, width);
-
- svgBackgroundCrossPart.setAttribute(aID, sUUID);
-
- if (isBackground)
- {
- iwbBackgroundCrossPart.setAttribute(aRef, sUUID);
- iwbBackgroundCrossPart.setAttribute(aLocked, avTrue);
-
- addIWBElementToResultModel(iwbBackgroundCrossPart);
- }
-
- addSVGElementToResultModel(svgBackgroundCrossPart, mSvgElements, DEFAULT_BACKGROUND_CROSS_LAYER);
-
- if (!bRet)
- {
- qDebug() << "|error at creating crosses on background";
- errorStr = "CreatingCrossedBackgroundParsingError.";
- }
-
- return bRet;
-}
-
-QTransform UBCFFAdaptor::UBToCFFConverter::getTransformFromUBZ(const QDomElement &ubzElement)
-{
- QTransform trRet;
-
- QStringList transformParameters;
-
- QString ubzTransform = ubzElement.attribute(aTransform);
- ubzTransform.remove("matrix");
- ubzTransform.remove("(");
- ubzTransform.remove(")");
-
- transformParameters = ubzTransform.split(",", UB::SplitBehavior::SkipEmptyParts);
-
- if (6 <= transformParameters.count())
- {
- QTransform *tr = NULL;
- tr = new QTransform(transformParameters.at(0).toDouble(),
- transformParameters.at(1).toDouble(),
- transformParameters.at(2).toDouble(),
- transformParameters.at(3).toDouble(),
- transformParameters.at(4).toDouble(),
- transformParameters.at(5).toDouble());
-
- trRet = *tr;
-
- delete tr;
- }
-
- if (6 <= transformParameters.count())
- {
- QTransform *tr = NULL;
- tr = new QTransform(transformParameters.at(0).toDouble(),
- transformParameters.at(1).toDouble(),
- transformParameters.at(2).toDouble(),
- transformParameters.at(3).toDouble(),
- transformParameters.at(4).toDouble(),
- transformParameters.at(5).toDouble());
-
- trRet = *tr;
-
- delete tr;
- }
- return trRet;
-}
-
-qreal UBCFFAdaptor::UBToCFFConverter::getAngleFromTransform(const QTransform &tr)
-{
- qreal angle = -(atan(tr.m21()/tr.m11())*180/PI);
- if (tr.m21() > 0 && tr.m11() < 0)
- angle += 180;
- else
- if (tr.m21() < 0 && tr.m11() < 0)
- angle += 180;
- return angle;
-}
-
-void UBCFFAdaptor::UBToCFFConverter::setGeometryFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement)
-{
- setCoordinatesFromUBZ(ubzElement,iwbElement);
-
-
-
-}
-
-void UBCFFAdaptor::UBToCFFConverter::setCoordinatesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement)
-{
- QTransform tr;
-
- if (QString() != ubzElement.attribute(aTransform))
- tr = getTransformFromUBZ(ubzElement);
-
- qreal x = ubzElement.attribute(aX).toDouble();
- qreal y = ubzElement.attribute(aY).toDouble();
- qreal height = ubzElement.attribute(aHeight).toDouble();
- qreal width = ubzElement.attribute(aWidth).toDouble();
-
- qreal alpha = getAngleFromTransform(tr);
-
- QRectF itemRect;
- QGraphicsRectItem item;
-
- item.setRect(0,0, width, height);
- item.setTransform(tr);
- item.setRotation(-alpha);
- QTransform sceneMatrix = item.sceneTransform();
-
- iwbElement.setAttribute(aX, x);
- iwbElement.setAttribute(aY, y);
- iwbElement.setAttribute(aHeight, height*sceneMatrix.m22());
- iwbElement.setAttribute(aWidth, width*sceneMatrix.m11());
- iwbElement.setAttribute(aTransform, QString("rotate(%1) translate(%2,%3)").arg(alpha)
- .arg(sceneMatrix.dx())
- .arg(sceneMatrix.dy()));
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::setContentFromUBZ(const QDomElement &ubzElement, QDomElement &svgElement)
-{
- bool bRet = true;
-
- QString srcPath;
- if (tUBZForeignObject != ubzElement.tagName())
- srcPath = ubzElement.attribute(aUBZHref);
- else
- srcPath = ubzElement.attribute(aSrc);
-
- QString sSrcContentFolder = getSrcContentFolderName(srcPath);
- QString sSrcFileName = sourcePath + "/" + srcPath ;
- QString fileExtention = getExtentionFromFileName(sSrcFileName);
- QString sDstContentFolder = getDstContentFolderName(ubzElement.tagName());
- QString sDstFileName(QString(QUuid::createUuid().toString()+"."+convertExtention(fileExtention)));
-
-
- if (itIsSupportedFormat(fileExtention)) // format is supported and we can copy src. files without changing.
- {
- sSrcFileName = sourcePath + "/" + sSrcContentFolder + "/" + getFileNameFromPath(srcPath); // some elements must be exported as images, so we take hes existing thumbnails.
-
- QFile srcFile;
- srcFile.setFileName(sSrcFileName);
-
- QDir dstDocFolder(destinationPath);
-
- if (!dstDocFolder.exists(sDstContentFolder))
- bRet &= dstDocFolder.mkdir(sDstContentFolder);
-
- if (bRet)
- {
- QString dstFilePath = destinationPath+"/"+sDstContentFolder+"/"+sDstFileName;
- bRet &= srcFile.copy(dstFilePath);
- }
-
- if (bRet)
- {
- svgElement.setAttribute(aSVGHref, sDstContentFolder+"/"+sDstFileName);
- // NOT by standard! Enable it later!
- // validator http://validator.imsglobal.org/iwb/index.jsp?validate=package
- //svgElement.setAttribute(aSVGRequiredExtension, svgRequiredExtensionPrefix+convertExtention(fileExtention));
- }
- }
- else
- if (itIsFormatToConvert(fileExtention)) // we cannot copy that source files. We need to create dst. file from src. file without copy.
- {
- if (feSvg == fileExtention)
- {
- QDir dstDocFolder(destinationPath);
-
- if (!dstDocFolder.exists(sDstContentFolder))
- bRet &= dstDocFolder.mkdir(sDstContentFolder);
-
- if (bRet)
- {
- if (feSvg == fileExtention) // svg images must be converted to PNG.
- {
- QString dstFilePath = destinationPath+"/"+sDstContentFolder+"/"+sDstFileName;
- bRet &= createPngFromSvg(sSrcFileName, dstFilePath, getTransformFromUBZ(ubzElement));
- }
- else
- bRet = false;
- }
-
- if (bRet)
- {
- svgElement.setAttribute(aSVGHref, sDstContentFolder+"/"+sDstFileName);
- // NOT by standard! Enable it later!
- // validator http://validator.imsglobal.org/iwb/index.jsp?validate=package
- //svgElement.setAttribute(aSVGRequiredExtension, svgRequiredExtensionPrefix+fePng);
- }
- }
- }else
- {
- addLastExportError(QObject::tr("Element ID = ") + QString("%1 \r\n").arg(ubzElement.attribute(aUBZUuid))
- + QString("Source file = ") + QString("%1 \r\n").arg(ubzElement.attribute(aUBZSource))
- + QObject::tr("Content is not supported in destination format."));
- bRet = false;
- }
-
- if (!bRet)
- {
- qDebug() << "format is not supported by CFF";
- }
-
- return bRet;
-}
-
-void UBCFFAdaptor::UBToCFFConverter::setCFFTextFromHTMLTextNode(const QDomElement htmlTextNode, QDomElement &iwbElement)
-{
-
- QDomDocument textDoc;
-
- QDomElement textParentElement = iwbElement;
-
- QString textString;
- QDomNode htmlPNode = htmlTextNode.firstChild();
- bool bTbreak = false;
-
- // reads HTML text strings - each string placed in separate section
- while(!htmlPNode.isNull())
- {
- // add for split strings
- if (bTbreak)
- {
- bTbreak = false;
-
- QDomElement tbreakNode = textDoc.createElementNS(svgIWBNS, svgIWBNSPrefix+":"+tIWBTbreak);
- textParentElement.appendChild(tbreakNode.cloneNode(true));
- }
-
- QDomNode spanNode = htmlPNode.firstChild();
-
- while (!spanNode.isNull())
- {
- if (spanNode.isText())
- {
- QDomText nodeText = textDoc.createTextNode(spanNode.nodeValue());
- textParentElement.appendChild(nodeText.cloneNode(true));
- }
- else
- if (spanNode.isElement())
- {
- QDomElement pElementIwb;
- QDomElement spanElement = textDoc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBTspan);
- setCommonAttributesFromUBZ(htmlPNode.toElement(), pElementIwb, spanElement);
-
- if (spanNode.hasAttributes())
- {
- int attrCount = spanNode.attributes().count();
- if (0 < attrCount)
- {
- for (int i = 0; i < attrCount; i++)
- {
- // html attributes like: style="font-size:40pt; color:"red";".
- QStringList cffAttributes = spanNode.attributes().item(i).nodeValue().split(";", UB::SplitBehavior::SkipEmptyParts);
- {
- for (int i = 0; i < cffAttributes.count(); i++)
- {
- QString attr = cffAttributes.at(i).trimmed();
- QStringList AttrVal = attr.split(":", UB::SplitBehavior::SkipEmptyParts);
- if(1 < AttrVal.count())
- {
- QString sAttr = ubzAttrNameToCFFAttrName(AttrVal.at(0));
- if (itIsSVGElementAttribute(spanElement.tagName(), sAttr))
- spanElement.setAttribute(sAttr, ubzAttrValueToCFFAttrName(AttrVal.at(1)));
- }
- }
- }
- }
- }
- }
- QDomText nodeText = textDoc.createTextNode(spanNode.firstChild().nodeValue());
- spanElement.appendChild(nodeText);
- textParentElement.appendChild(spanElement.cloneNode(true));
- }
- spanNode = spanNode.nextSibling();
- }
-
- bTbreak = true;
- htmlPNode = htmlPNode.nextSibling();
- }
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::ubzAttrNameToCFFAttrName(QString cffAttrName)
-{
- QString sRet = cffAttrName;
- if (QString("color") == cffAttrName)
- sRet = QString("fill");
- if (QString("align") == cffAttrName)
- sRet = QString("text-align");
-
- return sRet;
-}
-QString UBCFFAdaptor::UBToCFFConverter::ubzAttrValueToCFFAttrName(QString cffValue)
-{
- QString sRet = cffValue;
- if (QString("text") == cffValue)
- sRet = QString("normal");
-
- return sRet;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::setCFFAttribute(const QString &attributeName, const QString &attributeValue, const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement)
-{
- bool bRet = true;
- bool bNeedsIWBSection = false;
-
- if (itIsIWBAttribute(attributeName))
- {
- if (!((aBackground == attributeName) && (avFalse == attributeValue)))
- {
- iwbElement.setAttribute(attributeName, attributeValue);
- bNeedsIWBSection = true;
- }
- }
- else
- if (itIsUBZAttributeToConvert(attributeName))
- {
- if (aTransform == attributeName)
- {
- setGeometryFromUBZ(ubzElement, svgElement);
- }
- else
- if (attributeName.contains(aUBZUuid))
- {
-
- QString parentId = ubzElement.attribute(aUBZParent);
- QString id;
- if (!parentId.isEmpty())
- id = "{" + parentId + "}" + "{" + ubzElement.attribute(aUBZUuid)+"}";
- else
- id = "{" + ubzElement.attribute(aUBZUuid)+"}";
-
- svgElement.setAttribute(aID, id);
- }
- else
- if (attributeName.contains(aUBZHref)||attributeName.contains(aSrc))
- {
- bRet &= setContentFromUBZ(ubzElement, svgElement);
- bNeedsIWBSection = bRet||bNeedsIWBSection;
- }
- }
- else
- if (itIsSVGElementAttribute(svgElement.tagName(),attributeName))
- {
- svgElement.setAttribute(attributeName, attributeValue);
- }
-
- if (bNeedsIWBSection)
- {
- if (0 < iwbElement.attributes().count())
- {
-
- QStringList tl = ubzElement.attribute(aSVGHref).split("/");
- QString id = tl.at(tl.count()-1);
- // if element already have an ID, we use it. Else we create new id for element.
- if (QString() == id)
- id = QUuid::createUuid().toString();
-
- svgElement.setAttribute(aID, id);
- iwbElement.setAttribute(aRef, id);
- }
- }
-
- return bRet;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::setCommonAttributesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement)
-{
- bool bRet = true;
-
- for (int i = 0; i < ubzElement.attributes().count(); i++)
- {
- QDomNode attribute = ubzElement.attributes().item(i);
- QString attributeName = ubzAttrNameToCFFAttrName(attribute.nodeName().remove("ub:"));
-
- bRet &= setCFFAttribute(attributeName, ubzAttrValueToCFFAttrName(attribute.nodeValue()), ubzElement, iwbElement, svgElement);
- if (!bRet) break;
- }
- return bRet;
-}
-
-void UBCFFAdaptor::UBToCFFConverter::setViewBox(QRect viewbox)
-{
- mViewbox |= viewbox;
-}
-
-QDomNode UBCFFAdaptor::UBToCFFConverter::findTextNode(const QDomNode &node)
-{
- QDomNode iterNode = node;
-
- while (!iterNode.isNull())
- {
- if (iterNode.isText())
- {
- if (!iterNode.isNull())
- return iterNode;
- }
- else
- {
- if (!iterNode.firstChild().isNull())
- {
- QDomNode foundNode = findTextNode(iterNode.firstChild());
- if (!foundNode.isNull())
- if (foundNode.isText())
- return foundNode;
- }
- }
- if (!iterNode.nextSibling().isNull())
- iterNode = iterNode.nextSibling();
- else
- break;
- }
- return iterNode;
-}
-
-QDomNode UBCFFAdaptor::UBToCFFConverter::findNodeByTagName(const QDomNode &node, QString tagName)
-{
- QDomNode iterNode = node;
-
- while (!iterNode.isNull())
- {
- QString t = iterNode.toElement().tagName();
- if (tagName == t)
- return iterNode;
- else
- {
- if (!iterNode.firstChildElement().isNull())
- {
- QDomNode foundNode = findNodeByTagName(iterNode.firstChildElement(), tagName);
- if (!foundNode.isNull()){
- if (foundNode.isElement())
- {
- if (tagName == foundNode.toElement().tagName())
- return foundNode;
- }
- else
- break;
- }
- }
- }
-
- if (!iterNode.nextSibling().isNull())
- iterNode = iterNode.nextSibling();
- else
- break;
- }
- return QDomNode();
-
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::createBackground(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "|creating element background";
-
-
- QDomDocument doc;
-
- //QDomElement svgBackgroundElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tUBZImage);
- QDomElement svgBackgroundElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBRect);
- QDomElement iwbBackgroundElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
-
- QRect bckRect(mViewbox);
-
- if (0 <= mViewbox.topLeft().x())
- bckRect.topLeft().setX(0);
-
- if (0 <= mViewbox.topLeft().y())
- bckRect.topLeft().setY(0);
-
- if (QRect() != bckRect)
- {
- QString sElementID = QUuid::createUuid().toString();
-
- bool darkBackground = (avTrue == element.attribute(aDarkBackground));
- svgBackgroundElementPart.setAttribute(aFill, darkBackground ? "black" : "white");
- svgBackgroundElementPart.setAttribute(aID, sElementID);
- svgBackgroundElementPart.setAttribute(aX, bckRect.x());
- svgBackgroundElementPart.setAttribute(aY, bckRect.y());
- svgBackgroundElementPart.setAttribute(aHeight, bckRect.height());
- svgBackgroundElementPart.setAttribute(aWidth, bckRect.width());
-
- //svgBackgroundElementPart.setAttribute(aSVGHref, backgroundImagePath);
-
- iwbBackgroundElementPart.setAttribute(aRef, sElementID);
- iwbBackgroundElementPart.setAttribute(aBackground, avTrue);
- //iwbBackgroundElementPart.setAttribute(aLocked, avTrue);
-
- addSVGElementToResultModel(svgBackgroundElementPart, dstSvgList, DEFAULT_BACKGROUND_LAYER);
- addIWBElementToResultModel(iwbBackgroundElementPart);
- return true;
- }
- else
- {
- qDebug() << "|error at creating element background";
- errorStr = "CreatingElementBackgroundParsingError.";
- return false;
- }
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::createBackgroundImage(const QDomElement &element, QSize size)
-{
- QString sRet;
-
- QString sDstFileName(fIWBBackground);
-
- bool bDirExists = true;
- QDir dstDocFolder(destinationPath);
-
- if (!dstDocFolder.exists(cfImages))
- bDirExists &= dstDocFolder.mkdir(cfImages);
-
- QString dstFilePath;
- if (bDirExists)
- dstFilePath = destinationPath+"/"+cfImages+"/"+sDstFileName;
-
- if (!QFile().exists(dstFilePath))
- {
- QRect rect(0,0, size.width(), size.height());
-
- QImage *bckImage = new QImage(size, QImage::Format_RGB888);
-
- QPainter *painter = new QPainter(bckImage);
-
- bool darkBackground = (avTrue == element.attribute(aDarkBackground));
-
- QColor bCrossColor;
-
- bCrossColor = darkBackground?QColor(Qt::white):QColor(Qt::blue);
- int penAlpha = (int)(255/2); // default Sankore value for transform.m11 < 1
- bCrossColor.setAlpha(penAlpha);
- painter->setPen(bCrossColor);
- painter->setBrush(darkBackground?QColor(Qt::black):QColor(Qt::white));
-
- painter->drawRect(rect);
-
- if (avTrue == element.attribute(aCrossedBackground))
- {
- qreal firstY = ((int) (rect.y () / iCrossSize)) * iCrossSize;
-
- for (qreal yPos = firstY; yPos <= rect.y () + rect.height (); yPos += iCrossSize)
- {
- painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos);
- }
-
- qreal firstX = ((int) (rect.x () / iCrossSize)) * iCrossSize;
-
- for (qreal xPos = firstX; xPos <= rect.x () + rect.width (); xPos += iCrossSize)
- {
- painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ());
- }
- }
-
- painter->end();
- painter->save();
-
- if (QString() != dstFilePath)
- if (bckImage->save(dstFilePath))
- sRet = cfImages+"/"+sDstFileName;
-
- delete bckImage;
- delete painter;
- }
- else
- sRet = cfImages+"/"+sDstFileName;
-
- return sRet;
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::createPngFromSvg(QString &svgPath, QString &dstPath, QTransform transformation, QSize size)
-{
- if (QFile().exists(svgPath))
- {
- QImage i(svgPath);
-
- QSize iSize = (QSize() == size)?QSize(i.size().width()*transformation.m11(), i.size().height()*transformation.m22()):size;
-
- QImage image(iSize, QImage::Format_ARGB32_Premultiplied);
- image.fill(0);
- QPainter imagePainter(&image);
- QSvgRenderer renderer(svgPath);
- renderer.render(&imagePainter);
-
- return image.save(dstPath);
-
- }
- else
- return false;
-}
-
-
-bool UBCFFAdaptor::UBToCFFConverter::parseSVGGGroup(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "|parsing g section";
- QDomElement nextElement = element.firstChildElement();
- if (nextElement.isNull()) {
- qDebug() << "Empty g element";
- errorStr = "EmptyGSection";
- return false;
- }
-
- QMultiMap svgElements;
-
- QDomDocument doc;
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBG);
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- // Elements can know about its layer, so it must add result QDomElements to ordrered list.
- while (!nextElement.isNull()) {
- QString tagName = nextElement.tagName();
- if (tagName == tUBZLine) parseUBZLine(nextElement, svgElements);
- else if (tagName == tUBZPolygon) parseUBZPolygon(nextElement, svgElements);
- else if (tagName == tUBZPolyline) parseUBZPolyline(nextElement, svgElements);
-
- nextElement = nextElement.nextSiblingElement();
- }
-
- QList layers;
- const auto keys = svgElements.keys();
- for (const auto key : keys) {
- layers << key;
- }
-
- std::sort(layers.begin(), layers.end());
- int layer = layers.at(0);
-
- for (const auto &value : std::as_const(svgElements)) {
- svgElementPart.appendChild(value);
- }
-
- addSVGElementToResultModel(svgElementPart, dstSvgList, layer);
-
- return true;
-}
-bool UBCFFAdaptor::UBToCFFConverter::parseUBZImage(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "|parsing image";
-
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
-
- if (0 < iwbElementPart.attributes().count())
- addIWBElementToResultModel(iwbElementPart);
- return true;
- }
- else
- {
- qDebug() << "|error at image parsing";
- errorStr = "ImageParsingError";
- return false;
-
- }
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::parseUBZVideo(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "|parsing video";
-
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- QDomElement svgSwitchSection = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBSwitch);
- svgSwitchSection.appendChild(svgElementPart);
-
- // if viewer cannot open that content - it must use that:
- QDomElement svgText = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBTextArea);
- svgText.setAttribute(aX, svgElementPart.attribute(aX));
- svgText.setAttribute(aY, svgElementPart.attribute(aY));
- svgText.setAttribute(aWidth, svgElementPart.attribute(aWidth));
- svgText.setAttribute(aHeight, svgElementPart.attribute(aHeight));
- svgText.setAttribute(aTransform, svgElementPart.attribute(aTransform));
-
- QDomText text = doc.createTextNode("Cannot Open Content");
- svgText.appendChild(text);
-
- svgSwitchSection.appendChild(svgText);
-
- addSVGElementToResultModel(svgSwitchSection, dstSvgList, getElementLayer(element));
-
- if (0 < iwbElementPart.attributes().count())
- addIWBElementToResultModel(iwbElementPart);
- return true;
- }
- else
- {
- qDebug() << "|error at video parsing";
- errorStr = "VideoParsingError";
- return false;
- }
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::parseUBZAudio(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "|parsing audio";
-
- // audio file must be linked to cff item excluding video.
- // to do:
- // 1 add image for audio element.
- // 2 set id for this element
- // 3 add section with xlink:href to audio file
- // 4 add shild to a section with id of the image
-
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- //we must create image-containers for audio files
- int audioImageDimention = qMin(svgElementPart.attribute(aWidth).toInt(), svgElementPart.attribute(aHeight).toInt());
- QString srcAudioImageFile(sAudioElementImage);
- QString elementId = QString(QUuid::createUuid().toString());
- QString sDstAudioImageFileName = elementId+"."+fePng;
- QString dstAudioImageFilePath = destinationPath+"/"+cfImages+"/"+sDstAudioImageFileName;
- QString dstAudioImageRelativePath = cfImages+"/"+sDstAudioImageFileName;
-
- QFile srcFile(srcAudioImageFile);
-
- //creating folder for audioImage
- QDir dstDocFolder(destinationPath);
- bool bRes = true;
- if (!dstDocFolder.exists(cfImages))
- bRes &= dstDocFolder.mkdir(cfImages);
-
- // CFF cannot show SVG images, so we need to convert it to png.
- if (bRes && createPngFromSvg(srcAudioImageFile, dstAudioImageFilePath, getTransformFromUBZ(element), QSize(audioImageDimention, audioImageDimention)))
- {
- // switch section disabled because of imcompatibility with validator http://validator.imsglobal.org/iwb/index.jsp?validate=package
- // QDomElement svgSwitchSection = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBSwitch);
-
- // first we place content
- QDomElement svgASection = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBA);
- svgASection.setAttribute(aSVGHref, svgElementPart.attribute(aSVGHref));
-
- svgElementPart.setTagName(tIWBImage);
- svgElementPart.setAttribute(aSVGHref, dstAudioImageRelativePath);
- svgElementPart.setAttribute(aHeight, audioImageDimention);
- svgElementPart.setAttribute(aWidth, audioImageDimention);
-
- svgASection.appendChild(svgElementPart);
- // switch section disabled because of imcompatibility with validator http://validator.imsglobal.org/iwb/index.jsp?validate=package
- // svgSwitchSection.appendChild(svgASection);
-
- // if viewer cannot open that content - it must use that:
- QDomElement svgText = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBTextArea);
- svgText.setAttribute(aX, svgElementPart.attribute(aX));
- svgText.setAttribute(aY, svgElementPart.attribute(aY));
- svgText.setAttribute(aWidth, svgElementPart.attribute(aWidth));
- svgText.setAttribute(aHeight, svgElementPart.attribute(aHeight));
- svgText.setAttribute(aTransform, svgElementPart.attribute(aTransform));
-
- QDomText text = doc.createTextNode("Cannot Open Content");
- svgText.appendChild(text);
-
- // switch section disabled because of imcompatibility with validator http://validator.imsglobal.org/iwb/index.jsp?validate=package
- // svgSwitchSection.appendChild(svgText);
-
- // switch section disabled because of imcompatibility with validator http://validator.imsglobal.org/iwb/index.jsp?validate=package
- addSVGElementToResultModel(svgASection/*svgSwitchSection*/, dstSvgList, getElementLayer(element));
-
- if (0 < iwbElementPart.attributes().count())
- addIWBElementToResultModel(iwbElementPart);
- return true;
- }
- return false;
- }
- else
- {
- qDebug() << "|error at audio parsing";
- errorStr = "AudioParsingError";
- return false;
- }
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::parseForeignObject(const QDomElement &element, QMultiMap &dstSvgList)
-{
-
- if (element.attribute(aUBZType) == avUBZText) {
- return parseUBZText(element, dstSvgList);
- }
-
- qDebug() << "|parsing foreign object";
-
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
- if (0 < iwbElementPart.attributes().count())
- addIWBElementToResultModel(iwbElementPart);
- return true;
- }
- else
- {
- qDebug() << "|error at parsing foreign object";
- errorStr = "ForeignObjectParsingError";
- return false;
- }
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::parseUBZText(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "|parsing text";
-
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (element.hasChildNodes())
- {
- QDomDocument htmlDoc;
- htmlDoc.setContent(findTextNode(element).nodeValue());
- QDomNode bodyNode = findNodeByTagName(htmlDoc.firstChildElement(), "body");
-
- setCFFTextFromHTMLTextNode(bodyNode.toElement(), svgElementPart);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- QString commonParams;
- for (int i = 0; i < bodyNode.attributes().count(); i++)
- {
- commonParams += " " + bodyNode.attributes().item(i).nodeValue();
- }
- commonParams.remove(" ");
- commonParams.remove("'");
-
- QStringList commonAttributes = commonParams.split(";", UB::SplitBehavior::SkipEmptyParts);
- for (int i = 0; i < commonAttributes.count(); i++)
- {
- QStringList AttrVal = commonAttributes.at(i).split(":", UB::SplitBehavior::SkipEmptyParts);
- if (1 < AttrVal.count())
- {
- QString sAttr = ubzAttrNameToCFFAttrName(AttrVal.at(0));
- QString sVal = ubzAttrValueToCFFAttrName(AttrVal.at(1));
-
- setCFFAttribute(sAttr, sVal, element, iwbElementPart, svgElementPart);
- }
- }
- addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
- if (0 < iwbElementPart.attributes().count())
- addIWBElementToResultModel(iwbElementPart);
- return true;
- }
- return false;
- }
- else
- {
- qDebug() << "|error at text parsing";
- errorStr = "TextParsingError";
- return false;
- }
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::parseUBZPolygon(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "||parsing polygon";
-
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- svgElementPart.setAttribute(aStroke, svgElementPart.attribute(aFill));
- addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
-
- if (0 < iwbElementPart.attributes().count())
- {
- QString id = svgElementPart.attribute(aUBZUuid);
- if (id.isEmpty())
- id = QUuid::createUuid().toString();
-
- svgElementPart.setAttribute(aID, id);
- iwbElementPart.setAttribute(aRef, id);
-
- addIWBElementToResultModel(iwbElementPart);
- }
- return true;
- }
- else
- {
- qDebug() << "||error at parsing polygon";
- errorStr = "PolygonParsingError";
- return false;
- }
-
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::parseUBZPolyline(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "||parsing polyline";
- QDomElement resElement;
-
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- svgElementPart.setAttribute(aStroke, svgElementPart.attribute(aFill));
- addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
-
- if (0 < iwbElementPart.attributes().count())
- {
- QString id = QUuid::createUuid().toString();
- svgElementPart.setAttribute(aID, id);
- iwbElementPart.setAttribute(aRef, id);
-
- addIWBElementToResultModel(iwbElementPart);
- }
- return true;
- }
- else
- {
- qDebug() << "||error at parsing polygon";
- errorStr = "PolylineParsingError";
- return false;
- }
-
-}
-
-bool UBCFFAdaptor::UBToCFFConverter::parseUBZLine(const QDomElement &element, QMultiMap &dstSvgList)
-{
- qDebug() << "||parsing line";
- QDomElement resElement;
- QDomDocument doc;
-
- QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
- QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
-
- if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
- {
- svgElementPart.setAttribute(aStroke, svgElementPart.attribute(aFill));
- addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
-
- if (0 < iwbElementPart.attributes().count())
- {
- QString id = QUuid::createUuid().toString();
- svgElementPart.setAttribute(aID, id);
- iwbElementPart.setAttribute(aRef, id);
-
- addIWBElementToResultModel(iwbElementPart);
- }
- }
- else
- {
- qDebug() << "||error at parsing polygon";
- errorStr = "LineParsingError";
- return false;
- }
- return true;
-}
-
-void UBCFFAdaptor::UBToCFFConverter::addSVGElementToResultModel(const QDomElement &element, QMultiMap &dstList, int layer)
-{
- int elementLayer = (DEFAULT_LAYER == layer) ? DEFAULT_LAYER : layer;
-
- QDomElement rootElement = element.cloneNode(true).toElement();
- mDocumentToWrite->firstChildElement().appendChild(rootElement);
- dstList.insert(elementLayer, rootElement);
-}
-
-void UBCFFAdaptor::UBToCFFConverter::addIWBElementToResultModel(const QDomElement &element)
-{
- QDomElement rootElement = element.cloneNode(true).toElement();
- mDocumentToWrite->firstChildElement().appendChild(rootElement);
- mExtendedElements.append(rootElement);
-}
-
-UBCFFAdaptor::UBToCFFConverter::~UBToCFFConverter()
-{
- if (mDataModel)
- delete mDataModel;
- if (mIWBContentWriter)
- delete mIWBContentWriter;
- if (mDocumentToWrite)
- delete mDocumentToWrite;
-}
-bool UBCFFAdaptor::UBToCFFConverter::isValid() const
-{
- bool result = QFileInfo(sourcePath).exists()
- && QFileInfo(sourcePath).isDir()
- && errorStr == noErrorMsg;
-
- if (!result) {
- qDebug() << "specified data is not valid";
- errorStr = "ValidateDataError";
- }
-
- return result;
-}
-
-void UBCFFAdaptor::UBToCFFConverter::fillNamespaces()
-{
- mIWBContentWriter->writeDefaultNamespace(svgUBZNS);
- mIWBContentWriter->writeNamespace(iwbNS, iwbNsPrefix);
- mIWBContentWriter->writeNamespace(svgIWBNS, svgIWBNSPrefix);
- mIWBContentWriter->writeNamespace(xlinkNS, xlinkNSPrefix);
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::digitFileFormat(int digit) const
-{
- return QString("%1").arg(digit, 3, 10, QLatin1Char('0'));
-}
-QString UBCFFAdaptor::UBToCFFConverter::contentIWBFileName() const
-{
- return destinationPath + "/" + fIWBContent;
-}
-
-//setting SVG dimenitons
-QSize UBCFFAdaptor::UBToCFFConverter::getSVGDimentions(const QString &element)
-{
-
- QStringList dimList;
-
- dimList = element.split(dimensionsDelimiter1);
- if (dimList.count() != 2) // row unlike 0x0
- return QSize();
-
- bool ok;
-
- int width = dimList.takeFirst().toInt(&ok);
- if (!ok || !width)
- return QSize();
-
- int height = dimList.takeFirst().toInt(&ok);
- if (!ok || !height)
- return QSize();
-
- return QSize(width, height);
-}
-
-//Setting viewbox rectangle
-QRect UBCFFAdaptor::UBToCFFConverter::getViewboxRect(const QString &element) const
-{
- QStringList dimList;
-
- dimList = element.split(dimensionsDelimiter2);
- if (dimList.count() != 4) // row unlike 0 0 0 0
- return QRect();
-
- bool ok = false;
-
- int x = dimList.takeFirst().toInt(&ok);
- if (!ok || !x)
- return QRect();
-
- int y = dimList.takeFirst().toInt(&ok);
- if (!ok || !y)
- return QRect();
-
- int width = dimList.takeFirst().toInt(&ok);
- if (!ok || !width)
- return QRect();
-
- int height = dimList.takeFirst().toInt(&ok);
- if (!ok || !height)
- return QRect();
-
- return QRect(x, y, width, height);
-}
-
-QString UBCFFAdaptor::UBToCFFConverter::rectToIWBAttr(const QRect &rect) const
-{
- if (rect.isNull()) return QString();
-
- return QString("%1 %2 %3 %4").arg(rect.topLeft().x())
- .arg(rect.topLeft().y())
- .arg(rect.width())
- .arg(rect.height());
-}
-
-UBCFFAdaptor::UBToUBZConverter::UBToUBZConverter()
-{
-
-}
diff --git a/plugins/cffadaptor/src/UBCFFAdaptor.h b/plugins/cffadaptor/src/UBCFFAdaptor.h
deleted file mode 100644
index 5de50ec39..000000000
--- a/plugins/cffadaptor/src/UBCFFAdaptor.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
- *
- * Copyright (C) 2013 Open Education Foundation
- *
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
- * l'Education Numérique en Afrique (GIP ENA)
- *
- * This file is part of OpenBoard.
- *
- * OpenBoard 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).
- *
- * OpenBoard is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenBoard. If not, see .
- */
-
-
-#ifndef UBCFFADAPTOR_H
-#define UBCFFADAPTOR_H
-
-#include "UBCFFAdaptor_global.h"
-
-#include
-
-class QTransform;
-class QDomDocument;
-class QDomElement;
-class QDomNode;
-class QuaZipFile;
-
-class UBCFFADAPTORSHARED_EXPORT UBCFFAdaptor {
- class UBToCFFConverter;
-
-public:
- UBCFFAdaptor();
- ~UBCFFAdaptor();
-
- bool convertUBZToIWB(const QString &from, const QString &to);
- bool deleteDir(const QString& pDirPath) const;
- QList getConversionMessages();
-
-private:
- QString uncompressZip(const QString &zipFile);
- bool compressZip(const QString &source, const QString &destination);
- bool compressDir(const QString &dirName, const QString &parentDir, QuaZipFile *outZip);
- bool compressFile(const QString &fileName, const QString &parentDir, QuaZipFile *outZip);
-
- QString createNewTmpDir();
- bool freeDir(const QString &dir);
- void freeTmpDirs();
-
-private:
- QStringList tmpDirs;
- QList mConversionMessages;
-
-private:
-
- class UBToCFFConverter {
-
- static const int DEFAULT_LAYER = -100000;
-
- public:
- UBToCFFConverter(const QString &source, const QString &destination);
- ~UBToCFFConverter();
- bool isValid() const;
- QString lastErrStr() const {return errorStr;}
- bool parse();
- QList getMessages() {return mExportErrorList;}
-
- private:
-
- void addLastExportError(QString error) {mExportErrorList.append(error);}
-
- void fillNamespaces();
-
- bool parseMetadata();
- bool parseContent();
- QDomElement parsePageset(const QStringList &pageFileNames);
- QDomElement parsePage(const QString &pageFileName);
- QDomElement parseSvgPageSection(const QDomElement &element);
- void writeQDomElementToXML(const QDomNode &node);
- bool writeExtendedIwbSection();
- QDomElement parseGroupsPageSection(const QDomElement &groupRoot);
-
- bool createBackground(const QDomElement &element, QMultiMap &dstSvgList);
- QString createBackgroundImage(const QDomElement &element, QSize size);
- bool createPngFromSvg(QString &svgPath, QString &dstPath, QTransform transformation, QSize size = QSize());
-
- bool parseSVGGGroup(const QDomElement &element, QMultiMap &dstSvgList);
- bool parseUBZImage(const QDomElement &element, QMultiMap &dstSvgList);
- bool parseUBZVideo(const QDomElement &element, QMultiMap &dstSvgList);
- bool parseUBZAudio(const QDomElement &element, QMultiMap &dstSvgList);
- bool parseForeignObject(const QDomElement &element, QMultiMap &dstSvgList);
- bool parseUBZText(const QDomElement &element, QMultiMap &dstSvgList);
-
- bool parseUBZPolygon(const QDomElement &element, QMultiMap &dstSvgList);
- bool parseUBZPolyline(const QDomElement &element, QMultiMap &dstSvgList);
- bool parseUBZLine(const QDomElement &element, QMultiMap &dstSvgList);
- void addSVGElementToResultModel(const QDomElement &element, QMultiMap &dstList, int layer = DEFAULT_LAYER);
- void addIWBElementToResultModel(const QDomElement &element);
-
- qreal getAngleFromTransform(const QTransform &tr);
- QString getDstContentFolderName(const QString &elementType);
- QString getSrcContentFolderName(QString href);
- QString getFileNameFromPath(QString sPath);
- QString getExtentionFromFileName(const QString &filename);
- QString convertExtention(const QString &ext);
- QString getElementTypeFromUBZ(const QDomElement &element);
-
- int getElementLayer(const QDomElement &element);
-
- bool itIsSupportedFormat(const QString &format) const;
- bool itIsFormatToConvert(const QString &format) const;
- bool itIsSVGElementAttribute(const QString ItemType, const QString &AttrName);
- bool itIsIWBAttribute(const QString &attribute) const;
- bool itIsUBZAttributeToConvert(const QString &attribute) const;
-
- bool ibwAddLine(int x1, int y1, int x2, int y2, QString color=QString(), int width=1, bool isBackground=false);
-
- QTransform getTransformFromUBZ(const QDomElement &ubzElement);
- void setGeometryFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement);
- void setCoordinatesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement);
- bool setContentFromUBZ(const QDomElement &ubzElement, QDomElement &svgElement);
- void setCFFTextFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement);
- void setCFFTextFromHTMLTextNode(const QDomElement htmlTextNode, QDomElement &iwbElement);
- QString ubzAttrNameToCFFAttrName(QString cffAttrName);
- QString ubzAttrValueToCFFAttrName(QString cffAttrValue);
-
- bool setCFFAttribute(const QString &attributeName, const QString &attributeValue, const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement);
- bool setCommonAttributesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement);
- void setViewBox(QRect viewbox);
-
- QDomNode findTextNode(const QDomNode &node);
- QDomNode findNodeByTagName(const QDomNode &node, QString tagName);
-
- QSize getSVGDimentions(const QString &element);
-
- inline QRect getViewboxRect(const QString &element) const;
- inline QString rectToIWBAttr(const QRect &rect) const;
- inline QString digitFileFormat(int num) const;
- inline bool strToBool(const QString &in) const {return in == "true";}
- QString contentIWBFileName() const;
-
- private:
- QList mExportErrorList;
- QMap iwbSVGItemsAttributes;
- QDomDocument *mDataModel; //model for reading indata
- QXmlStreamWriter *mIWBContentWriter; //stream to write outdata
- QSize mSVGSize; //svg page size
- QRect mViewbox; //Main viewbox parameter for CFF
- QString sourcePath; // dir with unpacked source data (ubz)
- QString destinationPath; //dir with unpacked destination data (iwb)
- QDomDocument *mDocumentToWrite; //document for saved QDomElements from mSvgElements and mExtendedElements
- QMultiMap mSvgElements; //Saving svg elements to have a sorted by z order list of elements to write;
- QList mExtendedElements; //Saving extended options of elements to be able to add them to the end of result iwb document;
- mutable QString errorStr; // last error string message
-
- public:
- operator bool() const {return isValid();}
- };
-
- class UBToUBZConverter {
- public:
- UBToUBZConverter();
- };
-
-
-};
-
-#endif // UBCFFADAPTOR_H
diff --git a/plugins/cffadaptor/src/UBCFFAdaptor_global.h b/plugins/cffadaptor/src/UBCFFAdaptor_global.h
deleted file mode 100644
index 3f060b96d..000000000
--- a/plugins/cffadaptor/src/UBCFFAdaptor_global.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour l'Education Numérique en Afrique (GIP ENA)
- *
- * 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 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Open-Sankoré. If not, see .
- */
-
-
-#ifndef UBCFFADAPTOR_GLOBAL_H
-#define UBCFFADAPTOR_GLOBAL_H
-
-#include
-
-#if defined(UBCFFADAPTOR_LIBRARY)
-# define UBCFFADAPTORSHARED_EXPORT Q_DECL_EXPORT
-#else
-# define UBCFFADAPTORSHARED_EXPORT Q_DECL_IMPORT
-#endif
-
-#endif // UBCFFADAPTOR_GLOBAL_H
diff --git a/plugins/cffadaptor/src/UBCFFConstants.h b/plugins/cffadaptor/src/UBCFFConstants.h
deleted file mode 100644
index 276eb75a6..000000000
--- a/plugins/cffadaptor/src/UBCFFConstants.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour l'Education Numérique en Afrique (GIP ENA)
- *
- * 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 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Open-Sankoré. If not, see .
- */
-
-
-#ifndef UBCFFCONSTANTS_H
-#define UBCFFCONSTANTS_H
-
-#define PI 3.1415926535
-
-const int DEFAULT_BACKGROUND_LAYER = -20000002;
-const int DEFAULT_BACKGROUND_CROSS_LAYER = -20000001;
-
-// Constant names. Use only them instead const char* in each function
-
-// Constant fileNames;
-const QString fMetadata = "metadata.rdf";
-const QString fIWBContent = "content.xml";
-const QString fIWBBackground = "background.png";
-const QString sAudioElementImage = ":images/soundOn.svg";
-
-// Constant messages;
-const QString noErrorMsg = "NoError";
-
-// Tag names
-const QString tDescription = "Description";
-const QString tIWBRoot = "iwb";
-const QString tIWBMeta = "meta";
-const QString tUBZSize = "size";
-const QString tSvg = "svg";
-const QString tIWBPage = "page";
-const QString tIWBPageSet = "pageset";
-const QString tId = "id";
-const QString tElement = "element";
-const QString tUBZGroup = "group";
-const QString tUBZGroups = "groups";
-const QString tUBZG = "g";
-const QString tUBZPolygon = "polygon";
-const QString tUBZPolyline = "polyline";
-const QString tUBZLine = "line";
-const QString tUBZAudio = "audio";
-const QString tUBZVideo = "video";
-const QString tUBZImage = "image";
-const QString tUBZForeignObject = "foreignObject";
-const QString tUBZTextContent = "itemTextContent";
-
-const QString tIWBA = "a";
-const QString tIWBG = "g";
-const QString tIWBSwitch = "switch";
-const QString tIWBImage = "image";
-const QString tIWBVideo = "video";
-const QString tIWBAudio = "audio";
-const QString tIWBText = "text";
-const QString tIWBTextArea = "textarea";
-const QString tIWBPolyLine = "polyline";
-const QString tIWBPolygon = "polygon";
-const QString tIWBFlash = "video";
-const QString tIWBRect = "rect";
-const QString tIWBLine = "line";
-const QString tIWBTbreak = "tbreak";
-const QString tIWBTspan = "tspan";
-
-// Attributes names
-const QString aIWBVersion = "version";
-const QString aOwner = "owner";
-const QString aDescription = "description";
-const QString aCreator = "creator";
-const QString aAbout = "about";
-const QString aIWBViewBox = "viewbox";
-const QString aUBZViewBox = "viewBox";
-const QString aDarkBackground = "dark-background";
-const QString aBackground = "background";
-const QString aCrossedBackground = "crossed-background";
-const QString aUBZType = "type";
-const QString aUBZUuid = "uuid";
-const QString aUBZParent = "parent";
-const QString aFill = "fill"; // IWB attribute contans color to fill
-
-const QString aID = "id"; // ID of any svg element can be placed in to iwb section
-const QString aRef = "ref"; // as reference for applying additional attributes
-const QString aSVGHref = "xlink:href"; // reference to file
-const QString aIWBHref = "ref"; // reference to element ID
-const QString aUBZHref = "href";
-const QString aUBZSource = "source";
-const QString aSrc = "src";
-const QString aSVGRequiredExtension = "requiredExtensions";
-
-const QString aX = "x";
-const QString aY = "y";
-const QString aWidth = "width";
-const QString aHeight = "height";
-const QString aStroke = "stroke";
-const QString aStrokeWidth = "stroke-width";
-const QString aPoints = "points";
-const QString aZLayer = "z-value";
-const QString aLayer = "layer";
-const QString aTransform = "transform";
-const QString aLocked = "locked";
-const QString aIWBName = "name";
-const QString aIWBContent = "content";
-
-
-// Attribute values
-const QString avIWBVersionNo = "1.0";
-const QString avUBZText = "text";
-const QString avFalse = "false";
-const QString avTrue = "true";
-
-// Namespaces and prefixes
-const QString svgRequiredExtensionPrefix = "http://www.imsglobal.org/iwb/";
-const QString dcNS = "http://purl.org/dc/elements/1.1/";
-const QString ubNS = "http://uniboard.mnemis.com/document";
-const QString svgUBZNS = "http://www.imsglobal.org/xsd/iwb_v1p0";
-const QString svgIWBNS = "http://www.w3.org/2000/svg";
-const QString xlinkNS = "http://www.w3.org/1999/xlink";
-const QString iwbNS = "http://www.imsglobal.org/xsd/iwb_v1p0";
-const QString xsiNS = "http://www.w3.org/2001/XMLSchema-instance";
-const QString xsiShemaLocation = "\
-http://www.imsglobal.org/xsd/iwb_v1p0 \
-http://www.imsglobal.org/profile/iwb/iwbv1p0_v1p0.xsd \
-http://www.w3.org/2000/svg http://www.imsglobal.org/profile/iwb/svgsubsetv1p0_v1p0.xsd \
-http://www.w3.org/1999/xlink http://www.imsglobal.org/xsd/w3/1999/xlink.xsd";
-const QString dcNSPrefix = "dc";
-const QString ubNSPrefix = "ub";
-const QString svgIWBNSPrefix = "svg";
-const QString xlinkNSPrefix = "xlink";
-const QString iwbNsPrefix = "iwb";
-const QString xsiPrefix = "xsi";
-const QString xsiSchemaLocationPrefix = "schemaLocation";
-
-const QString avOwner = "";
-const QString avCreator = "";
-const QString avDescription = "";
-
-//constant symbols and words etc
-const QString dimensionsDelimiter1 = "x";
-const QString dimensionsDelimiter2 = " ";
-const QString pageAlias = "page";
-const QString pageFileExtentionUBZ = "svg";
-
-//content folder names
-const QString cfImages = "images";
-const QString cfVideos = "video";
-const QString cfAudios = "audio";
-const QString cfFlash = "flash";
-
-//known file extentions
-const QString feSvg = "svg";
-const QString feWgt = "wgt";
-const QString fePng = "png";
-
-const int iCrossSize = 32;
-const int iCrossWidth = 1;
-
-// Image formats supported by CFF exclude wgt. Wgt is Sankore widget, which is considered as a .png preview.
-const QString iwbElementImage(" \
-wgt, \
-jpeg, \
-jpg, \
-bmp, \
-gif, \
-wmf, \
-emf, \
-png, \
-tif, \
-tiff \
-");
-
-// Video formats supported by CFF
-const QString iwbElementVideo(" \
-mpg, \
-mpeg, \
-swf, \
-");
-
-// Audio formats supported by CFF
-const QString iwbElementAudio(" \
-mp3, \
-wav \
-");
-
-const QString cffSupportedFileFormats(iwbElementImage + iwbElementVideo + iwbElementAudio);
-const QString ubzFormatsToConvert("svg");
-
-
-const QString iwbSVGImageAttributes(" \
-id, \
-xlink:href, \
-x, \
-y, \
-height, \
-width, \
-fill-opacity, \
-requiredExtentions, \
-transform \
-");
-
-
-const QString iwbSVGAudioAttributes(" \
-id, \
-xlink:href, \
-x, \
-y, \
-height, \
-width, \
-fill-opacity, \
-requiredExtentions, \
-transform \
-");
-
-const QString iwbSVGVideoAttributes(" \
-id, \
-xlink:href, \
-x, \
-y, \
-height, \
-width, \
-fill-opacity, \
-requiredExtentions, \
-transform \
-");
-
-const QString iwbSVGRectAttributes(" \
-id, \
-x, \
-y, \
-height, \
-width, \
-fill, \
-fill-opacity, \
-stroke, \
-stroke-dasharray, \
-stroke-linecap, \
-stroke-linejoin, \
-stroke-opacity, \
-stroke-width, \
-transform \
-");
-
-
-
-const QString iwbSVGTextAttributes(" \
-id, \
-x, \
-y, \
-fill, \
-font-family, \
-font-size, \
-font-style, \
-font-weight, \
-font-stretch, \
-transform \
-");
-
-const QString iwbSVGTextAreaAttributes(" \
-id, \
-x, \
-y, \
-height, \
-width, \
-fill, \
-font-family, \
-font-size, \
-font-style, \
-font-weight, \
-font-stretch, \
-text-align, \
-transform \
-");
-
-const QString iwbSVGTspanAttributes(" \
-id, \
-fill, \
-font-family, \
-font-size, \
-font-style, \
-font-weight, \
-font-stretch, \
-text-align, \
-");
-
-const QString iwbSVGLineAttributes(" \
-id, \
-x1, \
-y1, \
-x2, \
-y2, \
-stroke, \
-stroke-dasharray, \
-stroke-width, \
-stroke-opacity, \
-stroke-linecap, \
-transform \
-");
-
-const QString iwbSVGPolyLineAttributes(" \
-id, \
-points, \
-stroke, \
-stroke-width, \
-stroke-dasharray, \
-stroke-opacity, \
-stroke-linecap, \
-transform \
-");
-
-const QString iwbSVGPolygonAttributes(" \
-id, \
-points, \
-fill, \
-fill-opacity, \
-stroke, \
-stroke-dasharray, \
-stroke-width, \
-stroke-linecap, \
-stroke-linejoin, \
-stroke-opacity, \
-stroke-width, \
-transform \
-");
-
-// 1 to 1 copy to SVG section
-const QString iwbElementAttributes(" \
-background, \
-background-fill, \
-background-posture, \
-flip, \
-freehand, \
-highlight, \
-highlight-fill, \
-list-style-type, \
-list-style-type-fill, \
-locked, \
-replicate, \
-revealer, \
-stroke-lineshape-start, \
-stroke-lineshape-end \
-");
-
-// cannot be copied 1 to 1 to SVG section
-const QString ubzElementAttributesToConvert(" \
-xlink:href, \
-src, \
-transform, \
-uuid \
-"
-);
-
-// additional attributes. Have references in SVG section.
-const QString svgElementAttributes(" \
-points, \
-fill, \
-fill-opacity, \
-stroke, \
-stroke-dasharray, \
-stroke-linecap, \
-stroke-opacity, \
-stroke-width, \
-stroke_linejoin, \
-requiredExtensions, \
-viewbox, \
-x, \
-y, \
-x1, \
-y1, \
-x2, \
-y2, \
-height, \
-width, \
-font-family, \
-font-size, \
-font-style, \
-font-weight, \
-font-stretch, \
-text-align \
-");
-
-const QString ubzContentFolders("audios,videos,images,widgets");
-
-#endif // UBCFFCONSTANTS_H
diff --git a/plugins/cffadaptor/src/UBGlobals.h b/plugins/cffadaptor/src/UBGlobals.h
deleted file mode 100644
index d49c11cfa..000000000
--- a/plugins/cffadaptor/src/UBGlobals.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
- *
- * Copyright (C) 2013 Open Education Foundation
- *
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
- * l'Education Numérique en Afrique (GIP ENA)
- *
- * This file is part of OpenBoard.
- *
- * OpenBoard 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).
- *
- * OpenBoard is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenBoard. If not, see .
- */
-
-
-#ifndef UBGLOBALS_H
-#define UBGLOBALS_H
-
-#define DELETEPTR(ptr) if(NULL != ptr){ \
- delete ptr; \
- ptr = NULL; \
- }
-
-#ifdef Q_WS_WIN
-
-#define WARNINGS_DISABLE __pragma(warning(push, 0));
-#define WARNINGS_ENABLE __pragma(warning(pop));
-
-#ifdef NO_THIRD_PARTY_WARNINGS
-// disabling warning level to 0 and save old state
-#define THIRD_PARTY_WARNINGS_DISABLE WARNINGS_DISABLE
-#else
-// just save old state (needs for not empty define)
-#define THIRD_PARTY_WARNINGS_DISABLE __pragma(warning(push));
-#endif //#ifdef NO_THIRD_PARTY_WARNINGS
-// anyway on WIN
-#define THIRD_PARTY_WARNINGS_ENABLE WARNINGS_ENABLE
-
-#else //#ifdef Q_WS_WIN
-
-#define WARNINGS_DISABLE _Pragma("GCC diagnostic push"); \
-_Pragma("GCC diagnostic ignored \"-Wunused-parameter\""); \
-_Pragma("GCC diagnostic ignored \"-Wunused-variable\""); \
-_Pragma("GCC diagnostic ignored \"-Wsign-compare\"");
-
-#define WARNINGS_ENABLE _Pragma("GCC diagnostic pop");
-
-#ifdef NO_THIRD_PARTY_WARNINGS
-//disabling some warnings
-#define THIRD_PARTY_WARNINGS_DISABLE WARNINGS_DISABLE
-
-#define THIRD_PARTY_WARNINGS_ENABLE WARNINGS_ENABLE
-#else
-// just save old state (needs for not empty define)
-#define THIRD_PARTY_WARNINGS_ENABLE WARNINGS_ENABLE
-
-#endif //#ifdef NO_THIRD_PARTY_WARNINGS
-
-#endif //#ifdef Q_WS_WIN
-
-#endif // UBGLOBALS_H
-
diff --git a/plugins/plugins.pri b/plugins/plugins.pri
deleted file mode 100644
index ddf3113a6..000000000
--- a/plugins/plugins.pri
+++ /dev/null
@@ -1,6 +0,0 @@
-HEADERS += plugins/cffadaptor/src/UBCFFAdaptor_global.h \
- plugins/cffadaptor/src/UBCFFAdaptor.h \
- plugins/cffadaptor/src/UBCFFConstants.h \
- plugins/cffadaptor/src/UBGlobals.h
-
-SOURCES += plugins/cffadaptor/src/UBCFFAdaptor.cpp
diff --git a/resources/OpenBoard.qrc b/resources/OpenBoard.qrc
index 6e817b3e6..fe55f1d62 100644
--- a/resources/OpenBoard.qrc
+++ b/resources/OpenBoard.qrc
@@ -2,7 +2,6 @@
images/OpenBoard.png
images/bigOpenBoard.png
- images/close.svg
images/increase.svg
images/decrease.svg
images/resize.svg
@@ -34,6 +33,8 @@
images/resizeRuler.svg
images/resizeCompass.svg
images/closeTool.svg
+ images/close.svg
+ images/close-no-bg.png
images/hflipTool.svg
images/vflipTool.svg
images/resetTool.svg
@@ -153,22 +154,6 @@
images/stylusPalette/captureAreaOn.png
images/stylusPalette/snap.svg
images/stylusPalette/snapOn.svg
- images/backgroundPalette/background1.svg
- images/backgroundPalette/background1On.svg
- images/backgroundPalette/background2.svg
- images/backgroundPalette/background2On.svg
- images/backgroundPalette/background3.svg
- images/backgroundPalette/background3On.svg
- images/backgroundPalette/background4.svg
- images/backgroundPalette/background4On.svg
- images/backgroundPalette/background5.svg
- images/backgroundPalette/background5On.svg
- images/backgroundPalette/background6.svg
- images/backgroundPalette/background6On.svg
- images/backgroundPalette/background7.svg
- images/backgroundPalette/background7On.svg
- images/backgroundPalette/background8.svg
- images/backgroundPalette/background8On.svg
images/toolPalette/podcast.svg
images/toolPalette/podcastOn.svg
images/toolPalette/rulerTool.png
@@ -212,8 +197,6 @@
images/addItemToCurrentPage.svg
images/addItemToNewPage.svg
images/addItemToLibrary.svg
- style/treeview-branch-closed.png
- style/treeview-branch-open.png
webbrowser/closetab.png
webbrowser/loading.gif
webbrowser/notfound.html
@@ -226,6 +209,8 @@
images/save.svg
images/libpalette/social.png
images/navig_arrow.png
+ darkTheme.qss
+ lightTheme.qss
images/flags/ar.png
images/flags/bg.png
images/flags/ca.png
@@ -333,18 +318,14 @@
images/libpalette/FlashCategory.svg
images/libpalette/FlashIcon.svg
images/toolbar/stylusTab.png
- images/library_close.png
- images/library_open.png
- images/pages_close.png
- images/pages_open.png
images/cache_close.png
images/cache_open.png
images/cache_circle.png
images/cache_square.png
- images/down_arrow.png
- images/up_arrow.png
- images/left_arrow.png
- images/right_arrow.png
+ images/down_arrow.svg
+ images/up_arrow.svg
+ images/left_arrow.svg
+ images/right_arrow.svg
images/moveUp.svg
images/moveDown.svg
images/moveDownDisabled.svg
@@ -353,8 +334,6 @@
images/moveUpDisabled.svg
style.qss
images/libpalette/WebSearchCategory.svg
- images/download_close.png
- images/download_open.png
images/tab_mask.png
images/duplicateDisabled.svg
images/roundeRrectangle.svg
@@ -400,5 +379,11 @@
images/removeFromFavorites.png
images/toolbar/tip.png
images/moveTool.svg
+ images/lightMode.svg
+ images/darkMode.svg
+ images/backgroundPalette/bgButtonTemplateDarkOff.svg
+ images/backgroundPalette/bgButtonTemplateDarkOn.svg
+ images/backgroundPalette/bgButtonTemplateLightOff.svg
+ images/backgroundPalette/bgButtonTemplateLightOn.svg
diff --git a/resources/customizations/fonts/Marelle-LICENSE.txt b/resources/customizations/fonts/Marelle-LICENSE.txt
new file mode 100644
index 000000000..4b8a16531
--- /dev/null
+++ b/resources/customizations/fonts/Marelle-LICENSE.txt
@@ -0,0 +1,92 @@
+Copyright 2026 Ministère de l’Éducation nationale, de l’Enseignement supérieur et de la Recherche, Laurent Bourcellier, Jonathan Fabreguettes and Rosalie Wagner, with Reserved Font Name "Marelle".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://openfontlicense.org
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION AND CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/resources/customizations/fonts/Marelle-Regular.ttf b/resources/customizations/fonts/Marelle-Regular.ttf
new file mode 100644
index 000000000..04b4d3662
Binary files /dev/null and b/resources/customizations/fonts/Marelle-Regular.ttf differ
diff --git a/resources/customizations/fonts/Marelle2-Regular.ttf b/resources/customizations/fonts/Marelle2-Regular.ttf
new file mode 100644
index 000000000..af86177a5
Binary files /dev/null and b/resources/customizations/fonts/Marelle2-Regular.ttf differ
diff --git a/resources/customizations/fonts/MarelleBaton-Regular.ttf b/resources/customizations/fonts/MarelleBaton-Regular.ttf
new file mode 100644
index 000000000..070aacbeb
Binary files /dev/null and b/resources/customizations/fonts/MarelleBaton-Regular.ttf differ
diff --git a/resources/customizations/fonts/MarelleBaton2-Regular.ttf b/resources/customizations/fonts/MarelleBaton2-Regular.ttf
new file mode 100644
index 000000000..14bf32638
Binary files /dev/null and b/resources/customizations/fonts/MarelleBaton2-Regular.ttf differ
diff --git a/resources/customizations/fonts/MarelleLIGNES-Regular.otf b/resources/customizations/fonts/MarelleLIGNES-Regular.otf
new file mode 100644
index 000000000..06389f12f
Binary files /dev/null and b/resources/customizations/fonts/MarelleLIGNES-Regular.otf differ
diff --git a/resources/customizations/fonts/MarelleLIGNES2-Regular.otf b/resources/customizations/fonts/MarelleLIGNES2-Regular.otf
new file mode 100644
index 000000000..c9df0b401
Binary files /dev/null and b/resources/customizations/fonts/MarelleLIGNES2-Regular.otf differ
diff --git a/resources/customizations/fonts/MarelleLIGNESBaton-Regular.otf b/resources/customizations/fonts/MarelleLIGNESBaton-Regular.otf
new file mode 100644
index 000000000..2a66a58a9
Binary files /dev/null and b/resources/customizations/fonts/MarelleLIGNESBaton-Regular.otf differ
diff --git a/resources/customizations/fonts/MarelleLIGNESBaton2-Regular.otf b/resources/customizations/fonts/MarelleLIGNESBaton2-Regular.otf
new file mode 100644
index 000000000..99c9411e8
Binary files /dev/null and b/resources/customizations/fonts/MarelleLIGNESBaton2-Regular.otf differ
diff --git a/resources/darkTheme.qss b/resources/darkTheme.qss
new file mode 100644
index 000000000..944b7eeac
--- /dev/null
+++ b/resources/darkTheme.qss
@@ -0,0 +1,1026 @@
+/*
+ * OpenBoard Dark Theme
+ */
+
+/* Base colors for dark theme */
+QWidget {
+ background-color: #353535;
+ color: #ffffff;
+}
+
+QMainWindow {
+ background-color: #2b2b2b;
+}
+
+/* Dialogs and Windows */
+QDialog, QMessageBox {
+ background-color: #353535;
+ color: #ffffff;
+}
+
+/* Text inputs */
+QLineEdit, QTextEdit, QPlainTextEdit {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ border-radius: 3px;
+ padding: 3px;
+ selection-background-color: #2a82da;
+ selection-color: #ffffff;
+}
+
+QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {
+ border: 1px solid #2a82da;
+ background-color: #2a2a2a;
+}
+
+QLineEdit:disabled, QTextEdit:disabled, QPlainTextEdit:disabled {
+ background-color: #404040;
+ color: #808080;
+}
+
+/* Labels */
+QLabel {
+ color: #ffffff;
+ background: transparent;
+}
+
+QLabel:disabled {
+ color: #808080;
+}
+
+/* Buttons */
+QPushButton {
+ background-color: #454545;
+ color: #ffffff;
+ border: 1px solid #555555;
+ border-radius: 4px;
+ padding: 6px 16px;
+ min-height: 20px;
+}
+
+QPushButton:hover {
+ background-color: #505050;
+ border: 1px solid #6a6a6a;
+}
+
+QPushButton:pressed {
+ background-color: #2a82da;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QPushButton:checked {
+ background-color: #2a82da;
+ color: #ffffff;
+}
+
+QPushButton:disabled {
+ background-color: #404040;
+ color: #808080;
+ border: 1px solid #404040;
+}
+
+QPushButton:default {
+ background-color: #2a82da;
+ color: #ffffff;
+ border: 2px solid #3d8fd1;
+}
+
+/* Checkboxes and Radio buttons */
+QCheckBox, QRadioButton {
+ color: #ffffff;
+ spacing: 5px;
+}
+
+QCheckBox:disabled, QRadioButton:disabled {
+ color: #808080;
+}
+
+QCheckBox::indicator, QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border: 1px solid #555555;
+ border-radius: 3px;
+ background-color: #2a2a2a;
+}
+
+QCheckBox::indicator:hover, QRadioButton::indicator:hover {
+ border: 1px solid #6a6a6a;
+}
+
+QCheckBox::indicator:checked, QRadioButton::indicator:checked {
+ background-color: #2a82da;
+}
+
+QRadioButton::indicator {
+ border-radius: 8px;
+}
+
+/* Combo boxes */
+QComboBox {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ border-radius: 3px;
+ padding: 4px 8px;
+ min-height: 20px;
+}
+
+QComboBox:hover {
+ border: 1px solid #6a6a6a;
+}
+
+QComboBox:focus {
+ border: 1px solid #2a82da;
+}
+
+QComboBox::drop-down {
+ border: none;
+ width: 20px;
+}
+
+QComboBox::down-arrow {
+ image: url(:/images/down_arrow.svg);
+ width: 12px;
+ height: 12px;
+}
+
+QComboBox QAbstractItemView {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ selection-background-color: #2a82da;
+ selection-color: #ffffff;
+ outline: none;
+}
+
+QComboBox QAbstractItemView::item {
+ padding: 4px;
+ min-height: 20px;
+}
+
+QComboBox QAbstractItemView::item:hover {
+ background-color: #404040;
+}
+
+#UBPageNavigationWidget {
+ background-color: #353535;
+}
+
+/* Spin boxes */
+QSpinBox, QDoubleSpinBox {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ border-radius: 3px;
+ padding: 3px;
+}
+
+QSpinBox:focus, QDoubleSpinBox:focus {
+ border: 1px solid #2a82da;
+}
+
+QSpinBox::up-button, QDoubleSpinBox::up-button {
+ background-color: #404040;
+ border-left: 1px solid #555555;
+ width: 10px;
+ border-top-right-radius: 3px;
+}
+
+QSpinBox::down-button, QDoubleSpinBox::down-button {
+ background-color: #404040;
+ border-left: 1px solid #555555;
+ width: 10px;
+ border-bottom-right-radius: 3px;
+}
+
+QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover,
+QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover {
+ background-color: #505050;
+}
+
+QSpinBox::up-arrow, QDoubleSpinBox::up-arrow {
+ image: url(:/images/up_arrow.svg);
+ width: 10px;
+ height: 10px;
+}
+
+QSpinBox::down-arrow, QDoubleSpinBox::down-arrow {
+ image: url(:/images/down_arrow.svg);
+ width: 10px;
+ height: 10px;
+}
+
+/* Sliders */
+QSlider::groove:horizontal {
+ background-color: #404040;
+ height: 8px;
+ border-radius: 4px;
+ border: 1px solid #2a2a2a;
+}
+
+QSlider::handle:horizontal {
+ background-color: #2a82da;
+ border: 1px solid #3d8fd1;
+ width: 16px;
+ margin: -5px 0;
+ border-radius: 8px;
+}
+
+QSlider::handle:horizontal:hover {
+ background-color: #3d8fd1;
+}
+
+QSlider::groove:vertical {
+ background-color: #404040;
+ width: 8px;
+ border-radius: 4px;
+ border: 1px solid #2a2a2a;
+}
+
+QSlider::handle:vertical {
+ background-color: #2a82da;
+ border: 1px solid #3d8fd1;
+ height: 16px;
+ margin: 0 -5px;
+ border-radius: 8px;
+}
+
+/* Scrollbars */
+QScrollBar:vertical {
+ background: #2b2b2b;
+ width: 14px;
+ margin: 18px 1px 18px 1px;
+}
+
+QScrollBar::handle:vertical {
+ background: white;
+ min-height: 30px;
+ border-radius: 6px;
+ border: 1px solid #1e5fa0;
+}
+
+QScrollBar::handle:vertical:hover {
+ background: #3d8fd1;
+}
+
+QScrollBar::handle:vertical:pressed {
+ background: #1e5fa0;
+}
+
+QScrollBar::add-line:vertical {
+ background: transparent;
+ border: none;
+ height: 0px;
+}
+
+QScrollBar::sub-line:vertical {
+ background: transparent;
+ border: none;
+ height: 0px;
+}
+
+QScrollBar:horizontal {
+ background: #2a82da;
+ height: 14px;
+ margin: 1px 18px 1px 18px;
+}
+
+QScrollBar::handle:horizontal {
+ background: #2a82da;
+ min-width: 30px;
+ border-radius: 6px;
+ border: 1px solid white;
+}
+
+QScrollBar::handle:horizontal:!hover {
+ background: #2a82da;
+ border: 1px solid #1e5fa0;
+}
+
+QScrollBar::handle:horizontal:hover {
+ background: #3d8fd1;
+}
+
+QScrollBar::handle:horizontal:pressed {
+ background: #1e5fa0;
+}
+
+QScrollBar::add-line:horizontal {
+ background: transparent;
+ border: none;
+ width: 0px;
+}
+
+QScrollBar::sub-line:horizontal {
+ background: transparent;
+ border: none;
+ width: 0px;
+}
+
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical,
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
+ background: none;
+}
+
+/* Tab widgets */
+QTabWidget::pane {
+ border: 1px solid #555555;
+ background-color: #353535;
+ border-top: none;
+}
+
+QTabBar::tab {
+ background-color: #2b2b2b;
+ color: #ffffff;
+ border: 1px solid #555555;
+ padding: 6px 12px;
+ margin-right: 2px;
+}
+
+QTabBar::tab:selected {
+ background-color: #353535;
+ border-bottom: none;
+ color: #ffffff;
+}
+
+QTabBar::tab:hover:!selected {
+ background-color: #404040;
+}
+
+QTabBar::tab:top {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+/* Group boxes */
+QGroupBox {
+ color: #ffffff;
+ border: 1px solid #555555;
+ border-radius: 5px;
+ margin-top: 12px;
+ font-weight: bold;
+ padding-top: 10px;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 5px;
+ color: #ffffff;
+ background-color: #353535;
+}
+
+/* Tree and List views */
+QTreeView {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ alternate-background-color: #323232;
+ selection-background-color: #2a82da;
+ selection-color: #ffffff;
+ show-decoration-selected: 0;
+ outline: none;
+}
+
+QListView, QTableView {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ alternate-background-color: #323232;
+ selection-background-color: #2a82da;
+ selection-color: #ffffff;
+ show-decoration-selected: 1;
+ outline: none;
+}
+
+QTreeView::item, QListView::item, QTableView::item {
+ padding: 3px;
+}
+
+QTreeView::item:hover, QListView::item:hover, QTableView::item:hover {
+ background-color: #404040;
+}
+
+QTreeView::item:selected, QListView::item:selected, QTableView::item:selected {
+ background-color: #2a82da;
+ color: #ffffff;
+}
+
+QTreeView::item:selected:active,
+QListView::item:selected:active,
+QTableView::item:selected:active {
+ background: #2a82da;
+ color: #ffffff;
+ border: none;
+}
+
+QTreeView::branch:selected {
+ background: transparent;
+ color: inherit;
+ border: none;
+}
+
+QTreeView QLineEdit,
+QListView QLineEdit,
+QTableView QLineEdit {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ padding: 1px 6px;
+ selection-background-color: #2a82da;
+ selection-color: #ffffff;
+}
+
+QTreeView QLineEdit:focus,
+QListView QLineEdit:focus,
+QTableView QLineEdit:focus {
+ background-color: #2a2a2a;
+ border: 1px solid #2a82da;
+}
+
+QTreeView::branch {
+ background-color: #2a2a2a;
+}
+
+QTreeView::branch:hover {
+ background-color: #404040;
+}
+
+QHeaderView::section {
+ background-color: #404040;
+ color: #ffffff;
+ padding: 4px;
+ border: 1px solid #555555;
+ font-weight: bold;
+}
+
+QHeaderView::section:hover {
+ background-color: #505050;
+}
+
+/* Menus */
+QMenuBar {
+ background-color: #2b2b2b;
+ color: #ffffff;
+ border-bottom: 1px solid #555555;
+}
+
+QMenuBar::item {
+ background-color: transparent;
+ padding: 4px 8px;
+}
+
+QMenuBar::item:selected {
+ background-color: #2a82da;
+}
+
+QMenuBar::item:pressed {
+ background-color: #2a82da;
+}
+
+QMenu {
+ background-color: #2a2a2a;
+ color: #ffffff;
+ border: 1px solid #555555;
+ padding: 4px;
+}
+
+QMenu::item {
+ padding: 6px 30px 6px 30px;
+ border-radius: 3px;
+}
+
+QMenu::item:selected {
+ background-color: #2a82da;
+}
+
+QMenu::separator {
+ height: 1px;
+ background-color: #555555;
+ margin: 4px 0px;
+}
+
+/* Toolbars */
+QToolBar {
+ background-color: #2b2b2b;
+ border: 1px solid #555555;
+ spacing: 3px;
+ padding: 5px;
+}
+
+QToolBar::separator {
+ background-color: #555555;
+ width: 1px;
+ margin: 4px;
+}
+
+QToolButton {
+ background-color: transparent;
+ color: #ffffff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ padding: 5px;
+ margin: 2px;
+}
+
+QToolButton:hover {
+ background-color: #404040;
+ border: 1px solid #555555;
+}
+
+QToolButton:pressed {
+ background-color: #2a82da;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QToolButton:checked {
+ background-color: #2a82da;
+ color: #ffffff;
+}
+
+QToolButton[popupMode="1"] { /* only for MenuButtonPopup */
+ padding-right: 20px;
+}
+
+QToolButton::menu-button {
+ border: 1px solid #555555;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ width: 16px;
+}
+
+/* Progress bars */
+QProgressBar {
+ background-color: #2a2a2a;
+ border: 1px solid #555555;
+ border-radius: 4px;
+ text-align: center;
+ color: #ffffff;
+ height: 20px;
+}
+
+QProgressBar::chunk {
+ background-color: #2a82da;
+ border-radius: 3px;
+}
+
+/* Status bar */
+QStatusBar {
+ background-color: #2b2b2b;
+ color: #ffffff;
+ border-top: 1px solid #555555;
+}
+
+QStatusBar::item {
+ border: none;
+}
+
+/* Splitter */
+QSplitter::handle {
+ background-color: #555555;
+}
+
+QSplitter::handle:horizontal {
+ width: 2px;
+}
+
+QSplitter::handle:vertical {
+ height: 2px;
+}
+
+QSplitter::handle:hover {
+ background-color: #2a82da;
+}
+
+/* Dock widgets */
+QDockWidget {
+ color: #ffffff;
+ titlebar-close-icon: url(:/images/close.png);
+ titlebar-normal-icon: url(:/images/undock.png);
+}
+
+QDockWidget::title {
+ background-color: #404040;
+ text-align: left;
+ padding-left: 5px;
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+QDockWidget::close-button, QDockWidget::float-button {
+ background-color: #404040;
+ border: none;
+ padding: 0px;
+}
+
+QDockWidget::close-button:hover, QDockWidget::float-button:hover {
+ background-color: #505050;
+}
+
+/* Tooltips */
+QToolTip {
+ background-color: #404040;
+ color: palette(tooltip-text);
+ border: 1px solid #555555;
+ padding: 4px;
+ border-radius: 3px;
+}
+
+/* Scroll areas */
+QScrollArea {
+ background-color: #353535;
+ border: none;
+}
+
+#BackgroundPaletteScrollArea {
+ background-color: #3f3f3f;
+ border: none;
+}
+#BackgroundPaletteScrollArea QWidget{
+ background-color: transparent;
+}
+
+#BackgroundPalette {
+ background-color: #3f3f3f;
+}
+#AddItemPalette {
+ background-color: #3f3f3f;
+}
+
+#DesktopPropertyPalette {
+ background-color: #3f3f3f;
+}
+
+#UBMessageWindow {
+ color: #ffffff;
+}
+
+#UBMessageWindow QLabel#UBMessageWindowLabel {
+ background: transparent;
+ border: none;
+ color: #f8fafc;
+ font-size: 15px;
+ font-weight: 600;
+ padding: 0px 2px 0px 0px;
+}
+
+#UBMessageWindow UBSpinningWheel#UBMessageWindowSpinner {
+ background: transparent;
+ color: #5aa5e0;
+}
+
+#BackgroundPalette QLabel {
+ color: palette(window-text);
+}
+#BackgroundPalette QToolButton#closeButton,
+#AddItemPalette QToolButton#closeButton,
+#UBStartupHintsPalette QToolButton#closeButton {
+ background: transparent;
+ border: none;
+ border-radius: 5px;
+ padding: 0px;
+ color: #ffffff;
+ font-size: 20px;
+ font-weight: bold;
+ min-width: 16px;
+ max-width: 16px;
+ min-height: 16px;
+ max-height: 16px;
+}
+
+#UBStartupHintsPalette QCheckBox {
+ background: transparent;
+ color: #ffffff;
+}
+#BackgroundPalette QToolButton#closeButton:hover,
+#AddItemPalette QToolButton#closeButton:hover,
+#UBStartupHintsPalette QToolButton#closeButton:hover {
+ background: rgba(255, 255, 255, 0.10);
+}
+#BackgroundPalette QToolButton#closeButton:pressed,
+#AddItemPalette QToolButton#closeButton:pressed,
+#UBStartupHintsPalette QToolButton#closeButton:pressed {
+ background: rgba(255, 255, 255, 0.18);
+}
+#BackgroundPaletteLabel {
+ color: palette(window-text);
+}
+
+/* Calendar widget */
+QCalendarWidget {
+ background-color: #2a2a2a;
+}
+
+QCalendarWidget QToolButton {
+ color: #ffffff;
+ background-color: #404040;
+}
+
+QCalendarWidget QMenu {
+ background-color: #2a2a2a;
+}
+
+QCalendarWidget QSpinBox {
+ background-color: #404040;
+ color: #ffffff;
+}
+
+QCalendarWidget QWidget#qt_calendar_navigationbar {
+ background-color: #2b2b2b;
+}
+
+/* Size grip */
+QSizeGrip {
+ background-color: transparent;
+}
+
+/* Override base button group colors for dark mode */
+/* Only override colors; the shared geometry lives in style.qss. */
+QToolButton#ubButtonGroupLeft,
+QToolButton#ubButtonGroupCenter,
+QToolButton#ubButtonGroupRight,
+QToolButton#desktop-ubButtonGroupLeft,
+QToolButton#desktop-ubButtonGroupCenter,
+QToolButton#desktop-ubButtonGroupRight
+{
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #505050, stop: 1 #3a3a3a);
+ color: #ffffff;
+ border-radius: 0px; /* Reset the global QToolButton border-radius */
+ border-left: none;
+ border-right: none;
+}
+
+QToolButton#ubButtonGroupLeft:hover,
+QToolButton#ubButtonGroupCenter:hover,
+QToolButton#ubButtonGroupRight:hover,
+QToolButton#desktop-ubButtonGroupLeft:hover,
+QToolButton#desktop-ubButtonGroupCenter:hover,
+QToolButton#desktop-ubButtonGroupRight:hover
+{
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #606060, stop: 1 #4a4a4a);
+}
+
+QToolButton#ubButtonGroupLeft:checked,
+QToolButton#ubButtonGroupCenter:checked,
+QToolButton#ubButtonGroupRight:checked,
+QToolButton#desktop-ubButtonGroupLeft:checked,
+QToolButton#desktop-ubButtonGroupCenter:checked,
+QToolButton#desktop-ubButtonGroupRight:checked
+{
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2a82da, stop: 1 #1e5fa0);
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QToolButton#ubButtonGroupRight[colorPaletteConfigButton="true"],
+QToolButton#desktop-ubButtonGroupRight[colorPaletteConfigButton="true"]
+{
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #616161, stop: 1 #4a4a4a);
+ color: #ffffff;
+ border-top: none;
+ border-bottom: none;
+ border-left: none;
+ border-right: none;
+}
+
+QToolButton#ubButtonGroupRight[colorPaletteConfigButton="true"]:hover,
+QToolButton#desktop-ubButtonGroupRight[colorPaletteConfigButton="true"]:hover
+{
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #6c6c6c, stop: 1 #555555);
+ color: #ffffff;
+}
+
+QToolButton#ubButtonGroupRight[colorPaletteConfigButton="true"]:pressed,
+QToolButton#desktop-ubButtonGroupRight[colorPaletteConfigButton="true"]:pressed
+{
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #747474, stop: 1 #5e5e5e);
+ color: #ffffff;
+}
+
+QDialog#colorPreferencesDialog {
+ background-color: #353535;
+}
+
+QDialog#colorPreferencesDialog QWidget#colorPreferencesHeader {
+ background-color: #2b2b2b;
+ border: 1px solid #555555;
+ border-radius: 8px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesHeaderLabel {
+ color: #f8fafc;
+ font-size: 14px;
+ font-weight: 600;
+ background: transparent;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider {
+ min-width: 190px;
+ background: transparent;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider::groove:horizontal {
+ height: 6px;
+ background-color: #404040;
+ border: none;
+ border-radius: 3px;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider::handle:horizontal {
+ width: 18px;
+ margin: -7px 0;
+ background-color: #2a82da;
+ border: 1px solid #3d8fd1;
+ border-radius: 9px;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider::sub-page:horizontal {
+ background-color: #2a82da;
+ border-radius: 3px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesPaletteSizeValue {
+ min-width: 32px;
+ padding: 4px 8px;
+ background: #2a2a2a;
+ color: #f8fafc;
+ border: 1px solid #555555;
+ border-radius: 4px;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QWidget#colorPreferencesHint {
+ background: #4b4324;
+ border: 1px solid #7b6b33;
+ border-radius: 6px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesHintIcon {
+ background: transparent;
+ min-width: 20px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesHintText {
+ background: transparent;
+ color: #f1e3a8;
+ font-size: 12px;
+ line-height: 1.3em;
+}
+
+QDialog#colorPreferencesDialog QTabWidget#colorPreferencesTabWidget::pane {
+ border: none;
+ background: transparent;
+ top: -1px;
+}
+
+QDialog#colorPreferencesDialog QTabBar::tab,
+QDialog#colorPreferencesDialog QTabBar::tab:top {
+ background: #2b2b2b;
+ color: #b7c3d4;
+ border: 1px solid #555555;
+ border-radius: 4px;
+ padding: 8px 18px;
+ margin-right: 8px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QTabBar::tab:selected {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2a82da, stop: 1 #1e5fa0);
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QDialog#colorPreferencesDialog QTabBar::tab:hover:!selected {
+ background: #404040;
+ color: #ffffff;
+}
+
+QDialog#colorPreferencesDialog QWidget#colorPreferencesSection {
+ background: #2b2b2b;
+ border: 1px solid #555555;
+ border-radius: 8px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesSectionTitle {
+ background: transparent;
+ color: #f8fafc;
+ font-size: 13px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame {
+ border-radius: 6px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="light"] {
+ background: #ffffff;
+ border: 1px solid #d9e0e8;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] {
+ background: #1f1f1f;
+ border: 1px solid #555555;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorShortcutLabel {
+ background: transparent;
+ color: #94a3b8;
+ font-size: 11px;
+ font-weight: 700;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QLabel#colorShortcutLabel {
+ color: #e2e8f0;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton#ubButtonGroupLeft,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton#ubButtonGroupCenter,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton#ubButtonGroupRight {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #fdfefe, stop: 1 #e7edf4);
+ border-top: 1px solid #d9e0e8;
+ border-bottom: 1px solid #d9e0e8;
+ border-left: none;
+ border-right: none;
+ border-radius: 0px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="light"] QToolButton#ubButtonGroupLeft {
+ border-left: 1px solid #d9e0e8;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="light"] QToolButton#ubButtonGroupRight {
+ border-right: 1px solid #d9e0e8;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupLeft,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupCenter,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupRight {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #505050, stop: 1 #3a3a3a);
+ border-top: 1px solid #555555;
+ border-bottom: 1px solid #555555;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupLeft {
+ border-left: 1px solid #555555;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupRight {
+ border-right: 1px solid #555555;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton:hover {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #f4f9ff, stop: 1 #dcebf9);
+ border-top-color: #c6d9ec;
+ border-bottom-color: #c6d9ec;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton:hover {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #606060, stop: 1 #4a4a4a);
+ border-top-color: #6a6a6a;
+ border-bottom-color: #6a6a6a;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesOpacityValue {
+ color: #ffffff;
+ font-size: 13px;
+ font-weight: 700;
+ background: transparent;
+}
+
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton {
+ padding: 7px 14px;
+ background: #454545;
+ color: #f8fafc;
+ border: 1px solid #555555;
+ border-radius: 4px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton:hover {
+ background: #505050;
+ border: 1px solid #6a6a6a;
+}
+
+QDialog#colorPreferencesDialog QDialogButtonBox#colorPreferencesButtonBox QPushButton {
+ min-width: 92px;
+ padding: 8px 18px;
+ border-radius: 4px;
+ font-weight: 600;
+}
+
+QWidget#UBFeaturesActionBar QToolButton
+{
+ padding: 0px;
+}
diff --git a/resources/etc/OpenBoard.config b/resources/etc/OpenBoard.config
index ce77e232e..ffc35de9b 100644
--- a/resources/etc/OpenBoard.config
+++ b/resources/etc/OpenBoard.config
@@ -104,7 +104,6 @@ PublishToIntranet=false
PublishingUrl=
[Library]
-AnimationsDirectory=./library/animations
ApplicationsDirectory=./library/applications
AudiosDirectory=./library/audios
ImageDirectory=./library/pictures
diff --git a/resources/etc/OpenBoard.css b/resources/etc/OpenBoard.css
index 92672b44e..b4ec1d09d 100644
--- a/resources/etc/OpenBoard.css
+++ b/resources/etc/OpenBoard.css
@@ -1,77 +1,89 @@
QWidget:enabled
{
- color: #3F3F3F;
+ color: palette(text);
}
QWidget:disabled
{
- color: #777777;
+ color: palette(disabled, text);
}
QComboBox,
QPushButton,
QComboBox QAbstractItemView
{
- background: #dddddd;
+ background: palette(button);
+}
+
+QPushButton:focus,
+QPushButton:pressed,
+QPushButton:checked,
+QPushButton:default,
+QToolButton:focus,
+QToolButton:pressed,
+QToolButton:checked
+{
+ color: palette(highlighted-text);
}
QTextEdit,
QLineEdit,
QComboBox#DockPaletteWidgetComboBox QAbstractItemView
{
- selection-background-color: lightgreen;
- selection-color: black;
+ selection-background-color: palette(highlight);
+ selection-color: palette(highlighted-text);
}
-QProgressBar:horizontal {
- border: 1px solid gray;
+QProgressBar:horizontal
+{
+ border: 1px solid palette(mid);
border-radius: 3px;
- background: white;
+ background: palette(base);
padding: 1px;
}
-QProgressBar::chunk:horizontal {
- /*background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, stop: 0 green, stop: 1 lightgreen);*/
- background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);
+QProgressBar::chunk:horizontal
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 palette(mid), stop:1 palette(button));
}
QMainWindow
{
- background-color: #F1F1F1;
+ background-color: palette(window);
}
QDialog
{
- background-color: #dddddd;
+ background-color: palette(button);
}
QMenu
{
border: none;
font-size: 12px;
- background-color: #dddddd;
+ background-color: palette(button);
}
QMenu::item
{
- background-color: #b3b3b3;
+ background-color: palette(midlight);
}
QMenu::item:selected
{
- background-color: #9f9f9f;
+ background-color: palette(mid);
}
QMenu::separator
{
- background-color: #b3b3b3;
- border: 1px dotted #888888;
+ background-color: palette(midlight);
+ border: 1px dotted palette(dark);
}
QToolBar
{
spacing: 0px;
- background-color: #b3b3b3;
+ background-color: palette(midlight);
border: none;
- border-bottom: 1px solid #888888;
+ border-bottom: 1px solid palette(dark);
}
QToolBar::handle
@@ -82,124 +94,56 @@ QToolBar::handle
QToolBar::separator
{
- border: 1px dotted #888888; border-left: none; margin-left: 5px; margin-right: 5px; width: 1px;
-}
-
-QToolBar QToolButton
-{
-
- margin: 4px;
- margin-left: 0px;
- margin-right: 0px;
- padding: 0px;
- border: none;
- height: 58px;
-}
-
-QToolBar QToolButton:pressed
-{
- margin: 4px;
- margin-left: 0px;
- margin-right: 0px;
- padding: 0px;
- border: none;
- height: 58px;
-
- background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5,
- fx:0.5, fy:0.5, stop: 0 #d3d3d3, stop: 1 #b3b3b3);
+ border: 1px dotted palette(dark); border-left: none; margin-left: 5px; margin-right: 5px; width: 1px;
}
QDialog QToolButton:pressed
{
- background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5,
- fx:0.5, fy:0.5, stop: 0 #ffffff, stop: 1 #dddddd);
+ background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5, fx:0.5, fy:0.5, stop: 0 #ffffff, stop: 1 #dddddd);
}
QToolButton#ubButtonGroupLeft,
QToolButton#desktop-ubButtonGroupLeft
{
- background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4);
margin-top: 1px;
margin-right: 0px;
padding: 5px;
-
- border: 1px solid #444444;
- border-right: none;
- border-top-left-radius : 3px;
- border-bottom-left-radius : 3px;
height: 14px;
}
QToolButton#ubButtonGroupCenter,
QToolButton#desktop-ubButtonGroupCenter
{
- background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4);
margin-top: 1px;
margin-right: 0px;
margin-left: 0px;
padding: 5px;
-
- border: 1px solid #444444;
- border-right: none;
- border-left: none;
height: 14px;
}
QToolButton#ubButtonGroupRight,
QToolButton#desktop-ubButtonGroupRight
{
- background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4);
margin-top: 1px;
margin-left: 0px;
padding: 5px;
-
- border: 1px solid #444444;
- border-left: none;
- border-top-right-radius : 3px;
- border-bottom-right-radius : 3px;
height: 14px;
}
-QToolButton#desktop-ubButtonGroupLeft
-QToolButton#desktop-ubButtonGroupCenter,
-QToolButton#desktop-ubButtonGroupRight
-{
- background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #c3c3c3, stop: 1 #ffffff);
-}
-
-QToolButton#desktop-ubButtonGroupLeft:checked,
-QToolButton#desktop-ubButtonGroupCenter:checked,
-QToolButton#desktop-ubButtonGroupRight:checked
-{
- border:1px solid white;
- background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #c3c3c3, stop: 1 #ffffff);
-}
-
-
-QToolButton#ubButtonGroupLeft:checked,
-QToolButton#ubButtonGroupCenter:checked,
-QToolButton#ubButtonGroupRight:checked
-{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #c3c3c3, stop: 1 #b4b4b4);
-}
QToolButton#ubButtonGroupLeft:checked
{
- border-right: 1px solid #444444;
padding-right: 4px;
}
QToolButton#ubButtonGroupCenter:checked
{
- border-left: 1px solid #444444;
- border-right: 1px solid #444444;
padding-right: 4px;
padding-left: 4px;
}
QToolButton#ubButtonGroupRight:checked
{
- border-left: 1px solid #444444;
padding-left: 4px;
}
@@ -209,12 +153,6 @@ QToolButton#ubButtonMenu
padding-right: 12px;
}
-QToolButton#ubButtonMenu:pressed,
-QToolButton#ubButtonMenu:checked
-{
- background-color: #b3b3b3;
-}
-
QToolButton#ubActionPaletteButton
{
margin: 0px;
@@ -237,28 +175,22 @@ QFrame#videoTopLeftFrame,
QFrame#toolTopLeftFrame
{
border: none;
- border-right: 1px solid #888888;
+ border-right: 1px solid palette(dark);
}
QWidget#topRightFrame
{
- background-color: #d3d3d3;
+ background-color: palette(light);
}
QFrame#toolFrame
{
- border-top: 1px solid #888888;
+ border-top: 1px solid palette(dark);
}
QTreeView
{
- background-color: rgb(209, 215, 226);
-}
-
-QTreeView::item:selected:active
-{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAB7C4, stop: 1 #7e8eA0);
- border: none;
+ background-color: palette(base);
}
QTreeView::item
@@ -267,47 +199,18 @@ QTreeView::item
padding-bottom: 1.5 px;
}
-QTreeView::item:selected,
-QTreeView::branch:selected
-{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAB7C4, stop: 1 #7e8eA0);
- border: none;
-}
-
-QTreeView::branch:has-siblings:!adjoins-item,
-QTreeView::branch:!has-children:!has-siblings:adjoins-item,
-QTreeView::branch:has-siblings:adjoins-item
-{
- border-image: none;
- image: none;
-}
-
-QTreeView::branch:has-children:!has-siblings:closed,
-QTreeView::branch:closed:has-children:has-siblings
-{
- border-image: none;
- image: url(:/style/treeview-branch-closed.png);
-}
-
-QTreeView::branch:open:has-children:!has-siblings,
-QTreeView::branch:open:has-children:has-siblings
-{
- border-image: none;
- image: url(:/style/treeview-branch-open.png);
-}
-
QSlider::groove:horizontal
{
- border: 1px solid #999999;
+ border: 1px solid palette(mid);
height: 2px;
- background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 palette(mid), stop:1 palette(button));
margin: 2px 0;
}
QSlider::handle:horizontal
{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #aaaaaa, stop: 1 #b8b8b8);
- border: 1px solid #5c5c5c;
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 palette(midlight), stop: 1 palette(button));
+ border: 1px solid palette(dark);
width: 18px;
margin: -2px 0;
@@ -316,14 +219,14 @@ QSlider::handle:horizontal
QTabWidget::pane
{
- border: 1px solid #888888;
+ border: 1px solid palette(dark);
margin-top: -2px;
}
QTabWidget::pane#libraryTabWidget
{
border: none;
- border-top: 1px solid #888888;
+ border-top: 1px solid palette(dark);
}
QTabWidget::tab-bar
@@ -333,15 +236,15 @@ QTabWidget::tab-bar
QTabWidget::tab-bar#ubWebBrowserTabWidget
{
- background: #dddddd;
+ background: palette(button);
alignment: left;
}
QTabBar::tab
{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d3d3d3, stop: 1 #c4c4c4);
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 palette(light), stop: 1 palette(button));
- border: 1px solid #888888;
+ border: 1px solid palette(dark);
border-bottom: none;
@@ -359,51 +262,51 @@ QTabBar::tab
QTabBar::tab:first
{
- border-left: 1px solid #888888;
+ border-left: 1px solid palette(dark);
}
QTabBar::tab:last
{
- border-right: 1px solid #888888;
+ border-right: 1px solid palette(dark);
}
QTabBar::tab:selected
{
- border-right: 1px solid #888888;
- border-left: 1px solid #888888;
+ border-right: 1px solid palette(dark);
+ border-left: 1px solid palette(dark);
border-bottom: none;
}
QTabBar::tab:first:selected
{
- border-right: 1px solid #888888;
+ border-right: 1px solid palette(dark);
}
QTabBar::tab:last:selected
{
- border-left: 1px solid #888888;
+ border-left: 1px solid palette(dark);
}
QTabBar::tab:selected
{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #aaaaaa, stop: 1 #b8b8b8);
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 palette(midlight), stop: 1 palette(button));
}
QTabBar::tab#ubWebBrowserTabBar
{
- background: #dddddd;
+ background: palette(button);
min-width: 150px;
}
QTabBar::tab:selected#ubWebBrowserTabBar
{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #b3b3b3, stop: 1 #dddddd);
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 palette(midlight), stop: 1 palette(button));
}
QLineEdit#ubWebBrowserLineEdit
{
- border: 1px solid #888888;
+ border: 1px solid palette(dark);
border-radius: 3px;
padding: 2 2px;
- background: white;
+ background: palette(base);
}
diff --git a/resources/etc/background/01_blank.xml b/resources/etc/background/01_blank.xml
new file mode 100644
index 000000000..d76dc8a1c
--- /dev/null
+++ b/resources/etc/background/01_blank.xml
@@ -0,0 +1,26 @@
+
+ 84836d5a-1846-4c91-9ff9-f2c4d118364d
+ Empty
+ Leer
+
+
+ #00000000
+ #00000000
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+
+ 90
+ 10
+
+ 0
+ 1
+
+
+
diff --git a/resources/etc/background/02_ruled.xml b/resources/etc/background/02_ruled.xml
new file mode 100644
index 000000000..6abde93f0
--- /dev/null
+++ b/resources/etc/background/02_ruled.xml
@@ -0,0 +1,14 @@
+
+ 0de33238-c30e-4396-8ec4-2bfc53304389
+ Ruled
+ Liniert
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+
diff --git a/resources/etc/background/03_crossed.xml b/resources/etc/background/03_crossed.xml
new file mode 100644
index 000000000..0e8cc232d
--- /dev/null
+++ b/resources/etc/background/03_crossed.xml
@@ -0,0 +1,22 @@
+
+ 7493c8bb-6d98-4be6-966c-fbddf9eff529
+ Crossed
+ Kariert
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+
+ 90
+ 10
+
+ 0
+ 1
+
+
+
diff --git a/resources/etc/background/04_crossed5.xml b/resources/etc/background/04_crossed5.xml
new file mode 100644
index 000000000..5930b73e6
--- /dev/null
+++ b/resources/etc/background/04_crossed5.xml
@@ -0,0 +1,38 @@
+
+ 8ed2037b-ab38-4d4f-9b52-c4e36b1c8102
+ Crossed 5mm
+ Kariert 5mm
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+ 0.5
+ 0.5
+
+
+
+
+ 90
+ 10
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+ 0.5
+ 0.5
+
+
+
+
diff --git a/resources/etc/background/05_seyes.xml b/resources/etc/background/05_seyes.xml
new file mode 100644
index 000000000..8109fcd7d
--- /dev/null
+++ b/resources/etc/background/05_seyes.xml
@@ -0,0 +1,69 @@
+
+ 38b45f18-f6a5-4336-ae91-bedba3a2442c
+ Seyes
+
+
+ 0
+ 20
+
+ 0
+ 2
+
+ #8e7cc3
+ #8e7cc3
+
+
+
+ 5
+ 2
+
+ #996fa8dc
+ #996fa8dc
+
+
+
+ 10
+ 2
+
+ #996fa8dc
+ #996fa8dc
+
+
+
+ 15
+ 2
+
+ #996fa8dc
+ #996fa8dc
+
+
+
+
+ 90
+ 20
+ topleft
+
+ 20
+ 2
+
+ #8e7cc3
+ #8e7cc3
+
+
+
+ -20
+
+
+
+ 90
+ topleft
+
+ 20
+ 2
+
+ #ff0000
+ #ff0000
+
+
+
+
diff --git a/resources/etc/background/06_staveBorder.xml b/resources/etc/background/06_staveBorder.xml
new file mode 100644
index 000000000..33cd8df21
--- /dev/null
+++ b/resources/etc/background/06_staveBorder.xml
@@ -0,0 +1,42 @@
+
+ 1da51382-220e-40d2-804a-36ca2ab3fbd8
+ Stave lines with border
+ Notenlinien mit Rand
+ Lignes de notes avec bordure
+
+ 0
+ 50
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+
+ 10
+ 1
+
+
+ 15
+ 1
+
+
+ 20
+ 1
+
+
+ -5
+ -5
+
+ 0
+ 1
+
+
+
+ 0
+ 0
+
+
+
diff --git a/resources/etc/background/background.xsd b/resources/etc/background/background.xsd
new file mode 100644
index 000000000..303b74265
--- /dev/null
+++ b/resources/etc/background/background.xsd
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/etc/background/crossed1.xml b/resources/etc/background/crossed1.xml
new file mode 100644
index 000000000..8da7bf0f9
--- /dev/null
+++ b/resources/etc/background/crossed1.xml
@@ -0,0 +1,166 @@
+
+ 5daad8dd-1c41-4c37-9c14-2ab073c7249c
+ Crossed 1mm
+ Millimeterpapier
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+ 1
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 2
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 3
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 4
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 5
+ 1
+
+ 0.6
+ 0.6
+
+
+
+ 6
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 7
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 8
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 9
+ 1
+
+ 0.4
+ 0.4
+
+
+
+
+ 90
+ 10
+
+ 0
+ 1
+
+
+ 1
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 2
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 3
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 4
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 5
+ 1
+
+ 0.6
+ 0.6
+
+
+
+ 6
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 7
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 8
+ 1
+
+ 0.4
+ 0.4
+
+
+
+ 9
+ 1
+
+ 0.4
+ 0.4
+
+
+
+
diff --git a/resources/etc/background/crossed5Border.xml b/resources/etc/background/crossed5Border.xml
new file mode 100644
index 000000000..b1e009826
--- /dev/null
+++ b/resources/etc/background/crossed5Border.xml
@@ -0,0 +1,52 @@
+
+ 9057d897-bbfe-4764-9867-1c75ad4da2e3
+ Crossed 5mm with border
+ Kariert 5mm mit Rand
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+ 0.5
+ 0.5
+
+
+
+ -30
+
+
+
+ 90
+ 10
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+ 0.5
+ 0.5
+
+
+
+ -30
+
+
+
+ 90
+ topleft
+
+ 30
+ 1
+
+
+
diff --git a/resources/etc/background/de-primary1.xml b/resources/etc/background/de-primary1.xml
new file mode 100644
index 000000000..d3f9d1c04
--- /dev/null
+++ b/resources/etc/background/de-primary1.xml
@@ -0,0 +1,33 @@
+
+ ca8931ff-19b6-4217-88f9-9f64ec366bfa
+ German elementary school, first grade
+ Grundschule, erste Klasse
+
+ 0
+ 20
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+
+ 10
+ 1
+
+
+ 15
+ 1
+
+
+ -5
+ -5
+
+ 0
+ 1
+
+
+
+
diff --git a/resources/etc/background/de-primary2.xml b/resources/etc/background/de-primary2.xml
new file mode 100644
index 000000000..be103166b
--- /dev/null
+++ b/resources/etc/background/de-primary2.xml
@@ -0,0 +1,33 @@
+
+ eb53b553-0e73-473c-b4c3-bcd328e27d76
+ German elementary school, second grade
+ Grundschule, zweite Klasse
+
+ 0
+ 16
+
+ 0
+ 1
+
+
+ 4
+ 1
+
+
+ 8
+ 1
+
+
+ 12
+ 1
+
+
+ -5
+ -5
+
+ 0
+ 1
+
+
+
+
diff --git a/resources/etc/background/de-primary3.xml b/resources/etc/background/de-primary3.xml
new file mode 100644
index 000000000..fd5622347
--- /dev/null
+++ b/resources/etc/background/de-primary3.xml
@@ -0,0 +1,25 @@
+
+ ff386ccf-e7e1-4838-b7fa-255c28208209
+ German elementary school, third grade
+ Grundschule, dritte Klasse
+
+ 0
+ 14
+
+ 0
+ 1
+
+
+ 3.5
+ 1
+
+
+ -5
+ -5
+
+ 0
+ 1
+
+
+
+
diff --git a/resources/etc/background/isometric.xml b/resources/etc/background/isometric.xml
new file mode 100644
index 000000000..6bac2b023
--- /dev/null
+++ b/resources/etc/background/isometric.xml
@@ -0,0 +1,30 @@
+
+ 07187386-b012-492c-b0a8-50faa18c28a0
+ Isometric
+ Isometrisches Gitter
+
+
+ 30
+ 8.66025403784
+
+ 0
+ 1
+
+
+
+ 90
+ 8.66025403784
+
+ 0
+ 1
+
+
+
+ 150
+ 8.66025403784
+
+ 0
+ 1
+
+
+
diff --git a/resources/etc/background/ruled5.xml b/resources/etc/background/ruled5.xml
new file mode 100644
index 000000000..a4c15e259
--- /dev/null
+++ b/resources/etc/background/ruled5.xml
@@ -0,0 +1,22 @@
+
+ e986ad6c-9a3e-4a63-a97a-1a19c7fa90cc
+ Ruled 5mm
+ Liniert 5mm
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+ 0.5
+ 0.5
+
+
+
+
diff --git a/resources/etc/background/ruledBorder.xml b/resources/etc/background/ruledBorder.xml
new file mode 100644
index 000000000..c1021972a
--- /dev/null
+++ b/resources/etc/background/ruledBorder.xml
@@ -0,0 +1,25 @@
+
+ c155edf1-bb46-4f4c-a665-a5800eeed465
+ Ruled with border
+ Liniert mit Rand
+
+
+ 0
+ 10
+
+ 0
+ 1
+
+
+ -30
+
+
+
+ 90
+ topleft
+
+ 30
+ 1
+
+
+
diff --git a/resources/etc/background/stave.xml b/resources/etc/background/stave.xml
new file mode 100644
index 000000000..2688462c3
--- /dev/null
+++ b/resources/etc/background/stave.xml
@@ -0,0 +1,30 @@
+
+ 1dd2b623-950c-4d4d-af74-98d576636099
+ Stave lines
+ Notenlinien
+ Lignes de notes
+
+ 0
+ 50
+
+ 0
+ 1
+
+
+ 5
+ 1
+
+
+ 10
+ 1
+
+
+ 15
+ 1
+
+
+ 20
+ 1
+
+
+
diff --git a/resources/etc/kwinKeepAbove.js b/resources/etc/kwinKeepAbove.js
new file mode 100644
index 000000000..90c27ab36
--- /dev/null
+++ b/resources/etc/kwinKeepAbove.js
@@ -0,0 +1,23 @@
+/*
+ * Set keepAbove for OpenBoard DesktopView
+ *
+ * Works with KDE 5 and KDE 6
+ */
+
+function keepOnTop() {
+ // KDE 6 property
+ var allClients = workspace.stackingOrder;
+
+ if (!allClients) {
+ // KDE 5 function
+ allClients = workspace.clientList();
+ }
+ for (var i = 0; i < allClients.length; ++i) {
+ var client = allClients[i];
+ if (client.resourceClass == "ch.openboard.OpenBoard" && client.caption == "DesktopView") {
+ client.keepAbove=true;
+ }
+ }
+}
+
+keepOnTop();
diff --git a/resources/etc/npapi-wrapper.application.x-shockwave-flash.swf.htm b/resources/etc/npapi-wrapper.application.x-shockwave-flash.swf.htm
deleted file mode 100644
index 909d19d1c..000000000
--- a/resources/etc/npapi-wrapper.application.x-shockwave-flash.swf.htm
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- Flash Widget
-
-
-
-
-
-
-
-
diff --git a/resources/etc/npapi-wrapper.config.xml b/resources/etc/npapi-wrapper.config.xml
deleted file mode 100644
index dc3d72114..000000000
--- a/resources/etc/npapi-wrapper.config.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- {in.name}
-
-
-
diff --git a/resources/forms/brushProperties.ui b/resources/forms/brushProperties.ui
index 5c4de12cf..b26db6a88 100644
--- a/resources/forms/brushProperties.ui
+++ b/resources/forms/brushProperties.ui
@@ -20,251 +20,7 @@
QFrame::Plain
- -
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
- -
-
-
-
- 0
- 0
-
-
-
- Pen is Pressure Sensitive
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 198
- 20
-
-
-
-
-
-
-
- -
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 154
- 20
-
-
-
-
- -
-
-
- Opacity
-
-
-
- -
-
-
- 20
-
-
- 100
-
-
- 50
-
-
- Qt::Horizontal
-
-
- QSlider::TicksAbove
-
-
- 20
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 156
- 20
-
-
-
-
-
-
-
- -
-
-
- Qt::LeftToRight
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
-
- 0
-
- -
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
- -
-
-
- On Light Background
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 32
- 32
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
- -
-
-
- On Dark Background
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 32
- 32
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
-
-
-
-
-
- -
+
-
@@ -458,20 +214,57 @@
- -
-
-
- Qt::Vertical
+ -
+
+
+ QFrame::NoFrame
-
-
- 20
- 40
-
+
+ QFrame::Raised
-
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Pen is Pressure Sensitive
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 198
+ 20
+
+
+
+
+
+
- -
+
-
QFrame::NoFrame
@@ -518,7 +311,7 @@
- -
+
-
Qt::Horizontal
@@ -534,12 +327,6 @@
-
- UBColorPicker
- QFrame
-
- 1
-
UBCircleFrame
QFrame
diff --git a/resources/forms/documents.ui b/resources/forms/documents.ui
index 921ca08d5..694a050be 100644
--- a/resources/forms/documents.ui
+++ b/resources/forms/documents.ui
@@ -102,22 +102,6 @@
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 10
- 20
-
-
-
-
-
@@ -146,17 +130,14 @@
-
-
-
- Qt::Horizontal
+
+
+ filter the documents
-
-
- 40
- 20
-
+
+ true
-
+
diff --git a/resources/forms/mainWindow.ui b/resources/forms/mainWindow.ui
index e7c76e60d..09673691f 100644
--- a/resources/forms/mainWindow.ui
+++ b/resources/forms/mainWindow.ui
@@ -555,6 +555,108 @@
5
+
+
+ true
+
+
+
+ :/images/toolbar/color.png :/images/toolbar/color.png
+
+
+ Color 6
+
+
+ Color 6
+
+
+ 6
+
+
+
+
+ true
+
+
+
+ :/images/toolbar/color.png :/images/toolbar/color.png
+
+
+ Color 7
+
+
+ Color 7
+
+
+ 7
+
+
+
+
+ true
+
+
+
+ :/images/toolbar/color.png :/images/toolbar/color.png
+
+
+ Color 8
+
+
+ Color 8
+
+
+ 8
+
+
+
+
+ true
+
+
+
+ :/images/toolbar/color.png :/images/toolbar/color.png
+
+
+ Color 9
+
+
+ Color 9
+
+
+ 9
+
+
+
+
+ true
+
+
+
+ :/images/toolbar/color.png :/images/toolbar/color.png
+
+
+ Color 10
+
+
+ Color 10
+
+
+ 0
+
+
+
+
+
+ :/images/toolbar/settings.png :/images/toolbar/settings.png
+
+
+ Color Preferences
+
+
+ Open color preferences
+
+
@@ -1186,158 +1288,6 @@
-
-
- true
-
-
-
- :/images/backgroundPalette/background1.svg
- :/images/backgroundPalette/background1On.svg :/images/backgroundPalette/background1.svg
-
-
- Plain Light Background
-
-
- Light
-
-
- Plain Light Background
-
-
-
-
- true
-
-
-
- :/images/backgroundPalette/background2.svg
- :/images/backgroundPalette/background2On.svg :/images/backgroundPalette/background2.svg
-
-
- Grid Light Background
-
-
- Light
-
-
- Grid Light Background
-
-
-
-
- true
-
-
-
- :/images/backgroundPalette/background5.svg
- :/images/backgroundPalette/background5On.svg :/images/backgroundPalette/background5.svg
-
-
- Ruled Light Background
-
-
- Light
-
-
- Ruled Light Background
-
-
-
-
- true
-
-
-
- :/images/backgroundPalette/background7.svg
- :/images/backgroundPalette/background7On.svg :/images/backgroundPalette/background7.svg
-
-
- Seyes ruled Light Background
-
-
- Light
-
-
- Seyes ruled Light Background
-
-
-
-
- true
-
-
-
- :/images/backgroundPalette/background3.svg
- :/images/backgroundPalette/background3On.svg :/images/backgroundPalette/background3.svg
-
-
- Plain Dark Background
-
-
- Dark
-
-
- Plain Dark Background
-
-
-
-
- true
-
-
-
- :/images/backgroundPalette/background4.svg
- :/images/backgroundPalette/background4On.svg :/images/backgroundPalette/background4.svg
-
-
- Grid Dark Background
-
-
- Dark
-
-
- Grid Dark Background
-
-
-
-
- true
-
-
-
- :/images/backgroundPalette/background6.svg
- :/images/backgroundPalette/background6On.svg :/images/backgroundPalette/background6.svg
-
-
- Ruled Dark Background
-
-
- Dark
-
-
- Ruled Dark Background
-
-
-
-
- true
-
-
-
- :/images/backgroundPalette/background8.svg
- :/images/backgroundPalette/background8On.svg :/images/backgroundPalette/background8.svg
-
-
- Seyes ruled Dark Background
-
-
- Dark
-
-
- Seyes ruled Dark Background
-
-
true
@@ -1910,20 +1860,20 @@
Reset grid size
-
+
true
- :/images/minus.svg
- :/images/save.svg :/images/minus.svg
+ :/images/lightMode.svg
+ :/images/darkMode.svg :/images/lightMode.svg
- Draw intermediate grid lines
+ Switch between light and dark background
- Draw intermediate grid lines
+ Switch between light and dark background
diff --git a/resources/forms/preferences.ui b/resources/forms/preferences.ui
index 45a2fc180..4ec35bd9f 100644
--- a/resources/forms/preferences.ui
+++ b/resources/forms/preferences.ui
@@ -7,7 +7,7 @@
0
0
1074
- 566
+ 816
@@ -26,9 +26,6 @@
QFrame::NoFrame
-
- QFrame::Raised
-
0
@@ -51,9 +48,6 @@
-
-
- Qt::Horizontal
-
40
@@ -82,7 +76,7 @@
-
- 7
+ 4
@@ -98,22 +92,22 @@
0
- -285
- 1013
- 765
+ 0
+ 1018
+ 1200
783
- 765
+ 1200
0
- 416
+ 920
1011
111
@@ -148,11 +142,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Preferred
+ QSizePolicy::Fixed
@@ -164,9 +155,6 @@
-
-
- Qt::Horizontal
-
40
@@ -181,7 +169,7 @@
0
- 320
+ 710
1011
101
@@ -219,11 +207,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Preferred
+ QSizePolicy::Fixed
@@ -235,9 +220,6 @@
-
-
- Qt::Horizontal
-
40
@@ -252,9 +234,9 @@
0
- 620
+ 1040
1011
- 101
+ 111
@@ -303,9 +285,6 @@
-
-
- Qt::Horizontal
-
QSizePolicy::Fixed
@@ -319,9 +298,6 @@
-
-
- Qt::Horizontal
-
40
@@ -336,7 +312,7 @@
0
- 218
+ 600
1011
101
@@ -353,11 +329,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Expanding
+ QSizePolicy::Fixed
@@ -394,11 +367,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Preferred
+ QSizePolicy::Fixed
@@ -414,7 +384,7 @@
0
- 102
+ 480
1011
104
@@ -471,9 +441,6 @@
-
-
- Qt::Vertical
-
20
@@ -486,11 +453,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Preferred
+ QSizePolicy::Fixed
@@ -502,11 +466,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Preferred
+ QSizePolicy::Fixed
@@ -522,9 +483,9 @@
0
- 540
+ 840
1011
- 71
+ 111
@@ -565,11 +526,34 @@
+ -
+
+
+ Theme:
+
+
+
+ -
+
+ -
+
+ Auto
+
+
+ -
+
+ Light
+
+
+ -
+
+ Dark
+
+
+
+
-
-
- Qt::Horizontal
-
40
@@ -582,11 +566,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Preferred
+ QSizePolicy::Fixed
@@ -604,62 +585,115 @@
0
0
1011
- 90
+ 450
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 450
+
+
Multi display
-
- -
-
-
- true
-
-
-
- -
-
-
- List of screens used for Control, Display and Previous pages
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Preferred
-
-
+
+ -
+
+
- 40
- 20
+ 0
+ 400
-
-
- -
-
-
- Show internal web page content on secondary screen or projector
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 600
+ 300
+
+
+
+
+ 900
+ 800
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 10
+
+
+
+
+
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+ -
+
+ -
+
+
+ Show internal web page content on secondary screen or projector
+
+
+
+ -
+
+
+ List of screens used for Control, Display and Previous pages
+
+
+
+ -
+
+
+ true
+
+
+
+
@@ -673,6 +707,26 @@
Grid
+ -
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 1032
+ 470
+
+
+
+
+
-
@@ -681,18 +735,12 @@
QFrame::NoFrame
-
- QFrame::Raised
-
-
QFrame::NoFrame
-
- QFrame::Raised
-
-
@@ -703,9 +751,6 @@
-
-
- Qt::Horizontal
-
40
@@ -723,10 +768,7 @@
- QFrame::StyledPanel
-
-
- QFrame::Raised
+ QFrame::NoFrame
@@ -738,15 +780,9 @@
QFrame::NoFrame
-
- QFrame::Raised
-
-
-
- Qt::Horizontal
-
154
@@ -777,7 +813,7 @@
Qt::Horizontal
- QSlider::TicksAbove
+ QSlider::NoTicks
20
@@ -786,9 +822,6 @@
-
-
- Qt::Horizontal
-
156
@@ -805,9 +838,6 @@
QFrame::NoFrame
-
- QFrame::Raised
-
-
@@ -818,9 +848,6 @@
-
-
- Qt::Horizontal
-
40
@@ -838,10 +865,7 @@
- QFrame::StyledPanel
-
-
- QFrame::Raised
+ QFrame::NoFrame
@@ -853,15 +877,9 @@
QFrame::NoFrame
-
- QFrame::Raised
-
-
-
- Qt::Horizontal
-
154
@@ -892,7 +910,7 @@
Qt::Horizontal
- QSlider::TicksAbove
+ QSlider::NoTicks
20
@@ -901,9 +919,6 @@
-
-
- Qt::Horizontal
-
156
@@ -920,9 +935,6 @@
-
-
- Qt::Vertical
-
20
@@ -938,14 +950,20 @@
Pen
- -
+
-
+
+
+ 0
+ 0
+
+
+
+ Qt::DefaultContextMenu
+
QFrame::NoFrame
-
- QFrame::Raised
-
@@ -955,14 +973,11 @@
Marker
- -
+
-
QFrame::NoFrame
-
- QFrame::Raised
-
@@ -1063,11 +1078,8 @@
-
-
- Qt::Horizontal
-
- QSizePolicy::Preferred
+ QSizePolicy::Fixed
@@ -1082,9 +1094,6 @@
-
-
- Qt::Vertical
-
20
@@ -1095,6 +1104,211 @@
+
+
+ Shortcut
+
+
+ -
+
+
+ Filter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QScrollArea:disabled {border: 1px solid red;}
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 1032
+ 423
+
+
+
+ -
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+ 25
+
+
+ 25
+
+
+
+
+
+
+
+ -
+
+ -
+
+
+ Active keyboard shortcuts without pressing Ctrl key
+
+
+
+
+
+ -
+
+
+ false
+
+
+ Shortcuts
+
+
+ Qt::AlignCenter
+
+
+ -
+
+ -
+
+
+ Key Sequence
+
+
+
+ -
+
+
+ true
+
+
+ 1
+
+
+
+ -
+
+
+ Mouse Button
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+ Stylus Button
+
+
+
+ -
+
+
+ true
+
+
+
+
+
+ -
+
+
+ color: red;
+
+
+ Qt::PlainText
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Reset
+
+
+
+ -
+
+
+ Abort
+
+
+
+ -
+
+
+ QPushButton:checked {background-color: red}
+
+
+ Record
+
+
+ true
+
+
+
+
+
+
+
+
+
+
true
@@ -1255,7 +1469,7 @@
*/
- Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+ Qt::NoTextInteraction
@@ -1300,7 +1514,7 @@ Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
- Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+ Qt::NoTextInteraction
@@ -2012,7 +2226,7 @@ Public License instead of this License. But first, please read
--8<---------------cut here---------------end--------------->8---
- Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+ Qt::NoTextInteraction
@@ -2382,7 +2596,7 @@ Public License instead of this License.
--8<---------------cut here---------------end--------------->8---
- Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+ Qt::NoTextInteraction
@@ -3089,7 +3303,7 @@ Public License instead of this License. But first, please read
--8<---------------cut here---------------end--------------->8---
- Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+ Qt::NoTextInteraction
@@ -3114,87 +3328,87 @@ Public License instead of this License. But first, please read
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
-</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:12pt; font-weight:600;">Translations</span><span style=" font-family:'Cantarell'; font-size:10pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">A special thanks to:<br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Alexander Angelov and Iva Ninova for Bulgarian</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Francesc Busquets and Toni Hortal for Catalan</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Milo Ivir for Croatian</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Jaroslav Krejčí, Janek Wagner for Czech</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Geert Kraeye and Derk Klomp for Dutch</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Christian Oïhénart for French</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Félix Díaz López for Galician </span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Hans-Peter Zahno, Klaus Tenner and Yves Kaiser for German</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Yannis Kiolalis for Greek</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Imre Fekete for Hungarian</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Antonello Comi, Marco Menardi, Marco Gregori and Salvatore Cristaldi for Italian</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Didier Clerc for Japanese</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Faraniaina Domoina Rabarijaona for Malagasy</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Patricia Fisch and César Marques for Portuguese</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Ilia Ryabokon for Russian</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Jaroslav Ryník for Slovak</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Dorian Fuentes, Juan José Gutiérrez Aparicio and Félix Díaz López for Spanish</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Anki Chen for Traditional Chinese</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Ferhat Ozkasgarli and Sabri Ünal for Turkish</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">• Alex Compit and Joonel for Ukrainian</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;"><br /></span><span style=" font-family:'Cantarell'; font-size:12pt; font-weight:600;">Resources added in OpenBoard</span></p>
+</style></head><body style=" font-family:'Noto Sans',''; font-size:10pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:12pt; font-weight:600;">Translations</span><span style=" font-family:'Cantarell';"><br /></span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">A special thanks to:<br /></span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Alexander Angelov and Iva Ninova for Bulgarian</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Francesc Busquets and Toni Hortal for Catalan</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Milo Ivir for Croatian</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Jaroslav Krejčí, Janek Wagner for Czech</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Geert Kraeye and Derk Klomp for Dutch</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Christian Oïhénart for French</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Félix Díaz López for Galician </span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Hans-Peter Zahno, Klaus Tenner and Yves Kaiser for German</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Yannis Kiolalis for Greek</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Imre Fekete for Hungarian</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Antonello Comi, Marco Menardi, Marco Gregori and Salvatore Cristaldi for Italian</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Didier Clerc for Japanese</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Faraniaina Domoina Rabarijaona for Malagasy</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Patricia Fisch and César Marques for Portuguese</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Ilia Ryabokon for Russian</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Jaroslav Ryník for Slovak</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Dorian Fuentes, Juan José Gutiérrez Aparicio and Félix Díaz López for Spanish</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Anki Chen for Traditional Chinese</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Ferhat Ozkasgarli and Sabri Ünal for Turkish</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">• Alex Compit and Joonel for Ukrainian</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';"><br /></span><span style=" font-family:'Cantarell'; font-size:12pt; font-weight:600;">Resources added in OpenBoard</span></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">AndBasR.ttf </span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Sil Open Font License</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://scripts.sil.org/OFL"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://scripts.sil.org/OFL</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">(c) 2004-2008, SIL International (</span><a href="http://scripts.sil.org"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://scripts.sil.org</span></a><span style=" font-family:'Cantarell'; font-size:10pt;">), </span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">with Reserved Font Names 'Andika' and 'SIL'.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">ec_cour.ttf </span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Open Font License</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://scripts.sil.org/OFL"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://scripts.sil.org/OFL</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">© Jean-Marie Douteau (</span><a href="mailto:douteau.ecolier@sfr.fr"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">douteau.ecolier@sfr.fr</span></a><span style=" font-family:'Cantarell'; font-size:10pt;">)</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Source : </span><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">ecl_cour.ttf</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Open Font License</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://scripts.sil.org/OFL"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://scripts.sil.org/OFL</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">© Jean-Marie Douteau (</span><a href="mailto:douteau.ecolier@sfr.fr"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">douteau.ecolier@sfr.fr</span></a><span style=" font-family:'Cantarell'; font-size:10pt;">)</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Source : </span><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">AndBasR.ttf </span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Sil Open Font License</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://scripts.sil.org/OFL"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://scripts.sil.org/OFL</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">(c) 2004-2008, SIL International (</span><a href="http://scripts.sil.org"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://scripts.sil.org</span></a><span style=" font-family:'Cantarell';">), </span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">with Reserved Font Names 'Andika' and 'SIL'.</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';"><br /></span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">ec_cour.ttf </span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Open Font License</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://scripts.sil.org/OFL"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://scripts.sil.org/OFL</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">© Jean-Marie Douteau (</span><a href="mailto:douteau.ecolier@sfr.fr"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">douteau.ecolier@sfr.fr</span></a><span style=" font-family:'Cantarell';">)</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Source : </span><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';"><br /></span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">ecl_cour.ttf</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Open Font License</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://scripts.sil.org/OFL"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://scripts.sil.org/OFL</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">© Jean-Marie Douteau (</span><a href="mailto:douteau.ecolier@sfr.fr"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">douteau.ecolier@sfr.fr</span></a><span style=" font-family:'Cantarell';">)</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Source : </span><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm</span></a></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#000000;">EcritureA and EcritureB</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by/3.0/"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">Creative Commons BY-ND</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#000000;">DGESCO (</span></a><a href="mailto:degre.numerique@education.gouv.fr"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">degre.numerique@education.gouv.fr</span></a><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#000000;">)</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#000000;">Source: </span></a><a href="http://eduscol.education.fr/cid72979/polices-de-caracteres-cursives-pour-l-enseignement-de-l-ecriture.html"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://eduscol.education.fr/cid72979/polices-de-caracteres-cursives-pour-l-enseignement-de-l-ecriture.html</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#000000;">EcritureA and EcritureB</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by/3.0/"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">Creative Commons BY-ND</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#000000;">DGESCO (</span></a><a href="mailto:degre.numerique@education.gouv.fr"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">degre.numerique@education.gouv.fr</span></a><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#000000;">)</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://douteau.ecolier.perso.sfr.fr/page_ecolier.htm"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#000000;">Source: </span></a><a href="http://eduscol.education.fr/cid72979/polices-de-caracteres-cursives-pour-l-enseignement-de-l-ecriture.html"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://eduscol.education.fr/cid72979/polices-de-caracteres-cursives-pour-l-enseignement-de-l-ecriture.html</span></a></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">GeTypo Libre</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Creative Commons BY-NC-ND</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.ge.ch/sem/cc/by-nc-nd/"><span style=" font-family:'Lucida Grande'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://www.ge.ch/sem/cc/by-nc-nd/</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">© 2005-2015, Vista Multimedia SA, Droit de diffusion Etat de Genève - DIP</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://edu.ge.ch/sem/node/1294"><span style=" font-family:'Lucida Grande'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://edu.ge.ch/sem/node/1294</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">GeTypo Libre</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Creative Commons BY-NC-ND</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.ge.ch/sem/cc/by-nc-nd/"><span style=" font-family:'Lucida Grande'; text-decoration: underline; color:#0000ff;">http://www.ge.ch/sem/cc/by-nc-nd/</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">© 2005-2015, Vista Multimedia SA, Droit de diffusion Etat de Genève - DIP</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://edu.ge.ch/sem/node/1294"><span style=" font-family:'Lucida Grande'; text-decoration: underline; color:#0000ff;">http://edu.ge.ch/sem/node/1294</span></a></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">GraphMe Widget 2.1</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Yannick Vessaz</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">GraphMe Widget 2.1</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Yannick Vessaz</span></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Papier.wgt 2.5.4</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Developed by F. Le Cléac’h </span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Papier.wgt 2.5.4</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Developed by F. Le Cléac’h </span></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/"><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)</span></a></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://www.openedu.fr"><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">https://www.openedu.fr</span></a></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">QR-Code Widget</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Basilstotz</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Licence: CCO</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">QR-Code Widget</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Basilstotz</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Licence: CCO</span></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; color:#000000;">Sonata para piano (.mp3)</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt; color:#000000;">Óscar G. Villegas</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/es"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">Creative Commons Attribution-NonCommercial-Share Alike 3.0 Unported</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://recursostic.educacion.es/bancoimagenes/web/"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://recursostic.educacion.es/bancoimagenes/web/</span></a><span style=" font-family:'Cantarell'; font-size:10pt;"><br /></span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; color:#000000;">Sonata para piano (.mp3)</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; color:#000000;">Óscar G. Villegas</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/es"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">Creative Commons Attribution-NonCommercial-Share Alike 3.0 Unported</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://recursostic.educacion.es/bancoimagenes/web/"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://recursostic.educacion.es/bancoimagenes/web/</span></a><span style=" font-family:'Cantarell';"><br /></span></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">wannaworktogether (.mp4)</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Creative Commons</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by/2.5/"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">Creative Commons Attribution</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/videos/wanna-work-together"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://creativecommons.org/videos/wanna-work-together</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;"><br /></span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Worldmap_wdb_combined (.svg)</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">David Eccles (gringer)</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by-sa/3.0/deed.en"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">Creative Commons Attribution-Share Alike 3.0 Unported</span></a></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://commons.wikimedia.org/wiki/File:Worldmap_wdb_combined.svg"><span style=" font-family:'Cantarell'; font-size:10pt; text-decoration: underline; color:#0000ff;">http://commons.wikimedia.org/wiki/File:Worldmap_wdb_combined.svg</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">wannaworktogether (.mp4)</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Creative Commons</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by/2.5/"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">Creative Commons Attribution</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/videos/wanna-work-together"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://creativecommons.org/videos/wanna-work-together</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';"><br /></span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Worldmap_wdb_combined (.svg)</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">David Eccles (gringer)</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://creativecommons.org/licenses/by-sa/3.0/deed.en"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">Creative Commons Attribution-Share Alike 3.0 Unported</span></a></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://commons.wikimedia.org/wiki/File:Worldmap_wdb_combined.svg"><span style=" font-family:'Cantarell'; text-decoration: underline; color:#0000ff;">http://commons.wikimedia.org/wiki/File:Worldmap_wdb_combined.svg</span></a></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p></body></html>
@@ -3219,23 +3433,23 @@ hr { height: 1px; border-width: 0; }
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
-</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Noto Sans',''; font-size:10pt; font-weight:400; font-style:normal;">
<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;">
<tr>
<td style="border: none;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">OpenBoard is copyright © 2022. All rights reserved.</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Cantarell'; font-size:10pt;"><br /></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">OpenBoard is derived from Open-Sankoré. Open-Sankoré is copyright © 2010-2015 Groupement d'Intérêt Public pour l'Education Numérique en Afrique (GIP ENA). All right reserved.</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Cantarell'; font-size:10pt;"><br /></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">OpenBoard 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). You can find the source code of this software at </span><a href="https://github.com/DIP-SEM/OpenBoard"><span style=" font-family:'.Helvetica Neue DeskInterface'; font-size:10pt; text-decoration: underline; color:#0000ff;">github.com/OpenBoard-org</span></a><span style=" font-family:'Cantarell'; font-size:10pt;">. </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">OpenBoard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License below for more details.</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Cantarell'; font-size:10pt;"><br /></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Contact :</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Service écoles-médias</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Rue des Gazomètres 5</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Case Postale 241</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">1211 Genève 8</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Switzerland</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">OpenBoard is copyright © 2022. All rights reserved.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Cantarell';"><br /></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">OpenBoard is derived from Open-Sankoré. Open-Sankoré is copyright © 2010-2015 Groupement d'Intérêt Public pour l'Education Numérique en Afrique (GIP ENA). All right reserved.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Cantarell';"><br /></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">OpenBoard 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). You can find the source code of this software at </span><a href="https://github.com/DIP-SEM/OpenBoard"><span style=" font-family:'.Helvetica Neue DeskInterface'; text-decoration: underline; color:#0000ff;">github.com/OpenBoard-org</span></a><span style=" font-family:'Cantarell';">. </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">OpenBoard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License below for more details.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Cantarell';"><br /></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Contact :</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Service écoles-médias</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Rue des Gazomètres 5</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Case Postale 241</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">1211 Genève 8</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell';">Switzerland</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.openboard.ch"><span style=" font-family:'.Helvetica Neue DeskInterface'; font-size:11pt; text-decoration: underline; color:#0000ff;">openboard.ch</span></a></p></td></tr></table></body></html>
@@ -3299,6 +3513,17 @@ hr { height: 1px; border-width: 0; }
QLineEdit
core/UBPreferencesController.h
+
+ UBPreferredBackgroundWidget
+ QWidget
+ gui/UBPreferredBackgroundWidget.h
+
+
+ UBScreenLayoutPreview
+ QWidget
+ core/UBPreferencesController.h
+ 1
+
useExternalBrowserCheckBox
diff --git a/resources/i18n/OpenBoard_de.ts b/resources/i18n/OpenBoard_de.ts
index 2eb616221..e6f43f5e5 100644
--- a/resources/i18n/OpenBoard_de.ts
+++ b/resources/i18n/OpenBoard_de.ts
@@ -3007,6 +3007,28 @@ Möchten Sie diese Fehler für diesen Computer ignorieren?
Use all available displays
Alle verfügbaren Bildschirme nutzen
+
+ Key sequence already in use
+ Tastenkombination wird bereits benutzt
+
+
+ Mouse button already in use
+ Maustaste wird bereits benutzt
+
+
+ Stylus button already in use
+ Stifttaste wird bereits benutzt
+
+
+ Accept
+ preferencesDialog
+ Übernehmen
+
+
+ Record
+ preferencesDialog
+ Aufnehmen
+
UBSettings
@@ -3078,7 +3100,7 @@ Möchten Sie diese Fehler für diesen Computer ignorieren?
Reset zoom factor
- Zoom zurücksetzen
+ Zoom-Faktor zurücksetzen
@@ -3128,7 +3150,7 @@ Möchten Sie diese Fehler für diesen Computer ignorieren?
Command
- Kommando
+ Befehl
@@ -3143,12 +3165,12 @@ Möchten Sie diese Fehler für diesen Computer ignorieren?
Mouse Button
- Mausknopf
+ Maustaste
Tablet Button
- Tablet Stiftknopf
+ Stifttaste
@@ -4074,6 +4096,46 @@ p, li { white-space: pre-wrap; }
List of screens used for Control, Display and Previous pages
Liste der Bildschirme, die für die Hauptansicht, Erweiterte Ansicht und Vorherige Seiten verwendet werden
+
+ Shortcut
+ Kurzbefehl
+
+
+ Filter
+ Filter
+
+
+ Active keyboard shortcuts without pressing Ctrl key
+ Aktiviere Kurzbefehle auch ohne Strg Taste
+
+
+ Shortcuts
+ Kurzbefehle
+
+
+ Abort
+ Abbrechen
+
+
+ Record
+ Aufnehmen
+
+
+ Stylus Button
+ Stifttaste
+
+
+ Mouse Button
+ Maustaste
+
+
+ Reset
+ Zurücksetzen
+
+
+ Key Sequence
+ Tasten
+
trapFlashDialog
diff --git a/resources/i18n/OpenBoard_it.ts b/resources/i18n/OpenBoard_it.ts
index 62dd8ac8f..04c1ff796 100644
--- a/resources/i18n/OpenBoard_it.ts
+++ b/resources/i18n/OpenBoard_it.ts
@@ -44,9 +44,9 @@
If you wish so, you may continue with an unverified certificate. Accepting an unverified certificate mean you may not be connected with the host you tried to connect to.
Do you wish to override the security check and continue ?
- Se vuoi, puoi prosseguire con un certificato non attestato. Accettare un certificato non attestato implica che potresti non essere connesso all'host al quale cerchi di accedere.
+ Se vuoi, puoi proseguire con un certificato non verificato. Accettare un certificato non verificato implica che potresti non essere connesso all'host al quale cerchi di accedere.
- Vuoi comunque prosseguire ?
+ Vuoi comunque proseguire ?
@@ -64,7 +64,7 @@ Do you wish to override the security check and continue ?
Save as
- Salvaguardare sotto
+ Salva come
@@ -84,22 +84,22 @@ Do you wish to override the security check and continue ?
%L1 B
- %L1 o
+ %L1 B
%L1 KiB
- %L1 ko
+ %L1 KiB
%L1 MiB
- %L1 Mo
+ %L1 MiB
%L1 GiB
- %L1 Go
+ %L1 GiB
@@ -119,7 +119,7 @@ Do you wish to override the security check and continue ?
cancelled - %1 downloaded - %2/s
- Anullato - %1 downloaded - %2/s
+ Annullato - %1 downloaded - %2/s
@@ -134,7 +134,7 @@ Do you wish to override the security check and continue ?
Remove from list
- Ritirare dalla lista
+ Rimuovere dalla lista
@@ -1790,12 +1790,12 @@ Do you wish to override the security check and continue ?
Complete deletion of %1 documents/folders
- Cancellazione definitiva des %1 documenti/folders
+ Cancellazione definitiva dei %1 documenti/folders
You are about to permanantly delete %1 documents and/or folders. Are you sure ?
- Stai per cancellare definitivamente %1 documenti et/o folders. Sei sicuro ?
+ Stai per cancellare definitivamente %1 documenti e/o folders. Sei sicuro ?
@@ -2120,7 +2120,7 @@ Dando un nuovo nome si creerà un nuovo documento.
Warnings during export was appeared
- È apparso un avviso durante l'esportazione
+ Sono apparsi avvisi durante l'esportazione
@@ -2504,12 +2504,12 @@ Dando un nuovo nome si creerà un nuovo documento.
Layer up
- stratificare
+ Strato verso l'alto
Layer down
- strato verso il basso
+ Strato verso il basso
@@ -3034,7 +3034,7 @@ Vuoi ignorare gli errori per questo host?
Background
- Fondi
+ Sfondi
@@ -3099,17 +3099,17 @@ Vuoi ignorare gli errori per questo host?
Scroll page up
- Scorri verso l'alto
+ Scorri la pagina verso l'alto
Scroll down
- Scorrere verso il basso
+ Scorri verso il basso
Scroll page down
- Scorrere verso il basso
+ Scorri la pagina verso il basso
@@ -3129,7 +3129,7 @@ Vuoi ignorare gli errori per questo host?
Key Sequence
- Sequenza di tastiera
+ Sequenza di tasti
@@ -3175,7 +3175,7 @@ Vuoi ignorare gli errori per questo host?
Task
MouseButton
- Macchia
+ Compito
@@ -3224,7 +3224,7 @@ Vuoi ignorare gli errori per questo host?
Generating preview thumbnails ...
- Generazione della miniatura di anteprima in corso...
+ Generazione delle miniature di anteprima in corso...
@@ -3366,7 +3366,7 @@ Si prega di riavviare l'applicazione per accedere ai documenti aggiornati.<
Open Web Inspector
- Aprier l’ispettore Web
+ Aprire l’ispettore Web
@@ -3470,7 +3470,7 @@ Si prega di riavviare l'applicazione per accedere ai documenti aggiornati.<
Bottom layer limit reached
- Limite del livello inferiore raggiunto
+ Raggiunto il limite inferiore degli strati
@@ -3520,48 +3520,48 @@ Si prega di riavviare l'applicazione per accedere ai documenti aggiornati.<
Enter username and password for "%1" at %2
- Entra l’utente e la password per «%1» a %2
+ Inserisci l’utente e la password per «%1» a %2
Allow %1 to access your location information?
- Autorizzare %1 ad accedere alla tua posizione ?
+ Autorizza %1 ad accedere alla tua posizione ?
Allow %1 to access your microphone?
- Autorizzare %1 ad accedere al tuo microfono ?
+ Autorizza %1 ad accedere al tuo microfono ?
Allow %1 to access your webcam?
- Autorizzare %1 ad accedere alla tua webcam ?
+ Autorizza %1 ad accedere alla tua webcam ?
Allow %1 to access your microphone and webcam?
- Autorizzare %1 ad accedere al tuo microfono ed alla tua webcam ?
+ Autorizza %1 ad accedere al tuo microfono ed alla tua webcam ?
Allow %1 to lock your mouse cursor?
- Autorizzare %1 a bloccare il cursore della tua mouse ?
+ Autorizza %1 a bloccare il cursore del tuo mouse ?
Allow %1 to capture video of your desktop?
- Autorizzare %1 a fare una cattura video del tuo desktop ?
+ Autorizza %1 a catturare un video del tuo desktop ?
Allow %1 to capture audio and video of your desktop?
- Autorizzare %1 a fare una cattura audio e video del tuo desktop ?
+ Autorizza %1 a catturare audio e video del tuo desktop ?
Permission Request
- Chiedere l’autorizzazione
+ Richiesta di autorizzazione
@@ -3579,22 +3579,22 @@ Si prega di riavviare l'applicazione per accedere ai documenti aggiornati.<
Render process normal exit
- Uscita normale del procedimento resa
+ Uscita normale del procedimento di rendering
Render process abnormal exit
- Uscita anomala del procedimento di resa
+ Uscita anomala del procedimento di rendering
Render process crashed
- Il procedimento di resa ha subito un crash
+ Il procedimento di rendering ha subito un crash
Render process killed
- Il procedimento di resa si è fermato
+ Procedimento di rendering interrotto
@@ -4062,7 +4062,7 @@ p, li { white-space: pre-wrap; }
List of screens used for Control, Display and Previous pages
- Lista degli schermi utilizzati per le visualizzazioni Principale, Esteso ePpagine precedenti
+ Lista degli schermi utilizzati per le visualizzazioni Principale, Esteso e Pagine precedenti
diff --git a/resources/images/backgroundPalette/background1.svg b/resources/images/backgroundPalette/background1.svg
deleted file mode 100644
index 468c39377..000000000
--- a/resources/images/backgroundPalette/background1.svg
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/background1On.svg b/resources/images/backgroundPalette/background1On.svg
deleted file mode 100644
index 83d52f55c..000000000
--- a/resources/images/backgroundPalette/background1On.svg
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/background2.svg b/resources/images/backgroundPalette/background2.svg
deleted file mode 100644
index 1023164cd..000000000
--- a/resources/images/backgroundPalette/background2.svg
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/background2On.svg b/resources/images/backgroundPalette/background2On.svg
deleted file mode 100644
index 75c81a8f4..000000000
--- a/resources/images/backgroundPalette/background2On.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/background3.svg b/resources/images/backgroundPalette/background3.svg
deleted file mode 100644
index 7198b419a..000000000
--- a/resources/images/backgroundPalette/background3.svg
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/background3On.svg b/resources/images/backgroundPalette/background3On.svg
deleted file mode 100644
index 26ebcd0b2..000000000
--- a/resources/images/backgroundPalette/background3On.svg
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/background4.svg b/resources/images/backgroundPalette/background4.svg
deleted file mode 100644
index 053ebf054..000000000
--- a/resources/images/backgroundPalette/background4.svg
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-image/svg+xml
\ No newline at end of file
diff --git a/resources/images/backgroundPalette/background4On.svg b/resources/images/backgroundPalette/background4On.svg
deleted file mode 100644
index 2513743cf..000000000
--- a/resources/images/backgroundPalette/background4On.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/background5.svg b/resources/images/backgroundPalette/background5.svg
deleted file mode 100644
index ac6e870e1..000000000
--- a/resources/images/backgroundPalette/background5.svg
+++ /dev/null
@@ -1,146 +0,0 @@
-
-
-
-image/svg+xml
\ No newline at end of file
diff --git a/resources/images/backgroundPalette/background5On.svg b/resources/images/backgroundPalette/background5On.svg
deleted file mode 100644
index 25d0a1c3c..000000000
--- a/resources/images/backgroundPalette/background5On.svg
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-image/svg+xml
\ No newline at end of file
diff --git a/resources/images/backgroundPalette/background6.svg b/resources/images/backgroundPalette/background6.svg
deleted file mode 100644
index 1c38545bb..000000000
--- a/resources/images/backgroundPalette/background6.svg
+++ /dev/null
@@ -1,146 +0,0 @@
-
-
-
-image/svg+xml
\ No newline at end of file
diff --git a/resources/images/backgroundPalette/background6On.svg b/resources/images/backgroundPalette/background6On.svg
deleted file mode 100644
index 1210a2516..000000000
--- a/resources/images/backgroundPalette/background6On.svg
+++ /dev/null
@@ -1,150 +0,0 @@
-
-
-
-image/svg+xml
\ No newline at end of file
diff --git a/resources/images/backgroundPalette/background7.svg b/resources/images/backgroundPalette/background7.svg
deleted file mode 100644
index bf960aaed..000000000
--- a/resources/images/backgroundPalette/background7.svg
+++ /dev/null
@@ -1,177 +0,0 @@
-
-
-
-image/svg+xml
diff --git a/resources/images/backgroundPalette/background7On.svg b/resources/images/backgroundPalette/background7On.svg
deleted file mode 100644
index a1c67bbf6..000000000
--- a/resources/images/backgroundPalette/background7On.svg
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-
-image/svg+xml
diff --git a/resources/images/backgroundPalette/background8.svg b/resources/images/backgroundPalette/background8.svg
deleted file mode 100644
index ad06d61b4..000000000
--- a/resources/images/backgroundPalette/background8.svg
+++ /dev/null
@@ -1,177 +0,0 @@
-
-
-
-image/svg+xml
diff --git a/resources/images/backgroundPalette/background8On.svg b/resources/images/backgroundPalette/background8On.svg
deleted file mode 100644
index d622b6433..000000000
--- a/resources/images/backgroundPalette/background8On.svg
+++ /dev/null
@@ -1,220 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-image/svg+xml
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/images/backgroundPalette/bgButtonTemplateDarkOff.svg b/resources/images/backgroundPalette/bgButtonTemplateDarkOff.svg
new file mode 100644
index 000000000..df2389127
--- /dev/null
+++ b/resources/images/backgroundPalette/bgButtonTemplateDarkOff.svg
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/images/backgroundPalette/bgButtonTemplateDarkOn.svg b/resources/images/backgroundPalette/bgButtonTemplateDarkOn.svg
new file mode 100644
index 000000000..ede9a1f6d
--- /dev/null
+++ b/resources/images/backgroundPalette/bgButtonTemplateDarkOn.svg
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/images/backgroundPalette/bgButtonTemplateLightOff.svg b/resources/images/backgroundPalette/bgButtonTemplateLightOff.svg
new file mode 100644
index 000000000..c8282c6a5
--- /dev/null
+++ b/resources/images/backgroundPalette/bgButtonTemplateLightOff.svg
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/images/backgroundPalette/bgButtonTemplateLightOn.svg b/resources/images/backgroundPalette/bgButtonTemplateLightOn.svg
new file mode 100644
index 000000000..971f280c8
--- /dev/null
+++ b/resources/images/backgroundPalette/bgButtonTemplateLightOn.svg
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/images/close-no-bg.png b/resources/images/close-no-bg.png
new file mode 100644
index 000000000..949b5900c
Binary files /dev/null and b/resources/images/close-no-bg.png differ
diff --git a/resources/images/darkMode.svg b/resources/images/darkMode.svg
new file mode 100644
index 000000000..9e8caa180
--- /dev/null
+++ b/resources/images/darkMode.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/images/down_arrow.png b/resources/images/down_arrow.png
deleted file mode 100644
index a51817681..000000000
Binary files a/resources/images/down_arrow.png and /dev/null differ
diff --git a/resources/images/down_arrow.svg b/resources/images/down_arrow.svg
new file mode 100644
index 000000000..f3c9dd5fc
--- /dev/null
+++ b/resources/images/down_arrow.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/resources/images/left_arrow.png b/resources/images/left_arrow.png
deleted file mode 100644
index 53e58f205..000000000
Binary files a/resources/images/left_arrow.png and /dev/null differ
diff --git a/resources/images/left_arrow.svg b/resources/images/left_arrow.svg
new file mode 100644
index 000000000..c7d64d1d0
--- /dev/null
+++ b/resources/images/left_arrow.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/resources/images/lightMode.svg b/resources/images/lightMode.svg
new file mode 100644
index 000000000..6d6e7992e
--- /dev/null
+++ b/resources/images/lightMode.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/images/right_arrow.png b/resources/images/right_arrow.png
deleted file mode 100644
index e9a64d2da..000000000
Binary files a/resources/images/right_arrow.png and /dev/null differ
diff --git a/resources/images/right_arrow.svg b/resources/images/right_arrow.svg
new file mode 100644
index 000000000..eacb2d0f2
--- /dev/null
+++ b/resources/images/right_arrow.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/resources/images/up_arrow.png b/resources/images/up_arrow.png
deleted file mode 100644
index 10aa5ab3b..000000000
Binary files a/resources/images/up_arrow.png and /dev/null differ
diff --git a/resources/images/up_arrow.svg b/resources/images/up_arrow.svg
new file mode 100644
index 000000000..3bc4a5ca4
--- /dev/null
+++ b/resources/images/up_arrow.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/resources/lightTheme.qss b/resources/lightTheme.qss
new file mode 100644
index 000000000..dd81d453d
--- /dev/null
+++ b/resources/lightTheme.qss
@@ -0,0 +1,971 @@
+/*
+ * OpenBoard Light Theme
+ */
+
+QWidget {
+ background-color: #edf2f7;
+ color: #1f2937;
+}
+
+QMainWindow,
+QDialog,
+QMessageBox,
+QMenuBar,
+QStatusBar,
+QToolBar,
+QDockWidget::title {
+ background-color: #edf2f7;
+ color: #1f2937;
+}
+
+QScrollArea,
+QAbstractScrollArea,
+QListView,
+QTreeView,
+QTableView {
+ background-color: #ffffff;
+ color: #1f2937;
+}
+
+QLineEdit,
+QTextEdit,
+QPlainTextEdit,
+QComboBox,
+QSpinBox,
+QDoubleSpinBox {
+ background-color: #ffffff;
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ border-radius: 6px;
+ padding: 4px 10px;
+ selection-background-color: #eaf4ff;
+ selection-color: #1f2937;
+}
+
+QLineEdit:hover,
+QTextEdit:hover,
+QPlainTextEdit:hover,
+QComboBox:hover,
+QSpinBox:hover,
+QDoubleSpinBox:hover {
+ border: 1px solid #c7d3df;
+}
+
+QLineEdit:focus,
+QTextEdit:focus,
+QPlainTextEdit:focus,
+QComboBox:focus,
+QSpinBox:focus,
+QDoubleSpinBox:focus {
+ border: 1px solid #3d8fd1;
+ background-color: #ffffff;
+}
+
+QSpinBox::up-button,
+QDoubleSpinBox::up-button,
+QSpinBox::down-button,
+QDoubleSpinBox::down-button {
+ background-color: #f7f9fc;
+ border-left: 1px solid #d9e0e8;
+ width: 18px;
+}
+
+QSpinBox::up-button,
+QDoubleSpinBox::up-button {
+ border-top-right-radius: 6px;
+}
+
+QSpinBox::down-button,
+QDoubleSpinBox::down-button {
+ border-bottom-right-radius: 6px;
+}
+
+QSpinBox::up-button:hover,
+QDoubleSpinBox::up-button:hover,
+QSpinBox::down-button:hover,
+QDoubleSpinBox::down-button:hover {
+ background-color: #eef6ff;
+}
+
+QSpinBox::up-arrow,
+QDoubleSpinBox::up-arrow {
+ image: url(:/images/up_arrow.svg);
+ width: 10px;
+ height: 10px;
+}
+
+QSpinBox::down-arrow,
+QDoubleSpinBox::down-arrow {
+ image: url(:/images/down_arrow.svg);
+ width: 10px;
+ height: 10px;
+}
+
+QComboBox::drop-down {
+ border: none;
+ width: 24px;
+}
+
+QComboBox::down-arrow {
+ image: url(:/images/down_arrow.svg);
+ width: 12px;
+ height: 12px;
+}
+
+QComboBox QAbstractItemView {
+ background-color: #ffffff;
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ selection-background-color: #eaf4ff;
+ selection-color: #1f2937;
+ outline: none;
+}
+
+QPushButton {
+ background-color: #f7f9fc;
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ border-radius: 6px;
+ padding: 6px 16px;
+ min-height: 20px;
+}
+
+QPushButton:hover {
+ background-color: #eef6ff;
+ color: #1f2937;
+ border: 1px solid #d3e4f6;
+}
+
+QPushButton:pressed {
+ background-color: #3d8fd1;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QPushButton:checked,
+QPushButton:default {
+ background-color: #3d8fd1;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QPushButton:disabled {
+ background-color: #eef2f7;
+ color: #94a3b8;
+ border: 1px solid #e2e8f0;
+}
+
+QToolButton {
+ background-color: transparent;
+ color: #1f2937;
+ border: 1px solid transparent;
+ border-radius: 6px;
+ padding: 5px;
+ margin: 2px;
+}
+
+QToolButton:hover {
+ background-color: #eef6ff;
+ color: #1f2937;
+ border: 1px solid #d3e4f6;
+}
+
+QToolButton:pressed,
+QToolButton:checked {
+ background-color: #3d8fd1;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QDialog#preferencesDialog QPushButton#closeButton,
+QDialog#preferencesDialog QPushButton#closeButton:hover,
+QDialog#preferencesDialog QPushButton#closeButton:pressed,
+QDialog#preferencesDialog QPushButton#closeButton:default {
+ color: #ffffff;
+}
+
+QDialog#preferencesDialog {
+ background-color: #f2f6fa;
+}
+
+QDialog#preferencesDialog QTabWidget::pane,
+QDialog#preferencesDialog QFrame#frame,
+QDialog#preferencesDialog QFrame#gridFrame {
+ background-color: #f2f6fa;
+}
+
+QDialog#preferencesDialog QScrollArea,
+QDialog#preferencesDialog QAbstractScrollArea,
+QDialog#preferencesDialog QWidget#scrollAreaWidgetContents,
+QDialog#preferencesDialog QWidget#scrollAreaWidgetContents_2 {
+ background-color: #edf2f7;
+}
+
+QDialog#preferencesDialog QTabBar::tab:selected {
+ background-color: #f2f6fa;
+ border-bottom-color: #f2f6fa;
+}
+
+QDialog#preferencesDialog QGroupBox,
+QDialog#preferencesDialog QGroupBox::title {
+ background-color: #edf2f7;
+}
+
+#UBPageNavigationWidget {
+ background-color: #edf2f7;
+}
+
+#UBMessageWindow {
+ color: #1f2937;
+}
+
+#UBMessageWindow QLabel#UBMessageWindowLabel {
+ background: transparent;
+ border: none;
+ color: #0f172a;
+ font-size: 15px;
+ font-weight: 600;
+ padding: 0px 2px 0px 0px;
+}
+
+#UBMessageWindow UBSpinningWheel#UBMessageWindowSpinner {
+ background: transparent;
+ color: #3d8fd1;
+}
+
+QToolButton#ubButtonGroupLeft,
+QToolButton#ubButtonGroupCenter,
+QToolButton#ubButtonGroupRight,
+QToolButton#desktop-ubButtonGroupLeft,
+QToolButton#desktop-ubButtonGroupCenter,
+QToolButton#desktop-ubButtonGroupRight {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #fdfefe, stop: 1 #e7edf4);
+ color: #1f2937;
+ border-radius: 0px;
+ border-top: 1px solid #d9e0e8;
+ border-bottom: 1px solid #d9e0e8;
+ border-left: none;
+ border-right: none;
+}
+
+QToolButton#ubButtonGroupLeft,
+QToolButton#desktop-ubButtonGroupLeft {
+ border-left: 1px solid #d9e0e8;
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+
+QToolButton#ubButtonGroupRight,
+QToolButton#desktop-ubButtonGroupRight {
+ border-right: 1px solid #d9e0e8;
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+
+QToolButton#ubButtonGroupLeft:hover,
+QToolButton#ubButtonGroupCenter:hover,
+QToolButton#ubButtonGroupRight:hover,
+QToolButton#desktop-ubButtonGroupLeft:hover,
+QToolButton#desktop-ubButtonGroupCenter:hover,
+QToolButton#desktop-ubButtonGroupRight:hover {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #f4f9ff, stop: 1 #dcebf9);
+ color: #1f2937;
+ border-top-color: #c6d9ec;
+ border-bottom-color: #c6d9ec;
+}
+
+QToolButton#ubButtonGroupLeft:pressed,
+QToolButton#ubButtonGroupCenter:pressed,
+QToolButton#ubButtonGroupRight:pressed,
+QToolButton#desktop-ubButtonGroupLeft:pressed,
+QToolButton#desktop-ubButtonGroupCenter:pressed,
+QToolButton#desktop-ubButtonGroupRight:pressed {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #4c9bdb, stop: 1 #2a82da);
+ color: #ffffff;
+ border-top: 1px solid #2a82da;
+ border-bottom: 1px solid #2a82da;
+ border-left: 1px solid #2a82da;
+ border-right: 1px solid #2a82da;
+}
+
+QToolButton#ubButtonGroupLeft:checked,
+QToolButton#ubButtonGroupCenter:checked,
+QToolButton#ubButtonGroupRight:checked,
+QToolButton#desktop-ubButtonGroupLeft:checked,
+QToolButton#desktop-ubButtonGroupCenter:checked,
+QToolButton#desktop-ubButtonGroupRight:checked {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5aa5e0, stop: 1 #3d8fd1);
+ color: #ffffff;
+ border-top: 1px solid #2a82da;
+ border-bottom: 1px solid #2a82da;
+ border-left: 1px solid #2a82da;
+ border-right: 1px solid #2a82da;
+}
+
+QToolButton#ubButtonGroupRight[colorPaletteConfigButton="true"],
+QToolButton#desktop-ubButtonGroupRight[colorPaletteConfigButton="true"] {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #e8edf4, stop: 1 #cfd8e3);
+ color: #334155;
+ border-top: 1px solid #bcc8d5;
+ border-bottom: 1px solid #bcc8d5;
+ border-left: 1px solid #bcc8d5;
+ border-right: 1px solid #bcc8d5;
+}
+
+QToolButton#ubButtonGroupRight[colorPaletteConfigButton="true"]:hover,
+QToolButton#desktop-ubButtonGroupRight[colorPaletteConfigButton="true"]:hover {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #dee6ef, stop: 1 #c4d0dc);
+ color: #1e293b;
+}
+
+QToolButton#ubButtonGroupRight[colorPaletteConfigButton="true"]:pressed,
+QToolButton#desktop-ubButtonGroupRight[colorPaletteConfigButton="true"]:pressed {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d1dae5, stop: 1 #b4c1d0);
+ color: #0f172a;
+}
+
+QDialog#colorPreferencesDialog {
+ background-color: #f2f6fa;
+}
+
+QDialog#colorPreferencesDialog QWidget#colorPreferencesHeader {
+ background-color: #edf2f7;
+ border: 1px solid #d9e0e8;
+ border-radius: 10px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesHeaderLabel {
+ color: #0f172a;
+ font-size: 14px;
+ font-weight: 600;
+ background: transparent;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider {
+ min-width: 190px;
+ background: transparent;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider::groove:horizontal {
+ height: 6px;
+ background-color: #d7e1ec;
+ border: none;
+ border-radius: 3px;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider::handle:horizontal {
+ width: 18px;
+ margin: -7px 0;
+ background-color: #3d8fd1;
+ border: 1px solid #2a82da;
+ border-radius: 9px;
+}
+
+QDialog#colorPreferencesDialog QSlider#colorPreferencesPaletteSizeSlider::sub-page:horizontal {
+ background-color: #3d8fd1;
+ border-radius: 3px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesPaletteSizeValue {
+ min-width: 32px;
+ padding: 4px 8px;
+ background: #ffffff;
+ color: #0f172a;
+ border: 1px solid #d9e0e8;
+ border-radius: 6px;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QWidget#colorPreferencesHint {
+ background: #fff8db;
+ border: 1px solid #ead9a2;
+ border-radius: 8px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesHintIcon {
+ background: transparent;
+ min-width: 20px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesHintText {
+ background: transparent;
+ color: #5b4b1f;
+ font-size: 12px;
+ line-height: 1.3em;
+}
+
+QDialog#colorPreferencesDialog QTabWidget#colorPreferencesTabWidget::pane {
+ border: none;
+ background: transparent;
+ top: -1px;
+}
+
+QDialog#colorPreferencesDialog QTabBar::tab,
+QDialog#colorPreferencesDialog QTabBar::tab:top {
+ background: #e2eaf3;
+ color: #475569;
+ border: 1px solid #d9e0e8;
+ border-radius: 6px;
+ padding: 8px 18px;
+ margin-right: 8px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QTabBar::tab:selected {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5aa5e0, stop: 1 #3d8fd1);
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QDialog#colorPreferencesDialog QTabBar::tab:hover:!selected {
+ background: #e8eff7;
+ color: #1e293b;
+}
+
+QDialog#colorPreferencesDialog QWidget#colorPreferencesSection {
+ background: #edf2f7;
+ border: 1px solid #d9e0e8;
+ border-radius: 10px;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesSectionTitle {
+ background: transparent;
+ color: #0f172a;
+ font-size: 13px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame {
+ border-radius: 8px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="light"] {
+ background: #ffffff;
+ border: 1px solid #d9e0e8;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] {
+ background: #131a24;
+ border: 1px solid #475569;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorShortcutLabel {
+ background: transparent;
+ color: #64748b;
+ font-size: 11px;
+ font-weight: 700;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QLabel#colorShortcutLabel {
+ color: #cbd5e1;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton#ubButtonGroupLeft,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton#ubButtonGroupCenter,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton#ubButtonGroupRight {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #fdfefe, stop: 1 #e7edf4);
+ border-top: 1px solid #d9e0e8;
+ border-bottom: 1px solid #d9e0e8;
+ border-left: none;
+ border-right: none;
+ border-radius: 0px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="light"] QToolButton#ubButtonGroupLeft {
+ border-left: 1px solid #d9e0e8;
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="light"] QToolButton#ubButtonGroupRight {
+ border-right: 1px solid #d9e0e8;
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupLeft,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupCenter,
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupRight {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #505050, stop: 1 #3a3a3a);
+ border-top: 1px solid #435066;
+ border-bottom: 1px solid #435066;
+ color: #ffffff;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupLeft {
+ border-left: 1px solid #435066;
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton#ubButtonGroupRight {
+ border-right: 1px solid #435066;
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame QToolButton:hover {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #f4f9ff, stop: 1 #dcebf9);
+ border-top-color: #c6d9ec;
+ border-bottom-color: #c6d9ec;
+}
+
+QDialog#colorPreferencesDialog QFrame#colorPreviewFrame[previewMode="dark"] QToolButton:hover {
+ background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #606060, stop: 1 #4a4a4a);
+ border-top-color: #64748b;
+ border-bottom-color: #64748b;
+}
+
+QDialog#colorPreferencesDialog QLabel#colorPreferencesOpacityValue {
+ color: #0f172a;
+ font-size: 13px;
+ font-weight: 700;
+ background: transparent;
+}
+
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton {
+ padding: 7px 14px;
+ background: #f7f9fc;
+ color: #334155;
+ border: 1px solid #d9e0e8;
+ border-radius: 6px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton:hover {
+ background: #eef6ff;
+ border: 1px solid #d3e4f6;
+}
+
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton:focus,
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton:pressed,
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton:checked,
+QDialog#colorPreferencesDialog QPushButton#colorPreferencesResetButton:default {
+ background: #3d8fd1;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QDialog#colorPreferencesDialog QDialogButtonBox#colorPreferencesButtonBox QPushButton {
+ min-width: 92px;
+ padding: 8px 18px;
+ border-radius: 6px;
+ font-weight: 600;
+}
+
+QDialog#colorPreferencesDialog QDialogButtonBox#colorPreferencesButtonBox QPushButton:focus,
+QDialog#colorPreferencesDialog QDialogButtonBox#colorPreferencesButtonBox QPushButton:pressed,
+QDialog#colorPreferencesDialog QDialogButtonBox#colorPreferencesButtonBox QPushButton:checked,
+QDialog#colorPreferencesDialog QDialogButtonBox#colorPreferencesButtonBox QPushButton:default {
+ background-color: #3d8fd1;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QCheckBox,
+QRadioButton {
+ color: #1f2937;
+ spacing: 6px;
+}
+
+QCheckBox::indicator,
+QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border: 1px solid #c7d3df;
+ border-radius: 4px;
+ background-color: #ffffff;
+}
+
+QCheckBox::indicator:hover,
+QRadioButton::indicator:hover {
+ border: 1px solid #3d8fd1;
+ background-color: #eef6ff;
+}
+
+QCheckBox::indicator:checked,
+QRadioButton::indicator:checked {
+ background-color: #3d8fd1;
+ border: 1px solid #2a82da;
+}
+
+QRadioButton::indicator {
+ border-radius: 8px;
+}
+
+QSlider::groove:horizontal,
+QSlider::groove:vertical {
+ background-color: #e2e8f0;
+ border: 1px solid #d3dce6;
+ border-radius: 4px;
+}
+
+QSlider::groove:horizontal {
+ height: 8px;
+}
+
+QSlider::groove:vertical {
+ width: 8px;
+}
+
+QSlider::handle:horizontal,
+QSlider::handle:vertical {
+ background-color: #3d8fd1;
+ border: 1px solid #2a82da;
+ border-radius: 6px;
+}
+
+QSlider::handle:horizontal {
+ width: 16px;
+ margin: -5px 0;
+}
+
+QSlider::handle:vertical {
+ height: 16px;
+ margin: 0 -5px;
+}
+
+QScrollBar:vertical {
+ background: transparent;
+ width: 12px;
+ margin: 8px 4px 8px 0px;
+}
+
+QScrollBar:horizontal {
+ background: transparent;
+ height: 12px;
+ margin: 0px 8px 4px 8px;
+}
+
+QScrollBar::handle:vertical,
+QScrollBar::handle:horizontal {
+ background: #cdd7e3;
+ border: 1px solid #c0ccd8;
+ border-radius: 4px;
+}
+
+QScrollBar::handle:vertical:!hover,
+QScrollBar::handle:horizontal:!hover {
+ background: #cdd7e3;
+ border: 1px solid #c0ccd8;
+}
+
+QScrollBar::handle:vertical {
+ min-height: 20px;
+}
+
+QScrollBar::handle:horizontal {
+ min-width: 20px;
+}
+
+QScrollBar::handle:vertical:hover,
+QScrollBar::handle:horizontal:hover {
+ background: #5aa5e0;
+ border: 1px solid #2a82da;
+}
+
+QScrollBar::handle:vertical:pressed,
+QScrollBar::handle:horizontal:pressed {
+ background: #2a82da;
+ border: 1px solid #2a82da;
+}
+
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical,
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ background: transparent;
+ border: none;
+ width: 0px;
+ height: 0px;
+}
+
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical,
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ background: transparent;
+}
+
+QTreeView {
+ background-color: #ffffff;
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ alternate-background-color: #fbfcfe;
+ selection-background-color: #eaf4ff;
+ selection-color: #1f2937;
+ show-decoration-selected: 0;
+ outline: none;
+}
+
+QListView,
+QTableView {
+ background-color: #ffffff;
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ alternate-background-color: #fbfcfe;
+ selection-background-color: #eaf4ff;
+ selection-color: #1f2937;
+ show-decoration-selected: 1;
+ outline: none;
+}
+
+QTreeView::item,
+QListView::item,
+QTableView::item {
+ padding: 4px;
+}
+
+QTreeView::item:hover,
+QListView::item:hover,
+QTableView::item:hover {
+ background-color: #f3f8fd;
+}
+
+QTreeView::item:selected,
+QListView::item:selected,
+QTableView::item:selected {
+ background-color: #3d8fd1;
+ color: #ffffff;
+}
+
+QTreeView::item:selected:active,
+QListView::item:selected:active,
+QTableView::item:selected:active {
+ background: #3d8fd1;
+ color: #ffffff;
+ border: none;
+}
+
+QTreeView::branch:selected {
+ background: transparent;
+ color: inherit;
+ border: none;
+}
+
+QTreeView QLineEdit,
+QListView QLineEdit,
+QTableView QLineEdit {
+ padding: 1px 6px;
+}
+
+QMenuBar {
+ border-bottom: 1px solid #e2e8f0;
+}
+
+QMenuBar::item {
+ background-color: transparent;
+ padding: 4px 8px;
+ border-radius: 4px;
+}
+
+QMenuBar::item:selected,
+QMenuBar::item:pressed {
+ background-color: #eef6ff;
+ color: #1f2937;
+}
+
+QMenu {
+ background-color: #ffffff;
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ padding: 6px;
+}
+
+QMenu::item {
+ padding: 6px 30px;
+ border-radius: 4px;
+}
+
+QMenu::item:selected {
+ background-color: #eef6ff;
+ color: #1f2937;
+}
+
+QMenu::separator {
+ height: 1px;
+ background-color: #e2e8f0;
+ margin: 4px 0px;
+}
+
+QToolBar {
+ border: none;
+ spacing: 4px;
+ padding: 6px;
+}
+
+QToolBar QToolButton:pressed,
+QToolBar QToolButton:checked {
+ background-color: #3d8fd1;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QToolButton#ubButtonMenu:pressed,
+QToolButton#ubButtonMenu:checked,
+QToolBar QToolButton#ubButtonMenu:pressed,
+QToolBar QToolButton#ubButtonMenu:checked {
+ background-color: #3d8fd1;
+ color: #ffffff;
+ border: 1px solid #2a82da;
+}
+
+QToolBar::separator {
+ background-color: #d9e0e8;
+ width: 1px;
+ margin: 6px 4px;
+}
+
+QTabWidget::pane {
+ border: 1px solid #d9e0e8;
+ background-color: #ffffff;
+ border-top: none;
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+}
+
+QTabBar::tab {
+ background-color: #eef2f7;
+ color: #667085;
+ border: 1px solid #d9e0e8;
+ padding: 7px 14px;
+ margin-right: 4px;
+ border-top-left-radius: 6px;
+ border-top-right-radius: 6px;
+}
+
+QTabBar::tab:selected {
+ background-color: #ffffff;
+ color: #1f2937;
+ border-bottom-color: #ffffff;
+}
+
+QTabBar::tab:hover:!selected {
+ background-color: #f3f8fd;
+ color: #1f2937;
+}
+
+QHeaderView::section {
+ background-color: #fbfcfe;
+ color: #667085;
+ padding: 6px;
+ border: 1px solid #e2e8f0;
+ font-weight: bold;
+}
+
+QGroupBox {
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ border-radius: 8px;
+ margin-top: 12px;
+ font-weight: bold;
+ padding-top: 10px;
+ background-color: #ffffff;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 6px;
+ color: #667085;
+ background-color: #f5f7fa;
+}
+
+QProgressBar {
+ background-color: #edf2f7;
+ border: 1px solid #d9e0e8;
+ border-radius: 6px;
+ text-align: center;
+ color: #1f2937;
+ height: 18px;
+}
+
+QProgressBar::chunk {
+ background-color: #3d8fd1;
+ border-radius: 5px;
+}
+
+QSplitter::handle {
+ background-color: #e2e8f0;
+}
+
+QSplitter::handle:hover {
+ background-color: #bfdcff;
+}
+
+QToolTip {
+ background-color: #ffffff;
+ color: #1f2937;
+ border: 1px solid #d9e0e8;
+ padding: 6px;
+ border-radius: 3px;
+}
+
+#BackgroundPaletteScrollArea {
+ background-color: #f2f6fa;
+ border: 1px solid #cfd8e3;
+ border-radius: 8px;
+}
+
+#BackgroundPaletteScrollArea QWidget {
+ background-color: #f2f6fa;
+}
+
+#BackgroundPalette {
+ background-color: #f2f6fa;
+ border: 1px solid #cfd8e3;
+ border-radius: 10px;
+}
+
+#AddItemPalette {
+ background-color: #f2f6fa;
+ border: 1px solid #cfd8e3;
+ border-radius: 10px;
+}
+
+#DesktopPropertyPalette {
+ background-color: #f2f6fa;
+ border: 1px solid #cfd8e3;
+ border-radius: 10px;
+}
+
+#UBStartupHintsPalette QCheckBox {
+ background: transparent;
+ color: #1f2937;
+}
+
+#BackgroundPalette QLabel,
+#BackgroundPaletteLabel {
+ color: #1f2937;
+ background: transparent;
+}
+
+#BackgroundPalette QToolButton#closeButton,
+#AddItemPalette QToolButton#closeButton,
+#UBStartupHintsPalette QToolButton#closeButton {
+ background: transparent;
+ border: none;
+ border-radius: 5px;
+ padding: 0px;
+ color: #667085;
+ font-size: 20px;
+ font-weight: bold;
+ min-width: 16px;
+ max-width: 16px;
+ min-height: 16px;
+ max-height: 16px;
+}
+
+#BackgroundPalette QToolButton#closeButton:hover,
+#AddItemPalette QToolButton#closeButton:hover,
+#UBStartupHintsPalette QToolButton#closeButton:hover {
+ background: #eef6ff;
+ color: #1f2937;
+}
+
+#BackgroundPalette QToolButton#closeButton:pressed,
+#AddItemPalette QToolButton#closeButton:pressed,
+#UBStartupHintsPalette QToolButton#closeButton:pressed {
+ background: #dbeeff;
+}
diff --git a/resources/startupHints/assets/common/PicturesCategory.svg b/resources/startupHints/assets/common/PicturesCategory.svg
new file mode 100644
index 000000000..1132cadcb
--- /dev/null
+++ b/resources/startupHints/assets/common/PicturesCategory.svg
@@ -0,0 +1,424 @@
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/assets/common/board.png b/resources/startupHints/assets/common/board.png
new file mode 100644
index 000000000..aca1a036c
Binary files /dev/null and b/resources/startupHints/assets/common/board.png differ
diff --git a/resources/startupHints/assets/common/eraserArrow.svg b/resources/startupHints/assets/common/eraserArrow.svg
index 21e354551..e0a6354ab 100644
--- a/resources/startupHints/assets/common/eraserArrow.svg
+++ b/resources/startupHints/assets/common/eraserArrow.svg
@@ -1,199 +1,199 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/assets/common/favorites.png b/resources/startupHints/assets/common/favorites.png
new file mode 100644
index 000000000..59637b880
Binary files /dev/null and b/resources/startupHints/assets/common/favorites.png differ
diff --git a/resources/startupHints/images/left.png b/resources/startupHints/assets/common/left.png
similarity index 100%
rename from resources/startupHints/images/left.png
rename to resources/startupHints/assets/common/left.png
diff --git a/resources/startupHints/assets/common/markerArrow.svg b/resources/startupHints/assets/common/markerArrow.svg
index 0e2b9ad66..066a9e1b7 100644
--- a/resources/startupHints/assets/common/markerArrow.svg
+++ b/resources/startupHints/assets/common/markerArrow.svg
@@ -1,230 +1,230 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/assets/common/penArrow.svg b/resources/startupHints/assets/common/penArrow.svg
index 0ef25469b..27bc38296 100644
--- a/resources/startupHints/assets/common/penArrow.svg
+++ b/resources/startupHints/assets/common/penArrow.svg
@@ -1,286 +1,286 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/assets/common/record.png b/resources/startupHints/assets/common/record.png
new file mode 100644
index 000000000..f9903256c
Binary files /dev/null and b/resources/startupHints/assets/common/record.png differ
diff --git a/resources/startupHints/images/right.png b/resources/startupHints/assets/common/right.png
similarity index 100%
rename from resources/startupHints/images/right.png
rename to resources/startupHints/assets/common/right.png
diff --git a/resources/startupHints/assets/hint1/openboard-logo.png.bck b/resources/startupHints/assets/hint1/openboard-logo.png.bck
deleted file mode 100644
index fe54ac431..000000000
Binary files a/resources/startupHints/assets/hint1/openboard-logo.png.bck and /dev/null differ
diff --git a/resources/startupHints/assets/hint1/openboard-logo.png b/resources/startupHints/assets/hint1/openboard-main-logo.png
similarity index 100%
rename from resources/startupHints/assets/hint1/openboard-logo.png
rename to resources/startupHints/assets/hint1/openboard-main-logo.png
diff --git a/resources/startupHints/assets/hint1/menu.png b/resources/startupHints/assets/hint1/openboard-menu-icon.png
similarity index 100%
rename from resources/startupHints/assets/hint1/menu.png
rename to resources/startupHints/assets/hint1/openboard-menu-icon.png
diff --git a/resources/startupHints/assets/hint10/application-gif1.gif b/resources/startupHints/assets/hint10/built-in-applications-demo.gif
similarity index 100%
rename from resources/startupHints/assets/hint10/application-gif1.gif
rename to resources/startupHints/assets/hint10/built-in-applications-demo.gif
diff --git a/resources/startupHints/assets/hint11/podcast-gif1.gif b/resources/startupHints/assets/hint11/video-capture-open-tool.gif
similarity index 100%
rename from resources/startupHints/assets/hint11/podcast-gif1.gif
rename to resources/startupHints/assets/hint11/video-capture-open-tool.gif
diff --git a/resources/startupHints/assets/hint11/podcast-gif2.gif b/resources/startupHints/assets/hint11/video-capture-save-to-desktop.gif
similarity index 100%
rename from resources/startupHints/assets/hint11/podcast-gif2.gif
rename to resources/startupHints/assets/hint11/video-capture-save-to-desktop.gif
diff --git a/resources/startupHints/assets/hint11/podcast2.png b/resources/startupHints/assets/hint11/video-recorder-interface.png
similarity index 100%
rename from resources/startupHints/assets/hint11/podcast2.png
rename to resources/startupHints/assets/hint11/video-recorder-interface.png
diff --git a/resources/startupHints/assets/hint12/favorites-add-document.png b/resources/startupHints/assets/hint12/favorites-add-document.png
new file mode 100644
index 000000000..fe65a67a3
Binary files /dev/null and b/resources/startupHints/assets/hint12/favorites-add-document.png differ
diff --git a/resources/startupHints/assets/hint12/favorites2.png b/resources/startupHints/assets/hint12/favorites-library-view.png
similarity index 100%
rename from resources/startupHints/assets/hint12/favorites2.png
rename to resources/startupHints/assets/hint12/favorites-library-view.png
diff --git a/resources/startupHints/assets/hint12/favorites.png b/resources/startupHints/assets/hint12/favorites.png
deleted file mode 100644
index 3a856ad8c..000000000
Binary files a/resources/startupHints/assets/hint12/favorites.png and /dev/null differ
diff --git a/resources/startupHints/assets/hint12/favorites3.png b/resources/startupHints/assets/hint12/recent-documents-view.png
similarity index 100%
rename from resources/startupHints/assets/hint12/favorites3.png
rename to resources/startupHints/assets/hint12/recent-documents-view.png
diff --git a/resources/startupHints/assets/hint2/arrow.png b/resources/startupHints/assets/hint2/board-mode-arrow.png
similarity index 100%
rename from resources/startupHints/assets/hint2/arrow.png
rename to resources/startupHints/assets/hint2/board-mode-arrow.png
diff --git a/resources/startupHints/assets/hint2/bo-gif1.gif b/resources/startupHints/assets/hint2/board-mode-background-change.gif
similarity index 100%
rename from resources/startupHints/assets/hint2/bo-gif1.gif
rename to resources/startupHints/assets/hint2/board-mode-background-change.gif
diff --git a/resources/startupHints/assets/hint2/bo1.png b/resources/startupHints/assets/hint2/board-mode-pen-palette.png
similarity index 100%
rename from resources/startupHints/assets/hint2/bo1.png
rename to resources/startupHints/assets/hint2/board-mode-pen-palette.png
diff --git a/resources/startupHints/assets/hint2/bo9.png b/resources/startupHints/assets/hint2/board-mode-toolbar.png
similarity index 100%
rename from resources/startupHints/assets/hint2/bo9.png
rename to resources/startupHints/assets/hint2/board-mode-toolbar.png
diff --git a/resources/startupHints/assets/hint3/bureau1.png.bck b/resources/startupHints/assets/hint3/bureau1.png.bck
deleted file mode 100644
index d8928d407..000000000
Binary files a/resources/startupHints/assets/hint3/bureau1.png.bck and /dev/null differ
diff --git a/resources/startupHints/assets/hint3/bureau-gif1.gif b/resources/startupHints/assets/hint3/desktop-mode-annotation.gif
similarity index 100%
rename from resources/startupHints/assets/hint3/bureau-gif1.gif
rename to resources/startupHints/assets/hint3/desktop-mode-annotation.gif
diff --git a/resources/startupHints/assets/hint3/bureau1.png b/resources/startupHints/assets/hint3/desktop-mode-icon.png
similarity index 100%
rename from resources/startupHints/assets/hint3/bureau1.png
rename to resources/startupHints/assets/hint3/desktop-mode-icon.png
diff --git a/resources/startupHints/assets/hint3/bureau-gif2.gif b/resources/startupHints/assets/hint3/desktop-mode-navigation.gif
similarity index 100%
rename from resources/startupHints/assets/hint3/bureau-gif2.gif
rename to resources/startupHints/assets/hint3/desktop-mode-navigation.gif
diff --git a/resources/startupHints/assets/hint4/gif-document1.gif b/resources/startupHints/assets/hint4/documents-folder-organization.gif
similarity index 100%
rename from resources/startupHints/assets/hint4/gif-document1.gif
rename to resources/startupHints/assets/hint4/documents-folder-organization.gif
diff --git a/resources/startupHints/assets/hint4/document1.png b/resources/startupHints/assets/hint4/documents-manager-view.png
similarity index 100%
rename from resources/startupHints/assets/hint4/document1.png
rename to resources/startupHints/assets/hint4/documents-manager-view.png
diff --git a/resources/startupHints/assets/hint4/gif-document2.gif b/resources/startupHints/assets/hint4/documents-page-actions.gif
similarity index 100%
rename from resources/startupHints/assets/hint4/gif-document2.gif
rename to resources/startupHints/assets/hint4/documents-page-actions.gif
diff --git a/resources/startupHints/assets/hint5/gif2.gif b/resources/startupHints/assets/hint5/documents-export-files.gif
similarity index 100%
rename from resources/startupHints/assets/hint5/gif2.gif
rename to resources/startupHints/assets/hint5/documents-export-files.gif
diff --git a/resources/startupHints/assets/hint5/img1.png b/resources/startupHints/assets/hint5/documents-import-export-panel.png
similarity index 100%
rename from resources/startupHints/assets/hint5/img1.png
rename to resources/startupHints/assets/hint5/documents-import-export-panel.png
diff --git a/resources/startupHints/assets/hint5/gif1.gif b/resources/startupHints/assets/hint5/documents-import-files.gif
similarity index 100%
rename from resources/startupHints/assets/hint5/gif1.gif
rename to resources/startupHints/assets/hint5/documents-import-files.gif
diff --git a/resources/startupHints/assets/hint6/addToolToLibrary.png b/resources/startupHints/assets/hint6/add-tool-to-library-icon.png
similarity index 100%
rename from resources/startupHints/assets/hint6/addToolToLibrary.png
rename to resources/startupHints/assets/hint6/add-tool-to-library-icon.png
diff --git a/resources/startupHints/assets/hint6/app1.png b/resources/startupHints/assets/hint6/web-browser-integrated-view.png
similarity index 100%
rename from resources/startupHints/assets/hint6/app1.png
rename to resources/startupHints/assets/hint6/web-browser-integrated-view.png
diff --git a/resources/startupHints/assets/hint6/app-gif2.gif b/resources/startupHints/assets/hint6/web-create-library-app.gif
similarity index 100%
rename from resources/startupHints/assets/hint6/app-gif2.gif
rename to resources/startupHints/assets/hint6/web-create-library-app.gif
diff --git a/resources/startupHints/assets/hint6/app2.png b/resources/startupHints/assets/hint6/web-library-entry.png
similarity index 100%
rename from resources/startupHints/assets/hint6/app2.png
rename to resources/startupHints/assets/hint6/web-library-entry.png
diff --git a/resources/startupHints/assets/hint6/app-gif1.gif b/resources/startupHints/assets/hint6/web-open-website.gif
similarity index 100%
rename from resources/startupHints/assets/hint6/app-gif1.gif
rename to resources/startupHints/assets/hint6/web-open-website.gif
diff --git a/resources/startupHints/assets/hint6/app-gif3.gif b/resources/startupHints/assets/hint6/web-saved-in-library.gif
similarity index 100%
rename from resources/startupHints/assets/hint6/app-gif3.gif
rename to resources/startupHints/assets/hint6/web-saved-in-library.gif
diff --git a/resources/startupHints/assets/hint7/gif-capture1.gif b/resources/startupHints/assets/hint7/board-area-capture.gif
similarity index 100%
rename from resources/startupHints/assets/hint7/gif-capture1.gif
rename to resources/startupHints/assets/hint7/board-area-capture.gif
diff --git a/resources/startupHints/assets/hint7/caputre2.png b/resources/startupHints/assets/hint7/board-capture-area-selection.png
similarity index 100%
rename from resources/startupHints/assets/hint7/caputre2.png
rename to resources/startupHints/assets/hint7/board-capture-area-selection.png
diff --git a/resources/startupHints/assets/hint7/caputre3.png b/resources/startupHints/assets/hint7/board-capture-result.png
similarity index 100%
rename from resources/startupHints/assets/hint7/caputre3.png
rename to resources/startupHints/assets/hint7/board-capture-result.png
diff --git a/resources/startupHints/assets/hint7/capture1.png b/resources/startupHints/assets/hint7/board-capture-tool.png
similarity index 100%
rename from resources/startupHints/assets/hint7/capture1.png
rename to resources/startupHints/assets/hint7/board-capture-tool.png
diff --git a/resources/startupHints/assets/hint7/capture-gif2.gif b/resources/startupHints/assets/hint7/desktop-area-capture.gif
similarity index 100%
rename from resources/startupHints/assets/hint7/capture-gif2.gif
rename to resources/startupHints/assets/hint7/desktop-area-capture.gif
diff --git a/resources/startupHints/assets/hint7/capture4.png b/resources/startupHints/assets/hint7/desktop-capture-tool.png
similarity index 100%
rename from resources/startupHints/assets/hint7/capture4.png
rename to resources/startupHints/assets/hint7/desktop-capture-tool.png
diff --git a/resources/startupHints/assets/hint8/documents-import-export-zone.png b/resources/startupHints/assets/hint8/documents-import-export-zone.png
new file mode 100644
index 000000000..10698d241
Binary files /dev/null and b/resources/startupHints/assets/hint8/documents-import-export-zone.png differ
diff --git a/resources/startupHints/assets/hint8/capture2.png b/resources/startupHints/assets/hint8/image-library-folder-view.png
similarity index 100%
rename from resources/startupHints/assets/hint8/capture2.png
rename to resources/startupHints/assets/hint8/image-library-folder-view.png
diff --git a/resources/startupHints/assets/hint8/capture1.png b/resources/startupHints/assets/hint8/image-library-open.png
similarity index 100%
rename from resources/startupHints/assets/hint8/capture1.png
rename to resources/startupHints/assets/hint8/image-library-open.png
diff --git a/resources/startupHints/assets/hint8/image-gif1.gif b/resources/startupHints/assets/hint8/images-folder-organization.gif
similarity index 100%
rename from resources/startupHints/assets/hint8/image-gif1.gif
rename to resources/startupHints/assets/hint8/images-folder-organization.gif
diff --git a/resources/startupHints/assets/hint8/image-gif3.gif b/resources/startupHints/assets/hint8/images-local-import.gif
similarity index 100%
rename from resources/startupHints/assets/hint8/image-gif3.gif
rename to resources/startupHints/assets/hint8/images-local-import.gif
diff --git a/resources/startupHints/assets/hint8/image-gif2.gif b/resources/startupHints/assets/hint8/images-web-search-import.gif
similarity index 100%
rename from resources/startupHints/assets/hint8/image-gif2.gif
rename to resources/startupHints/assets/hint8/images-web-search-import.gif
diff --git a/resources/startupHints/assets/hint9/cat-pict.png b/resources/startupHints/assets/hint9/categorize-pictures-widget.png
similarity index 100%
rename from resources/startupHints/assets/hint9/cat-pict.png
rename to resources/startupHints/assets/hint9/categorize-pictures-widget.png
diff --git a/resources/startupHints/assets/hint9/interactivite-gif2.gif b/resources/startupHints/assets/hint9/interactivity-add-images.gif
similarity index 100%
rename from resources/startupHints/assets/hint9/interactivite-gif2.gif
rename to resources/startupHints/assets/hint9/interactivity-add-images.gif
diff --git a/resources/startupHints/assets/hint9/interactivite3.png b/resources/startupHints/assets/hint9/interactivity-category-editor.png
similarity index 100%
rename from resources/startupHints/assets/hint9/interactivite3.png
rename to resources/startupHints/assets/hint9/interactivity-category-editor.png
diff --git a/resources/startupHints/assets/hint9/interactivite-gif3.gif b/resources/startupHints/assets/hint9/interactivity-run-exercise.gif
similarity index 100%
rename from resources/startupHints/assets/hint9/interactivite-gif3.gif
rename to resources/startupHints/assets/hint9/interactivity-run-exercise.gif
diff --git a/resources/startupHints/assets/hint9/interactivite1.png b/resources/startupHints/assets/hint9/interactivity-widget-list.png
similarity index 100%
rename from resources/startupHints/assets/hint9/interactivite1.png
rename to resources/startupHints/assets/hint9/interactivity-widget-list.png
diff --git a/resources/startupHints/css/basic.css b/resources/startupHints/css/basic.css
deleted file mode 100644
index e6b509beb..000000000
--- a/resources/startupHints/css/basic.css
+++ /dev/null
@@ -1,82 +0,0 @@
-html, body{
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- font-family: sans-serif;
- overflow: hidden;
-}
-
-body{
- background-color: #aaaaaa;
-}
-
-#main{
- background-color: #eeeeee;
- width: 99%;
- margin: 0px;
- margin-left:1px;
- padding: 0px;
- height: 99%;
- border-color:#999999;
- border-width:2px;
- border-radius:10px;
- border-style:solid;
-}
-
-#content{
- width: 100%;
- margin: 0px;
- padding: 0px;
- height: 90%;
-}
-
-iframe{
- border: none;
- padding: 5px;
-}
-
-#separator{
- width: 96%;
- margin: 0 auto;
- border: 2px solid #ccc;
-}
-
-#controls{
- height: 30px;
-}
-
-#navigation{
- margin-left: 10px;
- height: 100%;
- float: left;
- margin-top: 5px;
-}
-
-#left{
- width: 30px;
- height: 30px;
- background-image: url(../images/left.png);
- cursor: pointer;
- float: left;
-}
-
-#right{
- width: 30px;
- height: 30px;
- background-image: url(../images/right.png);
- cursor: pointer;
- float: right;
-}
-
-#title{
- width: 250px;
- height: 100%;
- float: left;
- margin: 0 5px;
- text-align: center;
- vertical-align: middle;
- display: table;
- user-select: none;
-}
-
diff --git a/resources/startupHints/css/dark.css b/resources/startupHints/css/dark.css
new file mode 100644
index 000000000..159b40487
--- /dev/null
+++ b/resources/startupHints/css/dark.css
@@ -0,0 +1,50 @@
+:root,
+:root[data-theme="dark"] {
+ /* Core colors */
+ --bg: #1f2329;
+ --text: #e5e7eb;
+ --muted: #9ca3af;
+ --brand: #8ba3d7;
+ --brand-soft: #2a3038;
+ --surface: #2b313a;
+ --line: #4b5563;
+ --tip-bg: #26303c;
+
+ /* Host and navigation shell */
+ --host-content-bg: #1b2027;
+ --host-frame-bg: #1f2329;
+ --nav-shell-bg: rgba(35, 43, 54, 0.92);
+ --nav-shell-border: rgba(114, 139, 176, 0.42);
+ --nav-shell-shadow: 0 4px 12px rgba(2, 7, 17, 0.44), 0 1px 2px rgba(0, 0, 0, 0.34);
+ --nav-btn-border: rgba(122, 146, 185, 0.45);
+ --nav-btn-bg: #2a3442;
+ --nav-btn-shadow: 0 1px 2px rgba(0, 0, 0, 0.32);
+ --nav-btn-hover-border: rgba(150, 178, 221, 0.72);
+ --nav-btn-hover-shadow: 0 2px 6px rgba(8, 16, 34, 0.48);
+ --nav-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
+ --nav-btn-focus-ring: 0 0 0 3px rgba(148, 186, 255, 0.3);
+ --nav-btn-focus-border: #98bfff;
+ --nav-title-color: #6682b5;
+ --nav-title-bg: rgba(33, 42, 54, 0.86);
+ --nav-title-border: rgba(136, 164, 207, 0.34);
+ --nav-divider: rgba(148, 175, 218, 0.36);
+ --nav-icon-filter: brightness(1.15) contrast(1.02);
+ --nav-icon-hover-filter: brightness(0) saturate(100%) invert(73%) sepia(41%) saturate(808%) hue-rotate(179deg) brightness(101%) contrast(99%);
+
+ /* Scrollbars */
+ --scrollbar-track: #2b2b2b;
+ --scrollbar-thumb: #ffffff;
+}
+
+body {
+ background-color: var(--bg);
+ color: var(--text);
+}
+
+#content {
+ background: var(--host-content-bg);
+}
+
+#source {
+ background: var(--host-frame-bg);
+}
\ No newline at end of file
diff --git a/resources/startupHints/css/light.css b/resources/startupHints/css/light.css
new file mode 100644
index 000000000..65e95b1f1
--- /dev/null
+++ b/resources/startupHints/css/light.css
@@ -0,0 +1,50 @@
+:root,
+:root[data-theme="light"] {
+ /* Core colors */
+ --bg: #ffffff;
+ --text: #1f2937;
+ --muted: #6b7280;
+ --brand: #6682b5;
+ --brand-soft: #ffffff;
+ --surface: #ffffff;
+ --line: #e5e7eb;
+ --tip-bg: #f8fafc;
+
+ /* Host and navigation shell */
+ --host-content-bg: #fafafa;
+ --host-frame-bg: #ffffff;
+ --nav-shell-bg: rgba(246, 250, 255, 0.94);
+ --nav-shell-border: rgba(147, 175, 226, 0.44);
+ --nav-shell-shadow: 0 4px 12px rgba(27, 58, 114, 0.1), 0 1px 2px rgba(17, 24, 39, 0.08);
+ --nav-btn-border: rgba(145, 172, 223, 0.58);
+ --nav-btn-bg: #f5f8fe;
+ --nav-btn-shadow: 0 1px 2px rgba(31, 59, 102, 0.08);
+ --nav-btn-hover-border: rgba(66, 104, 172, 0.7);
+ --nav-btn-hover-shadow: 0 2px 6px rgba(33, 76, 149, 0.16);
+ --nav-btn-active-shadow: 0 1px 2px rgba(33, 76, 149, 0.18);
+ --nav-btn-focus-ring: 0 0 0 3px rgba(59, 130, 246, 0.26);
+ --nav-btn-focus-border: #2f5fb3;
+ --nav-title-color: #6682b5;
+ --nav-title-bg: rgba(255, 255, 255, 0.82);
+ --nav-title-border: rgba(139, 167, 214, 0.35);
+ --nav-divider: rgba(93, 125, 181, 0.34);
+ --nav-icon-filter: none;
+ --nav-icon-hover-filter: brightness(0) saturate(100%) invert(42%) sepia(31%) saturate(1014%) hue-rotate(181deg) brightness(90%) contrast(91%);
+
+ /* Scrollbars (aligned with lightTheme.qss) */
+ --scrollbar-track: transparent;
+ --scrollbar-thumb: #cdd7e3;
+}
+
+body {
+ background-color: var(--bg);
+ color: var(--text);
+}
+
+#content {
+ background: var(--host-content-bg);
+}
+
+#source {
+ background: var(--host-frame-bg);
+}
\ No newline at end of file
diff --git a/resources/startupHints/css/style.css b/resources/startupHints/css/style.css
new file mode 100644
index 000000000..88b1b088c
--- /dev/null
+++ b/resources/startupHints/css/style.css
@@ -0,0 +1,492 @@
+/*
+ Startup hints stylesheet
+ Scope:
+ - Host viewer (index.html)
+ - Hint page content rendered inside the iframe (all locales)
+*/
+
+/* =========================
+ 1) Base and typography
+ ========================= */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+ background: var(--bg);
+ color: var(--text);
+ font-family: Arial, Helvetica, sans-serif;
+ line-height: 1.55;
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Scrollbars follow OpenBoard theme colors (qss to update to harmonize all OpenBoard scrollbars) */
+html,
+body,
+#content,
+#source {
+ scrollbar-width: auto;
+ scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
+}
+
+*::-webkit-scrollbar {
+ width: 12px;
+ height: 12px;
+}
+
+*::-webkit-scrollbar-track {
+ background: var(--scrollbar-track);
+}
+
+*::-webkit-scrollbar-thumb {
+ background: var(--scrollbar-thumb);
+}
+
+*::-webkit-scrollbar-corner {
+ background: var(--scrollbar-track);
+}
+
+p {
+ margin: 0.5rem 0;
+}
+
+/* =========================
+ 2) Host viewer (index.html)
+ ========================= */
+#main:not(.container) {
+ min-height: 100vh;
+ height: 100dvh;
+ display: grid;
+ grid-template-rows: minmax(0, 1fr) auto;
+}
+
+#content {
+ min-height: 0;
+ background: var(--host-content-bg);
+}
+
+#source {
+ width: 100%;
+ height: 100%;
+ border: 0;
+ display: block;
+ background: var(--host-frame-bg);
+}
+
+#controls {
+ margin: 0;
+ padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: transparent;
+ border-top: 1px solid var(--line);
+}
+
+#navigation {
+ display: grid;
+ grid-template-columns: 46px minmax(0, 1fr) 46px;
+ align-items: center;
+ gap: 8px;
+ width: min(400px, calc(100vw - 20px));
+ padding: 0;
+}
+
+#left,
+#right {
+ width: 40px;
+ height: 40px;
+ border: 0;
+ border-radius: 8px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ user-select: none;
+ background: transparent;
+ box-shadow: none;
+ padding: 0;
+ opacity: 0.86;
+ transition: transform 0.14s ease, opacity 0.18s ease;
+}
+
+.nav-icon {
+ width: 30px;
+ height: 30px;
+ display: block;
+ filter: var(--nav-icon-filter);
+ transition: transform 0.18s ease, filter 0.18s ease;
+}
+
+#left:hover,
+#right:hover {
+ transform: translateY(-1px);
+ opacity: 1;
+}
+
+#left:hover .nav-icon,
+#right:hover .nav-icon {
+ transform: scale(1.03);
+ filter: var(--nav-icon-hover-filter);
+}
+
+#left:active,
+#right:active {
+ transform: translateY(0);
+ opacity: 0.9;
+}
+
+#left:active .nav-icon,
+#right:active .nav-icon {
+ transform: scale(0.98);
+}
+
+#left:focus-visible,
+#right:focus-visible {
+ outline: none;
+ opacity: 1;
+ border-radius: 4px;
+ box-shadow: var(--nav-btn-focus-ring);
+}
+
+#title {
+ min-width: 120px;
+ text-align: center;
+ font-size: 15px;
+ font-weight: 600;
+ letter-spacing: 0.08em;
+ color: var(--nav-title-color);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+}
+
+#title::before,
+#title::after {
+ content: "";
+ flex: 1 1 auto;
+ max-width: 44px;
+ height: 1px;
+ background: var(--nav-divider);
+}
+
+#title span {
+ display: inline-block;
+ padding: 0;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+ font-variant-numeric: tabular-nums;
+ text-transform: uppercase;
+}
+
+@media (max-width: 520px) {
+ #navigation {
+ width: min(350px, calc(100vw - 12px));
+ gap: 6px;
+ padding: 0;
+ }
+
+ #left,
+ #right {
+ width: 34px;
+ height: 34px;
+ }
+
+ .nav-icon {
+ width: 26px;
+ height: 26px;
+ }
+
+ #title {
+ font-size: 13px;
+ gap: 8px;
+ }
+
+ #title::before,
+ #title::after {
+ max-width: 28px;
+ }
+}
+
+/* =========================
+ 3) Hint page content (iframe)
+ ========================= */
+.container {
+ width: min(920px, 92vw);
+ margin: 0 auto;
+ padding: 16px;
+}
+
+.page-header {
+ border-bottom: 1px solid var(--line);
+ background: var(--brand-soft);
+}
+
+.page-footer {
+ background: var(--bg);
+}
+
+.logo-title {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 20px;
+}
+
+.title {
+ margin: 0;
+ text-align: center;
+ color: var(--brand);
+ font-size: clamp(1.4rem, 2.6vw, 2rem);
+ font-weight: 700;
+}
+
+/* Keep a fixed header title size across FR hint pages (1-12). */
+html[lang="fr"] .title {
+ font-size: 1.8rem;
+}
+
+#logo {
+ width: 36px;
+ height: 36px;
+}
+
+#logo-small {
+ width: 48px;
+ height: 48px;
+}
+
+.lead {
+ font-size: 1.05rem;
+ margin: 0.75rem 0 0.25rem;
+}
+
+.h2 {
+ margin: 1rem 0 0.25rem;
+ font-size: clamp(1.05rem, 2.2vw, 1.25rem);
+ font-weight: 700;
+}
+
+.modes {
+ margin-top: 0.75rem;
+}
+
+.modes-grid {
+ list-style: none;
+ margin: 0.5rem 0 0;
+ padding: 0;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.mode-card {
+ background: var(--surface);
+ border: 1px solid var(--line);
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
+ transition: transform 0.15s ease, box-shadow 0.15s ease;
+}
+
+.mode-card:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
+}
+
+.mode-title {
+ margin: 0 0 8px;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 1.05rem;
+ font-weight: 600;
+ color: var(--brand);
+}
+
+.mode-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ color: inherit;
+ text-decoration: none;
+}
+
+.mode-link:focus-visible {
+ outline: 2px solid var(--brand);
+ outline-offset: 2px;
+}
+
+.mode-card-link {
+ display: block;
+ margin: -16px;
+ padding: 16px;
+ border-radius: inherit;
+ color: inherit;
+ text-decoration: none;
+}
+
+.mode-card-link:focus-visible {
+ outline: 2px solid var(--brand);
+ outline-offset: 2px;
+}
+
+.mode-icon {
+ width: 20px;
+ height: 20px;
+ flex: 0 0 20px;
+}
+
+.mode-text {
+ margin: 0;
+}
+
+.start {
+ margin-top: 0.75rem;
+}
+
+.image {
+ margin: 20px 0 12px;
+ text-align: center;
+}
+
+.image figcaption {
+ margin-top: 8px;
+ font-size: 0.9rem;
+ color: var(--muted);
+}
+
+.features {
+ list-style: none;
+ margin: 0.5rem 0 0;
+ padding: 0;
+}
+
+.features li {
+ position: relative;
+ margin: 0.25rem 0;
+ padding-left: 1.1rem;
+}
+
+.features li::before {
+ content: "•";
+ position: absolute;
+ left: 0;
+ color: var(--brand);
+ line-height: 1.2;
+}
+
+.file-extension {
+ font-family: Consolas, "Courier New", monospace;
+ font-size: 0.95em;
+ color: var(--brand);
+}
+
+.non-clickable {
+ cursor: default;
+ text-decoration: underline dotted;
+}
+
+.non-clickable:focus {
+ outline: none;
+}
+
+.tip {
+ margin-top: 1.5rem;
+ padding: 10px 12px;
+ display: flex;
+ align-items: flex-start;
+ gap: 8px;
+ border: 1px dashed var(--brand);
+ border-radius: 10px;
+ background: var(--tip-bg);
+ font-size: 0.95rem;
+ line-height: 1.4;
+}
+
+.tip p {
+ margin: 0;
+}
+
+.tip-icon {
+ width: 24px;
+ height: 24px;
+ margin-top: 2px;
+}
+
+.inline-icon {
+ vertical-align: -4px;
+ margin-left: 4px;
+}
+
+/* Semantic screenshot sizing helpers used across hint pages. */
+.hint-shot,
+.hint-shot--standard {
+ width: 100%;
+ max-width: min(360px, 92vw);
+ height: auto;
+}
+
+.hint-shot--narrow {
+ width: 100%;
+ max-width: min(240px, 92vw);
+ height: auto;
+}
+
+.hint-shot--wide {
+ width: 100%;
+ max-width: min(420px, 92vw);
+ height: auto;
+}
+
+/* =========================
+ 4) Responsive and accessibility
+ ========================= */
+@media (max-width: 640px) {
+ .modes-grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+@media (max-width: 480px) {
+ #navigation {
+ grid-template-columns: 30px minmax(120px, 1fr) 30px;
+ gap: 6px;
+ padding: 4px;
+ }
+
+ #left,
+ #right {
+ width: 28px;
+ height: 28px;
+ }
+
+ #title {
+ min-width: 120px;
+ font-size: 12px;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .mode-card,
+ #left,
+ #right {
+ transition: none;
+ }
+}
diff --git a/resources/startupHints/index.html b/resources/startupHints/index.html
index 6353c7c5a..ae7355224 100644
--- a/resources/startupHints/index.html
+++ b/resources/startupHints/index.html
@@ -1,102 +1,32 @@
-
-
-
- Introduce
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ Startuphints
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/js/app.js b/resources/startupHints/js/app.js
new file mode 100644
index 000000000..2f305c491
--- /dev/null
+++ b/resources/startupHints/js/app.js
@@ -0,0 +1,445 @@
+"use strict";
+
+/*
+ Startup hints runtime model:
+ 1) This host page controls navigation and title (index shell).
+ 2) Host theme CSS is applied here (light.css / dark.css).
+ 3) Each iframe page applies its own theme through theme-loader.js
+ using the ?theme=... query param.
+*/
+
+// ─── Config ──────────────────────────────────────────────────────────────────
+
+var CONFIG = {
+ language: "en",
+ localesRoot: "locales",
+ maxHints: 50
+};
+
+var DEBUG = new URLSearchParams(window.location.search).get("debug") === "1";
+
+function debugLog() {
+ if (!DEBUG) return;
+ var args = Array.prototype.slice.call(arguments);
+ args.unshift("[startupHints]");
+ console.log.apply(console, args);
+}
+
+var THEME_SYNC_RETRY_INTERVAL_MS = 100;
+var THEME_SYNC_MAX_ATTEMPTS = 40;
+
+// ─── State ───────────────────────────────────────────────────────────────────
+
+var state = {
+ currentIndex: 1,
+ fileCount: 0,
+ theme: "light"
+};
+
+// ─── DOM cache ───────────────────────────────────────────────────────────────
+
+var dom = {
+ source: null,
+ left: null,
+ right: null,
+ titleSpan: null
+};
+
+function cacheDomElements() {
+ dom.source = document.getElementById("source");
+ dom.left = document.getElementById("left");
+ dom.right = document.getElementById("right");
+ dom.titleSpan = document.querySelector("#title span");
+}
+
+// ─── URL builders ────────────────────────────────────────────────────────────
+
+function buildHintFileUrl(index) {
+ return CONFIG.localesRoot + "/" + CONFIG.language + "/" + index + ".html";
+}
+
+function buildHintUrl(index) {
+ return buildHintFileUrl(index) + "?theme=" + encodeURIComponent(state.theme);
+}
+
+function buildErrorUrl() {
+ return CONFIG.localesRoot + "/" + CONFIG.language + "/error.html"
+ + "?theme=" + encodeURIComponent(state.theme);
+}
+
+// ─── Language detection ─────────────────────────────────────────────────────
+
+function normalizeLanguage(value) {
+ if (typeof value !== "string") return null;
+ var trimmed = value.trim();
+ if (!trimmed) return null;
+
+ // Accept forms like "de", "de-DE", "de_DE" and keep the base language.
+ var base = trimmed.split(/[-_]/)[0].toLowerCase();
+ return /^[a-z]{2,3}$/.test(base) ? base : null;
+}
+
+function detectLanguageFromUrl() {
+ var params = new URLSearchParams(window.location.search);
+ return normalizeLanguage(params.get("lang") || params.get("language"));
+}
+
+function detectLanguageFromSankore() {
+ if (!window.sankore) return null;
+
+ try {
+ if (typeof window.sankore.lang === "function") {
+ return normalizeLanguage(window.sankore.lang());
+ }
+
+ return normalizeLanguage(window.sankore.lang);
+ } catch (e) {
+ return null;
+ }
+}
+
+function getCurrentLanguage() {
+ return detectLanguageFromUrl()
+ || detectLanguageFromSankore()
+ || normalizeLanguage(CONFIG.language)
+ || "en";
+}
+
+function localeExists(language) {
+ return requestText(CONFIG.localesRoot + "/" + language + "/1.html")
+ .then(function() { return true; })
+ .catch(function() { return false; });
+}
+
+async function resolveLanguage(preferredLanguage) {
+ var candidates = [
+ preferredLanguage,
+ normalizeLanguage(CONFIG.language),
+ "en"
+ ].filter(Boolean);
+
+ var seen = Object.create(null);
+ for (var i = 0; i < candidates.length; i++) {
+ var candidate = candidates[i];
+ if (seen[candidate]) continue;
+ seen[candidate] = true;
+
+ if (await localeExists(candidate)) return candidate;
+ }
+
+ return "en";
+}
+
+// ─── Theme detection ─────────────────────────────────────────────────────────
+
+function normalizeTheme(value) {
+ if (value === "dark" || value === "light") return value;
+ return null;
+}
+
+function detectThemeFromUrl() {
+ var params = new URLSearchParams(window.location.search);
+ return normalizeTheme(params.get("theme"));
+}
+
+function detectInitialHintFromUrl() {
+ var params = new URLSearchParams(window.location.search);
+ var raw = params.get("hint");
+ if (!raw) return null;
+
+ var index = parseInt(raw, 10);
+ if (!Number.isFinite(index) || index < 1) return null;
+ return index;
+}
+
+function resolveInitialHintIndex(fileCount) {
+ var requested = detectInitialHintFromUrl();
+ if (!requested) return 1;
+ if (requested > fileCount) return fileCount;
+ return requested;
+}
+
+function detectThemeFromSankore() {
+ if (window.sankore && typeof window.sankore.isDarkMode !== "undefined") {
+ return window.sankore.isDarkMode ? "dark" : "light";
+ }
+ return null;
+}
+
+function resolveTheme() {
+ return detectThemeFromUrl() || detectThemeFromSankore() || state.theme || "light";
+}
+
+// ─── Theme application ───────────────────────────────────────────────────────
+
+// Host-only theme stylesheet.
+// The iframe theme is handled by theme-loader.js.
+
+function applyHostThemeStylesheet(theme) {
+ var safeTheme = normalizeTheme(theme) || "light";
+ var themeUrl = new URL("css/" + safeTheme + ".css", window.location.href).href;
+ var linkId = "ob-theme-css";
+ var link = document.getElementById(linkId);
+
+ if (!link) {
+ link = document.createElement("link");
+ link.id = linkId;
+ link.rel = "stylesheet";
+ link.type = "text/css";
+ document.head.appendChild(link);
+ }
+
+ if (link.href !== themeUrl) link.href = themeUrl;
+}
+
+function applyHostTheme(theme) {
+ var safeTheme = normalizeTheme(theme) || "light";
+ document.documentElement.setAttribute("data-theme", safeTheme);
+ applyHostThemeStylesheet(safeTheme);
+}
+
+// Reload the current iframe page with the updated ?theme value.
+function refreshCurrentHintTheme() {
+ if (!dom.source || state.fileCount < 1) return;
+ dom.source.src = buildHintUrl(state.currentIndex);
+}
+
+// Sync host + iframe when OpenBoard theme changes.
+function bindThemeSync() {
+ function connectThemeBridge() {
+ if (!window.sankore
+ || !window.sankore.themeChanged
+ || typeof window.sankore.themeChanged.connect !== "function") {
+ return false;
+ }
+
+ window.sankore.themeChanged.connect(function(isDark) {
+ state.theme = isDark ? "dark" : "light";
+ applyHostTheme(state.theme);
+ // The iframe theme is applied by theme-loader.js via ?theme=...
+ refreshCurrentHintTheme();
+ });
+
+ var current = detectThemeFromSankore();
+ if (current && current !== state.theme) {
+ state.theme = current;
+ applyHostTheme(state.theme);
+ }
+
+ return true;
+ }
+
+ if (connectThemeBridge()) return;
+
+ var attempts = 0;
+ var timer = setInterval(function() {
+ if (connectThemeBridge() || ++attempts >= THEME_SYNC_MAX_ATTEMPTS) {
+ clearInterval(timer);
+ }
+ }, THEME_SYNC_RETRY_INTERVAL_MS);
+}
+
+// ─── Navigation ──────────────────────────────────────────────────────────────
+
+function loadCurrentHint() {
+ if (!dom.source) return;
+ state.theme = resolveTheme();
+ applyHostTheme(state.theme);
+ dom.source.src = buildHintUrl(state.currentIndex);
+ debugLog("loadHint", {
+ index: state.currentIndex,
+ fileCount: state.fileCount,
+ language: CONFIG.language,
+ theme: state.theme,
+ src: dom.source.src
+ });
+}
+
+function goToNextHint() {
+ if (state.fileCount < 1) return;
+ state.currentIndex = state.currentIndex < state.fileCount
+ ? state.currentIndex + 1
+ : 1;
+ loadCurrentHint();
+}
+
+function goToPreviousHint() {
+ if (state.fileCount < 1) return;
+ state.currentIndex = state.currentIndex > 1
+ ? state.currentIndex - 1
+ : state.fileCount;
+ loadCurrentHint();
+}
+
+function goToHint(index) {
+ if (state.fileCount < 1) return;
+
+ var target = parseInt(index, 10);
+ if (!Number.isFinite(target)) return;
+
+ if (target < 1) target = 1;
+ if (target > state.fileCount) target = state.fileCount;
+
+ state.currentIndex = target;
+ loadCurrentHint();
+}
+
+function bindNavigationHandlers() {
+ if (dom.right) dom.right.addEventListener("click", goToNextHint);
+ if (dom.left) dom.left.addEventListener("click", goToPreviousHint);
+
+ document.addEventListener("keydown", function(e) {
+ if (e.key === "ArrowRight") goToNextHint();
+ if (e.key === "ArrowLeft") goToPreviousHint();
+ });
+}
+
+// ─── Iframe handlers ─────────────────────────────────────────────────────────
+
+function bindFrameHandlers() {
+ if (!dom.source) return;
+ dom.source.addEventListener("load", setTitle);
+ dom.source.addEventListener("load", function() {
+ debugLog("iframeLoaded", {
+ index: state.currentIndex,
+ src: dom.source ? dom.source.src : null
+ });
+ });
+}
+
+// ─── Hint detection ──────────────────────────────────────────────────────────
+
+// Probes files sequentially until the first missing page is found.
+async function detectAvailableHints() {
+ while (state.fileCount < CONFIG.maxHints) {
+ try {
+ await requestText(buildHintFileUrl(state.fileCount + 1));
+ state.fileCount++;
+ } catch (e) {
+ break;
+ }
+ }
+
+ if (state.fileCount === CONFIG.maxHints) {
+ console.warn("Hint detection reached maxHints limit:", CONFIG.maxHints);
+ }
+}
+
+// ─── HTTP helper ─────────────────────────────────────────────────────────────
+
+// Tries fetch first, falls back to XHR for file:// contexts (OpenBoard).
+function requestText(url) {
+ return fetch(url, { method: "GET", cache: "no-store" })
+ .then(function(response) {
+ if (!response.ok) throw new Error("HTTP " + response.status);
+ return response.text().then(function(text) {
+ if (isMissingFileResponse(text)) throw new Error("Missing file");
+ return text;
+ });
+ })
+ .catch(function() {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, true);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState !== 4) return;
+ var ok = xhr.status >= 200 && xhr.status < 300;
+ var hasBody = typeof xhr.responseText === "string" && xhr.responseText.length > 0;
+ var local = xhr.status === 0 && hasBody && !isMissingFileResponse(xhr.responseText);
+ if (ok || local) resolve(xhr.responseText);
+ else reject(new Error("HTTP " + xhr.status));
+ };
+ xhr.onerror = function() { reject(new Error("Network error")); };
+ xhr.send();
+ });
+ });
+}
+
+function isMissingFileResponse(text) {
+ if (typeof text !== "string") return true;
+ return text.indexOf("ERR_FILE_NOT_FOUND") !== -1
+ || text.indexOf("404 Not Found") !== -1;
+}
+
+// ─── Title ───────────────────────────────────────────────────────────────────
+
+// Called on iframe load to refresh the center label.
+function setTitle() {
+ if (!dom.source || !dom.titleSpan) cacheDomElements();
+ if (!dom.source || !dom.titleSpan) return;
+
+ try {
+ var doc = dom.source.contentWindow.document;
+ var titleEl = doc.getElementsByTagName("title")[0];
+ var pageTitle = titleEl ? titleEl.innerHTML : "";
+ dom.titleSpan.textContent = state.currentIndex + "/" + state.fileCount
+ + (pageTitle ? " : " + pageTitle : "");
+ } catch (e) {
+ dom.titleSpan.textContent = state.currentIndex + "/" + state.fileCount;
+ }
+}
+
+// ─── Init ────────────────────────────────────────────────────────────────────
+
+async function init() {
+ debugLog("init:start", {
+ search: window.location.search,
+ sankorePresent: !!window.sankore
+ });
+
+ cacheDomElements();
+ bindFrameHandlers();
+
+ var requestedLanguage = getCurrentLanguage();
+ CONFIG.language = await resolveLanguage(requestedLanguage);
+ debugLog("language:resolved", {
+ requested: requestedLanguage,
+ selected: CONFIG.language
+ });
+
+ state.theme = resolveTheme();
+ applyHostTheme(state.theme);
+ bindThemeSync();
+ debugLog("theme:resolved", { theme: state.theme });
+
+ await detectAvailableHints();
+ debugLog("hints:detected", { fileCount: state.fileCount });
+
+ if (state.fileCount > 0) {
+ state.currentIndex = resolveInitialHintIndex(state.fileCount);
+ loadCurrentHint();
+ } else if (dom.source) {
+ dom.source.src = buildErrorUrl();
+ debugLog("hints:none", { errorSrc: dom.source.src });
+ }
+
+ bindNavigationHandlers();
+
+ window.startupHints = window.startupHints || {};
+ window.startupHints.goToHint = goToHint;
+
+ debugLog("init:done");
+}
+
+if (DEBUG) {
+ window.addEventListener("error", function(event) {
+ debugLog("window:error", {
+ message: event.message,
+ source: event.filename,
+ line: event.lineno,
+ column: event.colno
+ });
+ });
+
+ window.addEventListener("unhandledrejection", function(event) {
+ debugLog("window:unhandledrejection", {
+ reason: event.reason && event.reason.message ? event.reason.message : String(event.reason)
+ });
+ });
+}
+
+document.addEventListener("DOMContentLoaded", function() {
+ init().catch(function(error) {
+ console.error("[startupHints] init failed", error);
+ });
+});
\ No newline at end of file
diff --git a/resources/startupHints/js/jquery-1.6.2.min.js b/resources/startupHints/js/jquery-1.6.2.min.js
deleted file mode 100644
index e67db7472..000000000
--- a/resources/startupHints/js/jquery-1.6.2.min.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.6.2
- * http://jquery.com/
- *
- * Copyright 2011, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2011, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Thu Jun 30 14:16:56 2011 -0400
- */
-(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;ca ",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j =0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.
-shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c ",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML=" ",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="
";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,""," "],thead:[1,""],tr:[2,""],td:[3,""],col:[2,""],area:[1,""," "],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>$2>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j
-)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1>$2>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/
+
+
+
+
+
+
+
+
+ إليك بعض النصائح والإرشادات التي تساعدك على التعرّف إلى OpenBoard .
+
+
+
+ OpenBoard هو سبورة تفاعلية صُممت من قبل المعلمين ولأجلهم.
+ ويوفر أربعة أوضاع متكاملة للاستخدام داخل الصف.
+
+
+
+ أوضاع OpenBoard الأربعة
+
+
+
+
+ لنبدأ بأول الأوضاع وأهمها: وضع السبورة .
+
+
+
+
+
+ يمكنك إعادة فتح هذه النافذة في أي وقت عبر زر
+ «النصائح والإرشادات» الموجود في قائمة OpenBoard .
+ .
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/10.html b/resources/startupHints/locales/ar/10.html
new file mode 100644
index 000000000..6485a31ec
--- /dev/null
+++ b/resources/startupHints/locales/ar/10.html
@@ -0,0 +1,94 @@
+
+
+
+
+ التطبيقات
+
+
+
+
+
+
+
+
+
+
+
+
+
+ الوصول إلى التطبيقات
+
+ يوفر OpenBoard تطبيقات وأدوات مختلفة.
+ يمكنك العثور عليها في المكتبة بالنقر على
+ .
+
+
+
+
+
+ التطبيقات الافتراضية
+
+ ستجد أدوات هندسية، وآلة حاسبة، وخرائط Google، ومولد رموز QR، وغيرها الكثير.
+ قم بدمجها لإنشاء تجارب تعليمية ممتعة!
+
+
+
+
+ مثال على استخدام التطبيقات المدمجة في OpenBoard.
+
+
+
+
+
+ إنشاء تطبيقاتك الخاصة
+
+ كما هو موضح في قسم وضع الويب , يمكنك إنشاء تطبيق من موقع ويب باستخدام المتصفح المدمج أو من خلال نسخ رابط URL ولصقه على اللوحة.
+
+
+ يتيح لك ذلك تعزيز دروسك بأدوات قوية متاحة على الإنترنت ويمكن استخدامها مباشرةً داخل OpenBoard.
+ فيما يلي بعض الأمثلة المفيدة (اسحب الروابط وأفلتها على اللوحة لتجربتها):
+
+
+
+
+ ...وغير ذلك الكثير!
+
+
+
+
+ هل تحتاج إلى آلة حاسبة أكثر تقدماً من الموجودة في OpenBoard؟ أنشئ تطبيقك الخاص
+ عن طريق السحب والإفلات لهذا الرابط على الطاولة:
+ https://ti89-simulator.com/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/11.html b/resources/startupHints/locales/ar/11.html
new file mode 100644
index 000000000..6ffd56704
--- /dev/null
+++ b/resources/startupHints/locales/ar/11.html
@@ -0,0 +1,89 @@
+
+
+
+
+ تسجيل الفيديو
+
+
+
+
+
+
+
+
+
+
+
+
+
+ تسجيل دراستك
+
+ تيح لك OpenBoard حفظ الصوت و الفيديو الخاصين بدرسك.
+ وهو مثالي لمشاركة تمارين إضافية، أو نشر مقطع توضيحي قصير، أو إتاحة الدرس للطلاب الغائبين.
+
+
+
+
+
+ في وضع السبورة ، لا تظهر أشرطة الأدوات ولوحات الأدوات في الفيديو.
+ في وضع الويب ، يتم التقاط علامة التبويب النشطة فقط.
+
+
+
+
+
+
+ الوصول إلى أداة التسجيل
+ افتح أداة التسجيل كما هو موضح أدناه:
+
+
+
+ وصول سريع إلى أداة التسجيل من واجهة OpenBoard.
+
+
+
+
+
+ واجهة التحكم
+ تظهر الواجهة في الزاوية السفلية اليمنى من اللوحة:
+
+
+
+
+
+ انقر على الزر الأحمر لبدء التسجيل.
+
+
+
+
+ يمكنك تخصيص إعدادات التسجيل عبر
+ :
+ اختيار الميكروفون (أو عدم استخدام أي ميكروفون), اختيار دقة الفيديو و خيارات النشر .
+
+
+
+
+
+
+ إنهاء التسجيل واسترجاع الفيديو
+
+ بعد انتهاء التسجيل، يتم حفظ الفيديو تلقائياً على سطح المكتب في جهازك.
+
+
+
+
+ إيقاف التسجيل وظهور ملف الفيديو على سطح المكتب.
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/12.html b/resources/startupHints/locales/ar/12.html
new file mode 100644
index 000000000..588108d3a
--- /dev/null
+++ b/resources/startupHints/locales/ar/12.html
@@ -0,0 +1,91 @@
+
+
+
+
+ المستندات المفضلة
+
+
+
+
+
+
+
+
+
+
+
+
+
+ إضافة مستندات OpenBoard إلى المفضلة
+
+ أُضيفت هذه الميزة في الإصدار 1.7 , وتتيح لك إضافة مستندات OpenBoard إلى المفضلة .
+
+
+ للقيام بذلك، انتقل إلى وضع المستندات , وحدد مستنداً ثم انقر على
+
+ في شريط الأدوات.
+
+
+
+
+
+
+
+
+
+
+ التنقل بسرعة من مستند إلى آخر
+
+ تظهر مستنداتك المفضلة في مكتبة OpenBoard , ضمن
+ .
+
+
+ كل مستند مفضل
+
+ يمكن سحبه وإفلاته مباشرة على اللوحة.
+
+
+
+
+
+
+
+
+
+
+
+
+ المستندات المفتوحة مؤخراً
+
+ يُضاف كل مستند يتم فتحه مؤقتاً إلى المفضلة، مما يتيح لك التنقل بسرعة بين المستندات خلال الجلسة نفسها دون الحاجة إلى إضافتها يدوياً.
+
+
+
+
+
+
+
+
+
+
+ لجعل أحد المستندات , المفتوحة مؤخراً مفضلاً بشكل دائم، حدده من مجلد المفضلة ثم انقر على
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/2.html b/resources/startupHints/locales/ar/2.html
new file mode 100644
index 000000000..79237974f
--- /dev/null
+++ b/resources/startupHints/locales/ar/2.html
@@ -0,0 +1,120 @@
+
+
+
+
+ وضع السبورة
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ شريط اللوحة
+
+ يتيح لك شريط اللوحة تغيير لون و/أو حجم القلم وقلم التمييز، بالإضافة إلى وظائف أخرى.
+
+
+
+
+
+
+
+ يمكنك أيضاً تغيير خلفية اللوحة بالنقر على
+ .
+
+
+
+
+
+
+
+ تتوفر وظائف أخرى مثل: التراجع/الإعادة، إنشاء صفحات, التنقل بين الصفحات, مسح اللوحة وغيرها.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/3.html b/resources/startupHints/locales/ar/3.html
new file mode 100644
index 000000000..576f682d6
--- /dev/null
+++ b/resources/startupHints/locales/ar/3.html
@@ -0,0 +1,73 @@
+
+
+
+
+ وضع سطح المكتب
+
+
+
+
+
+
+
+
+
+
+
+
+ التفاعل مع التطبيقات الأخرى
+
+ يتيح لك وضع سطح المكتب التفاعل مع نظام التشغيل والتطبيقات المختلفة مع إبقاء أدوات OpenBoard متاحة فوقها.
+
+ ببساطة ما عليك سوى النقر على الأيقونة التالية:
+
+
+
+
+
+
+ استخدم أداة التحديد
+
+ للتفاعل مع سطح المكتب والتطبيقات الأخرى.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/4.html b/resources/startupHints/locales/ar/4.html
new file mode 100644
index 000000000..f432e0db7
--- /dev/null
+++ b/resources/startupHints/locales/ar/4.html
@@ -0,0 +1,79 @@
+
+
+
+
+ وضع المستندات
+
+
+
+
+
+
+
+
+
+
+
+
+ الوصول إلى مدير المستندات
+
+ يوفر OpenBoard مديراً للمستندات . انقر على
+
+ لفتحه.
+
+
+
+
+
+
+
+
+ إنشاء مجلدات وتنظيم عملك
+
+ أنشئ مجلداً باستخدام
+ ,
+ ثم قم بتسميته واسحب مستنداتك وأفلتها داخله.
+ وبالمثل, يمكنك نقل مجلد كامل إلى آخر.
+
+
+
+ مثال على إنشاء المجلدات وتنظيمها.
+
+
+
+
+
+ إدارة الصفحات
+
+ يمكن لمستند OpenBoard أن يحتوي على.عدة صفحات ومن وضع المستندات، يمكنك:
+
+
+ تكرار الصفحات
+ إرسالها إلى سلة المهملات
+ نسخها إلى مستند آخر
+ إنشاء صفحات جديدة من مجلد الصور
+
+
+
+ مثال على إدارة المستندات.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/5.html b/resources/startupHints/locales/ar/5.html
new file mode 100644
index 000000000..cc1ab9b80
--- /dev/null
+++ b/resources/startupHints/locales/ar/5.html
@@ -0,0 +1,102 @@
+
+
+
+
+
+ الاستيراد والتصدير
+
+
+
+
+
+
+
+
+
+
+
+ الاستيراد & التصدير
+
+ في هذا الوضع، تتوفر ميزتان أساسيتان: الاستيراد وَ التصدير .
+
+
+
+
+
+
+
+
+
+ استيراد المحتوى
+
+ يمكنك استيراد ملفات PDF (.pdf ),
+ وَ الصور (.png , .jpg ),
+ وَ مستندات OpenBoard (ubz. ) أو
+ OpenBoard مجلدات (.ubx ) بالنقر على
+ .
+
+
+
+
+
+ مثال على استيراد الملفات إلى OpenBoard.
+
+
+
+ يمكنك أيضاً استيراد مستند OpenBoard (ubz. ) من خلال
+ النقر المزدوج على ملفه من نظام التشغيل. سيُشغَّل OpenBoard عند الحاجة وسيقترح استيراده (أو استبداله إذا كان موجوداً مسبقاً).
+
+
+
+
+
+ يمكن استيرادعدة عناصر دفعة واحدة ,
+ دون الحاجة إلى النقر على زر الاستيراد.
+
+ في كل مرة.
+
+
+
+
+
+
+ تصدير مستنداتك
+
+ كما يمكنك يمكنك تصدير مستند OpenBoard بصيغة PDF أو UBZ ,
+ و مجلد OpenBoard بصيغة UBX . على سبيل المثال:
+
+
+ حفظ العمل المنجز أثناء الدرس ومشاركته مع طالب غائب.
+ مشاركته مع معلمين آخرين أو حفظه على وحدة USB لاستيراده في مكان آخر.
+ استيراد عمل طالب بصيغة PDF، وإضافة الملاحظات عليه، ثم تصدير النسخة المشروحة وإرسالها مجدداً.
+
+
+
+
+ مثال على تصدير الملفات من OpenBoard.
+
+
+
+
+
+ لتصدير لتصدير جميع مستنداتك , اختر أولاً المجلد الرئيسي
+ مستنداتي , ثم انقر على
+ .
+ ستحصل على ملف UBX يمكن استيراده إلى جهاز كمبيوتر آخر، وهو مثالي
+ للنسخ الاحتياطي أو للأرشفة الكاملة!
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/6.html b/resources/startupHints/locales/ar/6.html
new file mode 100644
index 000000000..aeef3c4de
--- /dev/null
+++ b/resources/startupHints/locales/ar/6.html
@@ -0,0 +1,89 @@
+
+
+
+
+ وضع الويب
+
+
+
+
+
+
+
+
+
+
+
+
+ المتصفح المدمج
+
+ وضع الويب هو متصفح مدمج داخل OpenBoard يضيف إلى المتصفح التقليدي ميزات عملية جداً للاستخدام داخل الصف الدراسي.
+
+
+ يتيح لك تصفح الإنترنت دون مغادرة OpenBoard، والتقاط المحتوى (جزء من الشاشة أو الشاشة كاملة)، وحتى إنشاء تطبيقات من مواقع الويب لإعادة استخدامها في مستنداتك.
+
+
+
+
+
+
+
+
+
+ إنشاء تطبيق من موقع ويب
+
+ يمكنك إنشاء تطبيق من أي موقع ويب وإضافته إلى اللوحة والتفاعل معه كما تتفاعل مع التطبيقات المدمجة.
+
+
+ انتقل إلى الموقع المطلوب، ثم انقر على
+
+ ثم أكّد العملية باختيار "إنشاء تطبيق" .
+
+
+
+
+ إنشاء تطبيق من وضع الويب.
+
+
+
+ بعد إنشائه، يُحفَظ التطبيق تلقائياً في
+ مكتبة OpenBoard . ستجده ضمن التطبيقات > الويب
+ ويمكنك إعادة استخدامه في أي مستند.
+
+
+
+
+ العثور على تطبيق تم إنشاؤه في المكتبة
+
+
+
+
+
+ استخدام متصفح خارجي
+
+ يمكنك اختيار فتح الروابط في متصفح خارجي عن طريق تحديد الخيار المناسب في الإعدادات. انقر على
+
+ سينطلق متصفحك المفضل كوضع سطح مكتب.
+
+
+
+
+
+ حتى عند استخدام متصفح خارجي، يمكنك إنشاء تطبيق من موقع ويب: انسخ الرابط إلى شريط العنوان في المتصفح، ثم عد إلى وضع اللوحة والصقه عند إنشاء التطبيق.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/7.html b/resources/startupHints/locales/ar/7.html
new file mode 100644
index 000000000..d7177b9a5
--- /dev/null
+++ b/resources/startupHints/locales/ar/7.html
@@ -0,0 +1,102 @@
+
+
+
+
+ لقطة شاشة
+
+
+
+
+
+
+
+
+
+
+
+ ميزة بسيطة ومفيدة جداً
+
+ تتيح لك لقطة الشاشة إنشاء لقطة فورية لحالة اللوحة (أو شاشتك)
+ أثناء دورتك، لحفظها أو مشاركتها أو إعادة استخدامها.
+
+
+
+
+
+ في وضع اللوحة
+
+ في لوحة أدوات القلم، انقر على
+ ,
+ ثم حدد المنطقة التي تريد التقاطها. بعد ذلك يمكنك اختيار:
+
+
+ إضافة إلى الصفحة الحالية
+ إضافة إلى صفحة جديدة
+
+ إضافة إلى المكتبة — يتم حفظ اللقطة في المجلد الصور
+ للاستخدام المستقبلي.
+
+
+
+
+
+ مثال على إدراج لقطة شاشة في OpenBoard.
+
+
+
+
+
+ لوحة أدوات القلم، معاينة الصفحات وعلامة تبويب المكتبة لا تُلتقط
+ بواسطة السحب: فقط تعليقاتك ومحتواك يُلتقط.
+
+
+
+
+
+
+ في وضع سطح المكتب
+
+ انتقل إلى وضع سطح المكتب عبر
+
+ لالتقاط محتوى من تطبيقات أخرى.
+
+ يتوفر خياران:
+
+
+
+ التقاط الشاشة كاملة
+
+
+
+ التقاط منطقة محددة
+
+
+ كما في وضع اللوحة، اختر المكان الذي تريد إضافة اللقطة إليه.
+
+
+
+ لقطة شاشة كاملة أو جزئية في وضع سطح المكتب.
+
+
+
+
+
+ في وضع الويب
+
+ في وضع الويب يمكنك التقاط جزء من الشاشة أو
+ التقاط علامة التبويب النشطة من المتصفح باستخدام
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/8.html b/resources/startupHints/locales/ar/8.html
new file mode 100644
index 000000000..a2ee6f67d
--- /dev/null
+++ b/resources/startupHints/locales/ar/8.html
@@ -0,0 +1,101 @@
+
+
+
+
+ الصور
+
+
+
+
+
+
+
+
+
+
+
+ الوصول إلى الصور وتنظيمها
+
+ في OpenBoard يمكنك الوصول إلى الصور وإضافتها بطرق مختلفة من خلال المكتبة . تقع المكتبة على الجانب الأيمن من الشاشة، كما يمكنك من خلالها تخزين الأصوات ومقاطع الفيديو والعثورعلى تطبيقات متنوعة.
+
+
+
+ صورة للمكتبة الموجودة على الجانب الأيمن من البرنامج.
+
+
+
+
+
+
+
+
+ إضافة صور من جهاز الكمبيوتر
+
+ يمكنك استيراد ملفات الصور الخاصة بك مباشرة إلى OpenBoard, كما هو موضح أدناه:
+
+
+
+
+ استيراد صورة محلية إلى OpenBoard.
+
+
+
+
+
+ إضافة صور من الويب
+
+ يمكنك أيضاً البحث عن صور مجانية عبر محركات البحث المدمجة,
+ المواقع في المجلد البحث في الويب
+ .
+
+
+
+
+ مثال على العثور على صور من الويب وإضافتها.
+
+
+
+
+
+ لا حاجة للسحب والإفلات: انقر على الصورة التي عثرت عليها لعرض تفاصيلها، ثم استخدم مباشرةً خيار "إضافة إلى المكتبة" .
+ هذه الميزة عملية جداً عند تحضير الدروس.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/9.html b/resources/startupHints/locales/ar/9.html
new file mode 100644
index 000000000..b5130fab6
--- /dev/null
+++ b/resources/startupHints/locales/ar/9.html
@@ -0,0 +1,106 @@
+
+
+
+
+ الأنشطة التفاعلية
+
+
+
+
+
+
+
+
+
+
+
+
+
+ تمارين تفاعلية سهلة التخصيص
+
+ يوفر OpenBoard مجموعة من الأنشطة التفاعلية القابلة للتخصيص، وهي مناسبة للتلاميذ الأصغر سناً وغيرهم، مثل: التصنيف، والحساب الذهني، والتذكر، وغيرها.
+
+
+ يمكن الوصول إليها في المكتبة : انقر على
+ .
+
+
+
+
+
+ مثال: " تصنيف الصور"
+
+ لننشئ تمريناً باستخدام النشاط التفاعلي
+ " تصنيف الصور " :
+ .
+
+
+
+
+ 1) ضع النشاط التفاعلي وافتح المحرر
+
+ اسحب النشاط التفاعلي وأفلته على اللوحة، ثم انقر على "تعديل " .
+
+
+ 2) تسمية الفئات
+
+ أعد تسمية الفئات حسب الحاجة. يمكنك أيضاً
+ إضافة فئات أو حذفها باستخدام أيقونتي “+” و “−”.
+
+
+
+
+ تعديل الفئات: الإضافة، الحذف، وإعادة التسمية.
+
+
+ 3) إضافة الصور
+
+ أضف الصور المناسبة لكل فئة (بالسحب والإفلات، أو بالاختيار من المكتبة، وغير ذلك).
+
+
+
+
+ ربط الصور بالفئات المحددة.
+
+
+ 4) عرض التمرين وتنفيذه
+
+ انقر على "عرض" لبدء النشاط في وضع الطالب.
+
+
+
+
+ تنفيذ التمرين: انقل الصور إلى الفئة الصحيحة.
+
+
+
+
+
+ جرّب ذلك! حرّك هذه النافذة إلى الجانب وأعد تنفيذ المثال على لوحتك.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/ar/error.html b/resources/startupHints/locales/ar/error.html
new file mode 100644
index 000000000..fc9225577
--- /dev/null
+++ b/resources/startupHints/locales/ar/error.html
@@ -0,0 +1,20 @@
+
+
+
+
+ خطأ
+
+
+
+
+
+
+ خطأ في التحميل
+
+ حدث خطأ ما.
+ تحقق من وجود صفحات الإرشادات في المجلد
+ /Resources/startupHints/ .
+
+
+
+
diff --git a/resources/startupHints/locales/de/1.html b/resources/startupHints/locales/de/1.html
index 6319ac5cb..44735348e 100644
--- a/resources/startupHints/locales/de/1.html
+++ b/resources/startupHints/locales/de/1.html
@@ -1,26 +1,95 @@
-
+
-
- Tipps und Tricks
-
-
+
+ Willkommen
+
+
+
-
-
- Willkommen bei OpenBoard
-
-
-
-
- Hier sind einige Tipps und Tricks, die Ihnen helfen sollen, sich mit OpenBoard vertraut zu machen.
- OpenBoard ist ein interaktives Whiteboard, das von Lehrern für Lehrer entwickelt wurde. Es besteht aus vier Modi: dem Boardmodus, dem Desktopmodus, dem Dokumentenmodus und dem Internetmodus.
- Beginnen wir mit dem ersten und wichtigsten: dem Boardmodus.
-
-
- Sie können dieses Fenster jederzeit wieder über die Schaltfläche "Tipps und Tricks" im OpenBoard-Menü ( ) öffnen.
-
+
+
+
+
+
+
+ Hier sind einige Tipps und Tricks, die Ihnen helfen sollen, sich mit OpenBoard vertraut zu machen.
+
+
+
+ OpenBoard ist ein interaktives Whiteboard, das von Lehrern für Lehrer entwickelt wurde.
+ Es bietet vier Modi ergänzend, um Ihre Verwendungsmöglichkeiten im Unterricht abzudecken.
+
+
+
+ Die 4 Modi von OpenBoard
+
+
+
+
+ Beginnen wir mit dem ersten und wichtigsten: Tafelmodus .
+
+
+
+
+
+ Sie konnen dieses Fenster jederzeit wieder offnen uber die Schaltflache
+ "Tipps und Tricks" im Menü OpenBoard
+ .
+
+
+
+
+
+
+
-
diff --git a/resources/startupHints/locales/de/10.html b/resources/startupHints/locales/de/10.html
index c72287117..69d41cbbd 100644
--- a/resources/startupHints/locales/de/10.html
+++ b/resources/startupHints/locales/de/10.html
@@ -1,44 +1,95 @@
-
-
-
-
- Applikationen
-
-
-
-
-
-
-
- OpenBoard bietet verschiedene Apps und Werkzeuge. Sie können auf diese zugreifen, indem Sie auf in der OpenBoard-Bibliothek klicken
- Standard-Apps
- Hier finden Sie geometrische Werkzeuge, einen Taschenrechner, Google Map, einen QR-Code-Generator und vieles mehr! Kombinieren Sie sie, um anregende Lernerfahrungen zu schaffen!
-
- Erstellen Sie Apps
- Wie im Abschnitt Internetmodus erläutert, können Sie eine App von einer Website aus erstellen, indem Sie den internen Browser verwenden oder eine URL mit Kopieren und Einfügen auf das Board einfügen.
- Damit können Sie Ihren Unterricht mit leistungsstarken Online-Tools aufpeppen, die Sie direkt auf dem Board verwenden können! Hier sind einige Beispiele interessanter Apps (Ziehen Sie sie auf das Board, um sie zu testen!) :
-
-
- ... und noch viel mehr!
-
- Benötigen Sie einen leistungsfähigeren Taschenrechner als den, der standardmäßig in OpenBoard enthalten ist? Denken Sie daran! Sie können Ihre eigenen Anwendungen erstellen! Ziehen Sie den folgenden Link per Drag & Drop auf Ihr Board: https://ti89-simulator.com/
-
-
-
-
-
+
+
+
+
+ Anwendungen
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auf Apps zugreifen
+
+ OpenBoard bietet verschiedene Apps und Tools .
+ Finden Sie sie in der Bibliothek, indem Sie auf klicken
+ .
+
+
+
+
+
+ Standard-Apps
+
+ Sie finden geometrische Werkzeuge, einen Taschenrechner, Google Maps, einen QR-Code-Generator und vieles mehr.
+ Kombinieren Sie sie, um spannende Bildungserlebnisse zu schaffen!
+
+
+
+
+ Beispiel für die Verwendung der integrierten Anwendungen OpenBoard.
+
+
+
+
+
+ Erstellen Sie Ihre eigenen Apps
+
+ Wie im Abschnitt erläutert Webmodus , Sie können eine Anwendung von einer Site aus erstellen,
+ über den internen Browser oder durch Kopieren und Einfügen einer URL auf die Pinnwand.
+
+
+ Dadurch können Sie Ihre Kurse mit leistungsstarken Online-Tools erweitern, die direkt in OpenBoard verwendet werden können.
+ Hier sind einige interessante Beispiele (ziehen Sie die Links per Drag-and-Drop auf die Pinnwand, um sie zu testen):
+
+
+
+
+ ...und noch viel mehr!
+
+
+
+
+ Benötigen Sie einen fortgeschritteneren Rechner als OpenBoard? Erstellen Sie Ihr eigenes
+ Anwendung durch Ziehen und Ablegen dieses Links auf die Tabelle:
+ https://ti89-simulator.com/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/11.html b/resources/startupHints/locales/de/11.html
index 0fba2fac1..66516afae 100644
--- a/resources/startupHints/locales/de/11.html
+++ b/resources/startupHints/locales/de/11.html
@@ -1,39 +1,90 @@
-
-
-
-
- Videoaufnahme
-
-
-
-
-
-
-
- Nehmen Sie Ihren Kurs auf
- OpenBoard bietet Ihnen die Möglichkeit, Audio- und Videoaufnahmen von Ihrem Unterricht zu machen.
- Dies kann zum Beispiel nützlich sein, um zusätzliche Übungen oder eine Information über einen Videoclip zu teilen oder eine Unterrichtsstunde aufzuzeichnen, um sie mit abwesenden Schülern zu teilen.
-
- Im Boardmodus werden die Symbolleisten und Paletten nicht im Videoclip erscheinen, sodass Sie sich keine Gedanken darüber machen müssen! Dasselbe gilt für den internen Browser, wo nur die aktive Registerkarte erfasst wird.
-
- Sie können auf dieses Tool wie folgt zugreifen:
-
-
- Sie werden folgende Schnittstelle in der rechten unteren Ecke des Boards sehen:
-
-
- Klicken Sie auf die rote Schaltfläche, um die Aufnahme zu starten.
-
- Sie können die Einstellungen anpassen, indem Sie auf klicken. Dort finden Sie Audioeinstellungen (ein Mikrofon auswählen oder keines), Videoeinstellungen (Auflösung der Videoaufnahme) und konfigurierbare Veröffentlichungsoptionen.
-
- Sobald die Aufnahme beendet ist, wird sie gespeichert und ist auf dem Desktop Ihres Computers verfügbar.
-
-
-
-
-
-
+
+
+
+
+ Videoaufnahme
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Zeichnen Sie Ihren Kurs auf
+
+ OpenBoard ermöglicht Ihnen das Speichern Audio- und die Video Ihres Kurses.
+ Ideal, um zusätzliche Übungen zu teilen, einen kurzen Erklärclip zu veröffentlichen oder
+ eine Lehrveranstaltung abwesenden Studierenden zur Verfügung stellen.
+
+
+
+
+
+ Im Tafelmodus werden Symbolleisten und Paletten im Video nicht angezeigt.
+ In Webmodus , wird nur die aktive Registerkarte erfasst.
+
+
+
+
+
+
+ Greifen Sie auf das Registrierungstool zu
+ Öffnen Sie das Snipping Tool wie unten gezeigt:
+
+
+
+ Schneller Zugriff auf das Registrierungstool über die OpenBoard-Schnittstelle.
+
+
+
+
+
+ Steuerschnittstelle
+ Die Schnittstelle erscheint unten rechts in der Tabelle:
+
+
+
+
+
+ Klicken Sie auf roter Knopf um mit der Aufnahme zu beginnen.
+
+
+
+
+ Passen Sie die Aufnahme über an
+ :
+ Auswahl von Mikrofon (oder keine), Wahl von Videoauflösung und Optionen Veröffentlichung .
+
+
+
+
+
+
+ Beenden Sie das Video und stellen Sie es wieder her
+
+ Sobald die Aufnahme abgeschlossen ist, wird das Video automatisch abgespielt auf dem Desktop gespeichert Ihres Computers.
+
+
+
+
+ Stoppen Sie die Aufnahme und die Videodatei ist auf dem Desktop verfügbar.
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/12.html b/resources/startupHints/locales/de/12.html
index 66b003714..a07b8c7fb 100644
--- a/resources/startupHints/locales/de/12.html
+++ b/resources/startupHints/locales/de/12.html
@@ -1,37 +1,94 @@
-
-
-
-
- Favoriten-Dokumente
-
-
-
-
-
-
-
- OpenBoard-Dokumente zu Favoriten hinzufügen
- Als neue Funktion in Version 1.7 können Sie OpenBoard-Dokumente zu Ihren Favoriten hinzufügen!
- Gehen Sie dazu in den Dokumentenmodus, wählen Sie ein Dokument aus und klicken Sie auf in der Symbolleiste des Dokumentenmodus.
-
-
-
- Schnell von einem Dokument zum anderen wechseln
- Ihre Lieblingsdokumente erscheinen in der OpenBoard-Bibliothek unter
- Jedes dieser OpenBoard-Dokumente ( ) kann dann per Drag & Drop auf das Board gezogen werden!
-
-
- Sie können die Suchleiste am unteren Rand der OpenBoard Bibliothek verwenden, um ein Dokument anhand seines Namens zu finden
-
- Zuletzt geöffnete Dokumente
- Jedes geöffnete Dokument wird vorübergehend zu den Favoriten hinzugefügt, sodass Sie während einer Sitzung schnell zwischen ihnen wechseln können, ohne sie explizit als Favoriten markieren zu müssen.
-
- Wenn Sie ein kürzlich geöffnetes Dokument dauerhaft zu den Favoriten hinzufügen möchten, können Sie dies über den Ordner Favoriten in der OpenBoard Bibliothek tun: Markieren Sie es und klicken Sie auf
-
-
-
-
+
+
+
+
+ Lieblingsdokumente
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Fügen Sie OpenBoard Dokumente zu Ihren Favoriten hinzu
+
+ Eingeführt in die Version 1.7 Mit dieser Funktion können Sie Ihre OpenBoard-Dokumente hinzufügen
+ in Favoriten .
+
+
+ Gehen Sie dazu zu Dokumentenmodus , wählen Sie ein Dokument aus und klicken Sie auf
+
+ in der Symbolleiste.
+
+
+
+
+
+
+
+
+
+
+ Wechseln Sie schnell von einem Dokument zum anderen
+
+ Ihre Lieblingsdokumente werden im angezeigt Bibliothek OpenBoard , unten
+ .
+
+
+ Jedes Lieblingsdokument
+
+ können per Drag & Drop direkt auf den Tisch gezogen werden.
+
+
+
+
+
+
+
+
+
+ Benutzen Sie die Suchleiste unten in der Bibliothek, damit Sie ein Dokument schnell anhand des Namens finden können.
+
+
+
+
+
+
+
+ Kürzlich geöffnete Dokumente
+
+ Jedes geöffnete Dokument wird vorübergehend zu den Favoriten hinzugefügt, um schnell von einem zum anderen wechseln zu können
+ während derselben Sitzung, ohne sie explizit markieren zu müssen.
+
+
+
+
+
+
+
+
+
+
+ Zu machen dauerhaft Um ein kürzlich geöffnetes Dokument anzuzeigen, wählen Sie es im Ordner „Favoriten“ aus
+ und klicken
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/2.html b/resources/startupHints/locales/de/2.html
index ce479061f..c0a566106 100644
--- a/resources/startupHints/locales/de/2.html
+++ b/resources/startupHints/locales/de/2.html
@@ -1,47 +1,122 @@
-
-
-
-
- Board-Modus
-
-
-
-
-
-
-
- Die Stiftpalette
- Mit der Stiftpalette haben Sie Zugriff auf die wichtigsten Werkzeuge, wenn Sie an einem Whiteboard arbeiten.
-
-
- Dort finden Sie den Bleistift ( ), den Radiergummi ( ) und den Textmarker ( ). OpenBoard bietet außerdem Funktionen, die ein herkömmliches Whiteboard nicht bieten kann :
-
- ist der Selektor. Damit können Sie Objekte auswählen und mit ihnen interagieren.
- ist der magische Finger. Sie können Objekte bewegen oder mit ihnen interagieren, ohne dass Sie sie auswählen müssen.
- ist die Hand. Damit können Sie die Seite bewegen. Sehr nützlich, wenn sie mit den Zoomfunktionen kombiniert wird!
- geben Ihnen die Möglichkeit, ein- und auszuzoomen. Wählen Sie einfach den gewünschten Effekt aus und klicken Sie auf die Stelle, auf die Sie ihn anwenden möchten!
- ist ein Laserpointer, der nützlich ist, um auf Elemente auf dem Board zu zeigen, ohne mit diesen zu interagieren.
- wird zum einfachen Zeichnen von geraden Linien verwendet.
- ist eine Textbox, die es ermöglicht, mit der Tastatur statt mit einem Bleistift zu schreiben.
-
-
- Mit der Maus können Sie den Zoom feiner steuern! Verwenden Sie Strg/Befehl + Mausrad, um genauer hinein-/herauszuzoomen!
-
- Die Werkzeugleiste des Boards
- Mit der Werkzeugleiste können Sie unter anderem die Farbe und Größe des Stifts und Markers ändern.
-
-
- Dort finden Sie auch die Möglichkeit, den Hintergrund des Boards zu ändern, indem Sie auf klicken.
-
-
- Außerdem finden Sie hier Funktionen wie Rückgängigmachen/Wiederherstellen, Erstellen und von Seite zu Seite Navigieren, Löschen des Boards, ...
-
- Sie können spezifischere Elemente des Boards vollständig löschen, indem Sie einen langen Klick auf machen. Einige zusätzliche Funktionen erreichen Sie so auch für !
-
-
-
-
+
+
+
+
+ Tafelmodus
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Die Tischbar
+
+ In der Tabellenleiste können Sie die ändern Farbe und/oder die Größe unter anderem Bleistift und Textmarker.
+
+
+
+
+
+
+
+ Sie können auch die ändern Hintergrund der Tabelle indem Sie auf klicken
+ .
+
+
+
+
+
+
+
+ Weitere Funktionen stehen zur Verfügung: rückgängig machen/wiederholen , Seiten erstellen, zwischen Seiten navigieren, die Tabelle löschen usw.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/3.html b/resources/startupHints/locales/de/3.html
index fd31a49f4..ba2604b29 100644
--- a/resources/startupHints/locales/de/3.html
+++ b/resources/startupHints/locales/de/3.html
@@ -1,30 +1,74 @@
-
-
-
-
- Desktop-Modus
-
-
-
-
-
-
-
- Mit anderen Apps interagieren
- Wenn Sie den Desktop-Modus verwenden, können Sie mit Ihrem Betriebssystem und anderer Software interagieren, während OpenBoard darüber liegt !
- Klicken Sie einfach auf das folgende Symbol :
-
- Verwenden Sie den Selektor (
), um mit dem Desktop und anderen Anwendungen zu interagieren.
- Apps oder Webseiten annotieren
- Sie können jede Software mit Anmerkungen versehen, indem Sie den Bleistift (
) oder den Marker (
) verwenden.
-
-
- Sie können auf weitere Optionen für , , und zugreifen, indem Sie sie mit einem langen Klick anklicken oder auf den kleinen schwarzen Pfeil klicken.
-
-
-
-
+
+
+
+
+ Desktop-Modus
+
+
+
+
+
+
+
+
+
+
+
+
+ Interagieren Sie mit anderen Apps
+
+ Der Büromodus ermöglicht Ihnen die Interaktion mit Ihrem Betriebssystem und Ihrer Software,
+ unter Beibehaltung der OpenBoard-Tools oben.
+
+ Klicken Sie einfach auf das folgende Symbol:
+
+
+
+
+
+
+ Benutzen Sie die Wähler
+
+ um mit dem Desktop und anderen Anwendungen zu interagieren.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/4.html b/resources/startupHints/locales/de/4.html
index 08f334715..20175b7a7 100644
--- a/resources/startupHints/locales/de/4.html
+++ b/resources/startupHints/locales/de/4.html
@@ -1,32 +1,79 @@
-
-
-
-
- Dokumenten-Modus
-
-
-
-
-
-
-
- OpenBoard bietet einen Dokumentenmanager. Sie können darauf zugreifen, indem Sie einfach auf klicken.
-
-
- Legen Sie Ordner an und organisieren Sie Ihre Arbeit
- Sie können einen Ordner erstellen, indem Sie auf "Neuer Ordner" klicken. Benennen Sie ihn und ziehen Sie Ihre Dokumente per Drag & Drop hinein. Auf die gleiche Weise können Sie einen ganzen Ordner in einen anderen verschieben.
-
-
- Seitenverwaltung
- Ein OpenBoard-Dokument kann mehrere Seiten enthalten. Über den Dokumentenmodus können Sie sie duplizieren, in den Papierkorb legen oder in ein anderes Dokument kopieren, neue Seiten aus einem Bildordner erstellen, ...
-
-
- Beachten Sie, dass die verfügbaren Aktionen je nachdem, was ausgewählt wird, aktualisiert werden.
-
-
-
-
+
+
+
+
+ Dokumentenmodus
+
+
+
+
+
+
+
+
+
+
+
+
+ Greifen Sie auf den Dokumentenmanager zu
+
+ OpenBoard bietet a Dokumentenmanager . Klicken Sie auf
+
+ um es zu öffnen.
+
+
+
+
+
+
+
+
+ Erstellen Sie Ordner und organisieren Sie Ihre Arbeit
+
+ Erstellen Sie einen Ordner über
+ ,
+ Nennen Sie es dann Drag & Drop Ihre Dokumente darin.
+ Ebenso können Sie einen ganzen Ordner in einen anderen verschieben.
+
+
+
+ Beispiel für das Erstellen und Organisieren von Ordnern.
+
+
+
+
+
+ Seitenverwaltung
+
+ Ein OpenBoard-Dokument kann enthalten mehrere Seiten . Von Dokumentenmodus aus können Sie:
+
+
+ Doppelte Seiten
+ Schicken Sie sie in den Papierkorb
+ Kopieren Sie sie in ein anderes Dokument
+ Erstellen Sie neue Seiten aus einem Bilderordner
+
+
+
+ Beispiel für den Umgang mit Dokumenten.
+
+
+
+
+
+ DER Aktionen verfügbar Passen Sie sich dem an, was ist
+ ausgewählt (Ordner, Dokument, Seite).
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/5.html b/resources/startupHints/locales/de/5.html
index bf51f1176..5a38dff97 100644
--- a/resources/startupHints/locales/de/5.html
+++ b/resources/startupHints/locales/de/5.html
@@ -1,39 +1,105 @@
-
-
-
-
- Dokumenten-Modus
-
-
-
-
-
-
-
- In diesem Modus finden Sie auch zwei sehr wichtige Funktionen: den Import und den Export.
-
-
- Import
- Sie können PDF-Dateien (.pdf ), Bilder (.png , .jpg ), OpenBoard-Dokumente (.ubz ) oder OpenBoard-Ordner (.ubx ) importieren, indem Sie anklicken.
-
- Beachten Sie, dass Sie auch ein OpenBoard-Dokument (.ubz ) importieren können, indem Sie darauf doppelklicken. Dies startet OpenBoard, wenn es nicht bereits gestartet ist, und importiert es (oder schlägt vor, die Datei zu ersetzen, wenn sie bereits vorhanden ist).
- Sie können auch mehrere Elemente auf einmal importieren, ohne dass Sie immer und immer wieder auf klicken müssen.
- Export
- Sie können ein OpenBoard-Dokument im PDF- oder UBZ-Format und einen OpenBoard-Ordner im UBX-Format exportieren. So können Sie zum Beispiel :
-
- Die während einer Unterrichtsstunde geleistete Arbeit speichern und sie mit einem abwesenden Schüler teilen.
- Es mit anderen Lehrern teilen oder auf einem USB-Stick speichern, um es auf einen anderen Computer zu importieren.
- Die Arbeit eines Schülers im PDF-Format importieren, mit Anmerkungen versehen und das mit Anmerkungen versehene Dokument im PDF-Format exportieren, um es an den Schüler zurückzuschicken
-
-
-
-
- Exportieren Sie alle Ihre Dokumente, indem Sie auf den Stammordner "Meine Dokumente" klicken, bevor Sie auf klicken, um sie im UBX-Format zu exportieren. Sie können sie dann auf einem anderen Computer importieren. Dies ist auch eine gute Möglichkeit, ein Archiv oder eine Sicherungskopie Ihrer gesamten Arbeit zu erstellen!
-
-
-
-
+
+
+
+
+
+ Import und Export
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Importieren und Exportieren
+
+ In diesem Modus stehen Ihnen zwei wesentliche Funktionen zur Verfügung: Import Und Export .
+
+
+
+
+
+
+
+
+
+ Inhalte importieren
+
+ Sie können Dateien importieren PDF (.pdf ),
+ des Bilder (.png , .jpg ),
+ des Dokumente OpenBoard (.ubz ) oder
+ OpenBoard Ordner (.ubx ), indem Sie auf klicken
+ .
+
+
+
+
+
+ Beispiel für den Import von Dateien in OpenBoard.
+
+
+
+ Sie können auch ein OpenBoard-Dokument importieren (.ubz ) In
+ doppelklicken darauf von Ihrem System. OpenBoard wird bei Bedarf gestartet und
+ bietet den Import an (oder ersetzt ihn, falls er bereits vorhanden ist).
+
+
+
+
+
+ Es ist möglichImportieren Sie mehrere Elemente gleichzeitig ,
+ ohne erneut zu klicken
+
+ jedes Mal.
+
+
+
+
+
+
+ Exportieren Sie Ihre Dokumente
+
+ Sie können eine exportieren Dokument OpenBoard im Format PDF Oder UBZ ,
+ und a Ordner OpenBoard im Format UBX . Zum Beispiel :
+
+
+ Zeichnen Sie die während einer Unterrichtsstunde geleistete Arbeit auf und teilen Sie sie mit einem abwesenden Schüler.
+ Teilen Sie es mit anderen Lehrern oder speichern Sie es auf einem USB-Stick, um es woanders zu importieren.
+ Importieren Sie die Arbeit eines Schülers als PDF, versehen Sie sie mit Anmerkungen und exportieren Sie dann die kommentierte PDF-Datei zum erneuten Senden.
+
+
+
+
+ Beispiel für den Export von Dateien aus OpenBoard.
+
+
+
+
+
+ Zum Exportieren alle Ihre Dokumente Wählen Sie zunächst den Stammordner aus
+ Meine Dokumente , und klicken Sie dann
+ .
+ Du bekommst ein UBX auf einen anderen Computer importierbar – perfekt für
+ Sicherung oder ein Archiv vollständig!
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/6.html b/resources/startupHints/locales/de/6.html
index f66431dfc..cc12d021f 100644
--- a/resources/startupHints/locales/de/6.html
+++ b/resources/startupHints/locales/de/6.html
@@ -1,38 +1,96 @@
-
-
-
-
- Internet-Modus
-
-
-
-
-
-
-
- Der Internetmodus ist ein interner Browser, der einen traditionelleren Browser um einige sehr interessante Funktionen erweitert.
- Verwendung des internen Browsers
- Mithilfe des internen Browsers haben Sie die Möglichkeit, das Internet zu durchsuchen, ohne OpenBoard zu minimieren oder zu verlassen, mit zusätzlichen Funktionen, die es Ihnen ermöglichen, einen Teil oder den gesamten Bildschirm zu erfassen oder Apps von Websites zu erstellen und sie dem Board hinzuzufügen!
-
-
-
- Eine App erstellen
- Sie können eine App von jeder beliebigen Website aus erstellen, um sie dem Board hinzuzufügen und mit ihr zu interagieren, genau wie mit den Standardanwendungen.
- Gehen Sie dazu auf die Website, die Sie erfassen möchten, klicken Sie auf und bestätigen Sie ihre Erstellung, indem Sie auf "Anwendung erstellen" klicken.
-
-
- Wenn eine Anwendung erstellt wird, wird sie automatisch in der OpenBoard-Bibliothek gespeichert, sodass Sie sie in jedem beliebigen Dokument wiederverwenden können. Sie finden sie unter dem Ordner "Anwendungen" in einem Unterordner namens "Internet".
-
-
-
- Verwendung des externen Browsers
- Sie können auch einen externen Browser verwenden, indem Sie die entsprechende Option in den Einstellungen ankreuzen. Wenn Sie auf klicken, wird Ihr bevorzugter Browser dann im Desktopmodus gestartet.
- Wenn Sie einen externen Browser verwenden, können Sie immer noch eine App von einer Website aus erstellen, indem Sie die URL in der Adresszeile Ihres Browsers kopieren und sie dann einfügen, wenn Sie wieder im Boardmodus sind!
-
-
-
-
+
+
+
+
+ Webmodus
+
+
+
+
+
+
+
+
+
+
+
+
+ Der integrierte Browser
+
+ DER Webmodus ist ein interner Browser von OpenBoard, der zu einem Browser hinzugefügt wird
+ klassische, sehr praktische Features für den Unterricht.
+
+
+ Es ermöglicht Ihnen, im Internet zu surfen, ohne OpenBoard zu verlassen, um Inhalte (teilweise oder teilweise) zu erfassen
+ Vollbild) und sogar Apps erstellen von Websites für
+ Wiederverwendung in Ihren Dokumenten.
+
+
+
+
+
+
+
+
+
+ Erstellen Sie eine Anwendung von einer Site
+
+ Von jeder Site aus können Sie eine erstellen Anwendung um es hinzuzufügen
+ auf dem Board und interagieren Sie damit wie mit den Standardanwendungen.
+
+
+ Gehen Sie zur gewünschten Seite und klicken Sie auf
+
+ Anschließend durch Auswählen bestätigen Erstellen Sie eine App .
+
+
+
+
+ Erstellung einer Anwendung aus dem Webmodus.
+
+
+
+ Nach der Erstellung wird die Anwendung automatisch im gespeichert
+ Bibliothek OpenBoard . Sie finden es weiter unten Anwendungen > Web
+ und kann es in jedem Dokument wiederverwenden.
+
+
+
+
+ Suchen Sie eine in Ihrer Bibliothek erstellte Anwendung.
+
+
+
+
+
+ Verwenden Sie einen externen Browser
+
+ Sie können die Links in einem öffnen externer Browser durch Überprüfung
+ die entsprechende Option in den Einstellungen. Klicken Sie auf
+
+ startet dann Ihren Lieblingsbrowser als Desktop-Modus.
+
+
+
+
+
+ Auch mit einem externen Browser ist das möglich eine App erstellen von einer Website:
+ Kopieren Sie die URL in die Adressleiste des Browsers und kehren Sie zur zurück Tafelmodus und klebe es fest
+ wenn Sie die Anwendung erstellen.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/7.html b/resources/startupHints/locales/de/7.html
index ce1ab539d..36b706a16 100644
--- a/resources/startupHints/locales/de/7.html
+++ b/resources/startupHints/locales/de/7.html
@@ -1,44 +1,102 @@
-
-
-
-
- Bildschirmaufnahme
-
-
-
-
-
-
-
- Eine der grundlegenden, aber wirklich nützlichen Funktionen von OpenBoard ist der Screenshot. Damit können Sie während Ihres Unterrichts einen Schnappschuss von einem beliebigen Zustand des Boards erstellen.
- Im Boardmodus
- Suchen Sie in der Stiftpalette, klicken Sie darauf und wählen Sie den Bereich aus, den Sie erfassen möchten. Anschließend werden Ihnen drei Optionen angeboten :
-
- Zur aktuellen Seite hinzufügen
- Zur neuen Seite hinzufügen
- Zur Bibliothek hinzufügen (fügt den Schnappschuss dem Bilder Ordner hinzu, sodass Sie ihn jederzeit wiederverwenden können)
-
-
- Hier ein Beispiel für den gesamten Prozess :
-
-
- Sie müssen sich keine Gedanken um die Stiftpalette, die Seitenvorschau oder die Registerkarte für die OpenBoard-Bibliothek machen - sie werden nicht von Ihrem Lasso eingefangen!
-
- Im Desktop-Modus
- Dasselbe können Sie im Desktop-Modus tun, um Ihre Arbeit in anderen Programmen zu erfassen. Wechseln Sie in den Desktop-Modus, indem Sie auf klicken.
- Sie finden zwei Symbole: um den gesamten Bildschirm zu erfassen, und um nur einen Teil davon zu erfassen. Wie im Boardmodus müssen Sie auswählen, wo Sie die Aufnahme hinzufügen möchten
-
- Hier eine Illustration des gesamten Prozesses :
-
-
-
- Im Internetmodus
- In ähnlicher Weise ist dies auch im Internetmodus möglich, wo Sie eine Teilaufnahme des Bildschirms machen oder den aktiven Tab des Browsers erfassen können, indem Sie anklicken
-
-
-
-
+
+
+
+
+ Screenshot
+
+
+
+
+
+
+
+
+
+
+
+ Eine einfache und sehr nützliche Funktion
+
+ Mit dem Screenshot können Sie einen erstellen sofort der Zustand des Boards (oder Ihres Bildschirms)
+ während Ihres Kurses, um Inhalte zu archivieren, zu teilen oder wiederzuverwenden.
+
+
+
+
+
+ Im Tafelmodus
+
+ Klicken Sie in der Stiftpalette auf
+ ,
+ Wählen Sie dann den zu erfassenden Bereich aus. Sie können dann wählen:
+
+
+ Zur aktuellen Seite hinzufügen
+ Zu neuer Seite hinzufügen
+
+ Zur Bibliothek hinzufügen — Die Aufnahme wird im Ordner gespeichert Bilder
+ zur späteren Wiederverwendung.
+
+
+
+
+
+ Beispiel für die Einbettung eines Screenshots in OpenBoard.
+
+
+
+
+
+ Die Registerkarte „Stiftpalette“, „Seitenvorschau“ und „Bibliothek“. werden nicht erfasst
+ per Lasso: Nur Ihre Anmerkungen und Ihre Inhalte.
+
+
+
+
+
+
+ In Desktop-Modus
+
+ Wechseln Sie zu Desktop-Modus über
+
+ um andere Software zu erfassen.
+
+ Es stehen zwei Optionen zur Verfügung:
+
+
+
+ Vollbildaufnahme
+
+
+
+ Erfassen eines Bereichs
+
+
+ Wahlen Sie wie im Tafelmodus aus, wo die Aufnahme eingefugt werden soll.
+
+
+
+ Vollständiger oder teilweiser Screenshot in Desktop-Modus.
+
+
+
+
+
+ In Webmodus
+
+ In Webmodus können Sie einen Bereich erobern des Bildschirms bzw
+ Aktive Registerkarte erfassen aus dem Browser mit
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/8.html b/resources/startupHints/locales/de/8.html
index ab34f00a8..b661833c5 100644
--- a/resources/startupHints/locales/de/8.html
+++ b/resources/startupHints/locales/de/8.html
@@ -1,36 +1,102 @@
-
-
-
-
- Bilder
-
-
-
-
-
-
-
- In OpenBoard können Sie auf Bilder auf verschiedene Arten zugreifen.
- Organisieren Sie Ihren Bilder-Ordner
- Screenshots, die der Bibliothek hinzugefügt wurden, finden Sie im Ordner Bilder : Sie können Unterordner erstellen, indem Sie ganz unten in der Bibliothek verwenden. Ziehen Sie dann Ihre Bilder per Drag & Drop in die verschiedenen Ordner, die Sie erstellt haben.
-
-
- Egal, wo Sie sich in der OpenBoard-Bibliothek befinden, die Bilder, die Sie hinzufügen, werden automatisch innerhalb des Bilder-Ordners platziert , so dass die Bibliothek organisiert bleibt.
-
- Fügen Sie Bilder von Ihrem Computer hinzu
- Sie können auch Bilder von Ihrem Computer hinzufügen, wie hier dargestellt :
-
-
- Fügen Sie Bilder aus Suchmaschinen hinzu
- Schließlich können Sie auch nach lizenzfreien Bildern suchen und diese zum Board hinzufügen, indem Sie die Suchmaschinen im Ordner "Websuche" verwenden:
-
-
- Anstatt Drag-and-Drop zu verwenden, klicken Sie einfach auf ein Bild, das als Suchergebnis erscheint, um Details zu sehen und Optionen wie Zur Bibliothek hinzufügen zu finden. Nützlich bei der Vorbereitung einer Unterrichtsstunde!
-
-
-
-
+
+
+
+
+ Bilder
+
+
+
+
+
+
+
+
+
+
+
+ Greifen Sie auf Ihre Bilder zu und organisieren Sie sie
+
+ In OpenBoard können Sie von Ihrem aus auf verschiedene Arten auf Bilder zugreifen und diese hinzufügen Bibliothek . Letzteres befindet sich auf der rechten Seite des Bildschirms. Hier können Sie auch Sounds und Videos speichern und verschiedene Anwendungen finden.
+
+
+
+ Bild der Bibliothek rechts in der Software.
+
+
+
+
+
+
+
+
+ Fügen Sie Bilder von Ihrem Computer hinzu
+
+ Sie können Ihre eigenen Bilddateien direkt in OpenBoard importieren, wie unten gezeigt:
+
+
+
+
+ Importieren eines lokalen Bildes in OpenBoard.
+
+
+
+
+
+ Fügen Sie Bilder aus dem Internet hinzu
+
+ Sie können auch nach suchen lizenzfreie Bilder über integrierte Suchmaschinen,
+ befindet sich im Ordner Websuche
+ .
+
+
+
+
+ Beispiel für das Suchen und Hinzufügen von Bildern aus dem Internet.
+
+
+
+
+
+ Kein Ziehen und Ablegen erforderlich: Klicken Sie auf ein gefundenes Bild, um dessen Details anzuzeigen
+ und direkt die Option nutzen Zur Bibliothek hinzufügen .
+ Das ist bei der Unterrichtsvorbereitung sehr praktisch.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/9.html b/resources/startupHints/locales/de/9.html
index 8ca9d819d..52138850f 100644
--- a/resources/startupHints/locales/de/9.html
+++ b/resources/startupHints/locales/de/9.html
@@ -1,43 +1,99 @@
-
-
-
-
- Interaktivitäten
-
-
-
-
-
-
-
- Für jüngere Schülerinnen und Schüler finden Sie eine Reihe von anpassbaren Anwendungen, die speziell auf diese Zielgruppe zugeschnitten sind.
- Die interaktiven Übungen von OpenBoard
- Mit diesen Interaktivitäten können Sie verschiedene Arten von Übungen erstellen. Dabei kann es sich um Kategorisierung, Kopfrechnen, Auswendiglernen usw. handeln.
- Die Interaktivitäten befinden sich in der OpenBoard-Bibliothek: Klicken Sie auf , um sie zu finden.
-
- Beispiele
- Wir werden eine Übung erstellen, die die Interaktivität "Cat egorize pict ures" (übersetzt: Bilder kategorisieren) verwendet:
- Probieren Sie es aus! Verschieben Sie dieses Fenster auf eine Seite und reproduzieren Sie das Beispiel auf der Pinnwand!
- Zunächst ziehen Sie die Interaktivität per Drag & Drop auf das Board und klicken auf "Bearbeiten".
- Ändern Sie dann die Namen der Kategorien nach Bedarf :
-
-
- Sie können Kategorien mithilfe der Symbole + und - hinzufügen oder entfernen.
-
- Fügen Sie dann die entsprechenden Bilder zu jeder Kategorie hinzu.
-
-
- Klicken Sie schließlich auf "Anzeigen", um das Ergebnis zu sehen und die Übung durchzuführen.
-
-
- Sie können die Übung erneut starten, indem Sie auf das Symbol "Neu laden" klicken.
-
-
-
-
-
-
+
+
+
+
+ Interaktivitäten
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Interaktive Übungen, einfach zu personalisieren
+
+ Für die jüngsten Schüler (und nicht nur) bietet OpenBoard ein Set
+ vonInteraktivitäten anpassbar: Kategorisierung, mentale Berechnung, Auswendiglernen usw.
+
+
+ Sie sind im zugänglich Bibliothek : klicken Sie auf
+ .
+
+
+
+
+
+ Beispiel: „Bilder kategorisieren“
+
+ Lassen Sie uns eine Übung mit Interaktivität erstellen
+ Katze egorisieren Bild ures (Bilder kategorisieren):
+ .
+
+
+
+
+
+ Versuchen! Schieben Sie dieses Fenster zur Seite und reproduzieren Sie das Beispiel auf Ihrem Board.
+
+
+
+ 1) Platzieren Sie die Interaktivität und öffnen Sie den Editor
+
+ Ziehen Sie die Interaktivität per Drag-and-Drop auf das Board und klicken Sie dann Zu ändern .
+
+
+ 2) Benennen Sie die Kategorien
+
+ Benennen Sie die Kategorien nach Bedarf um. Das können Sie auch
+ hinzufügen Oder LÖSCHEN Kategorien mit den Symbolen „+“ und „−“.
+
+
+
+
+ Kategorien bearbeiten: Hinzufügen, Löschen, Umbenennen.
+
+
+ 3) Fügen Sie die Bilder hinzu
+
+ Fügen Sie Bilder entsprechend jeder Kategorie hinzu (Drag & Drop, Auswahl aus der Bibliothek usw.).
+
+
+
+
+ Verknüpfen Sie Bilder mit definierten Kategorien.
+
+
+ 4) Zeigen Sie die Übung und machen Sie sie
+
+ Klicken Sie auf Anzeige um die Aktivität im Studentenmodus zu starten.
+
+
+
+
+ Durchführung der Übung: Verschieben Sie die Bilder in die richtige Kategorie.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/de/css/style.css b/resources/startupHints/locales/de/css/style.css
deleted file mode 100644
index de0ecb4d5..000000000
--- a/resources/startupHints/locales/de/css/style.css
+++ /dev/null
@@ -1,36 +0,0 @@
-*{
- font-family: Arial, Helvetica, sans-serif;
-}
-
-.title
-{
- width:100%;
- color: #6682b5;
- text-align: center;
-}
-
-.file-extension
-{
- background: lightgrey;
-}
-
-.image
-{
- text-align:center;
-}
-
-.image img
-{
- max-width: 600px;
-}
-
-.icon
-{
- vertical-align: middle;
-}
-
-.tip
-{
- font-style: italic;
- font-size: 0.8rem;
-}
diff --git a/resources/startupHints/locales/de/error.html b/resources/startupHints/locales/de/error.html
index e396c93ee..9d4d207f5 100644
--- a/resources/startupHints/locales/de/error.html
+++ b/resources/startupHints/locales/de/error.html
@@ -1,15 +1,20 @@
-
-
-
-
- Fehler
-
-
-
-
-
-Etwas ist schief gelaufen ...
-Überprüfen Sie die Existenz Ihrer Tipps im Ordner
-/resources/startupHints/ …
-
-
+
+
+
+
+ Fehler
+
+
+
+
+
+
+ Fehler beim Laden
+
+ Etwas ist schief gelaufen.
+ Überprüfen Sie, ob im Ordner Tipps-Seiten vorhanden sind
+ /Resources/startupHints/ .
+
+
+
+
diff --git a/resources/startupHints/locales/en/1.html b/resources/startupHints/locales/en/1.html
index af197854a..a2841f8c3 100644
--- a/resources/startupHints/locales/en/1.html
+++ b/resources/startupHints/locales/en/1.html
@@ -1,26 +1,95 @@
-
+
-
- Hints and tips
-
-
+
+ Welcome
+
+
+
-
-
-
-
-
- Here's some hints and tips in order to help you familiarize with OpenBoard.
- OpenBoard is an interactive whiteboard designed by teachers, for teachers. It comes with 4 modes : Board Mode, Desktop Mode, Documents Mode and Web Mode.
- Let's jump in the first, and most important one : the Board Mode.
-
-
- You can reopen the "Hints and tips" dialog at any time, using the dedicated button on the OpenBoard menu ( )
-
+
+
+
+
+
+
+ Here are some tips and tricks to help you get familiar with OpenBoard.
+
+
+
+ OpenBoard is an interactive whiteboard designed by teachers, for teachers.
+ It offers four complementary modes for classroom use.
+
+
+
+ The 4 modes of OpenBoard
+
+
+
+
+ Let's start with the first, and most important: Board Mode .
+
+
+
+
+
+ You can reopen this window at any time via the button
+ "Hints and tips" in the OpenBoard menu
+ .
+
+
+
+
+
+
+
-
diff --git a/resources/startupHints/locales/en/10.html b/resources/startupHints/locales/en/10.html
index e6c8eb617..16159f7d6 100644
--- a/resources/startupHints/locales/en/10.html
+++ b/resources/startupHints/locales/en/10.html
@@ -1,44 +1,95 @@
-
-
-
-
- Applications
-
-
-
-
-
-
-
- OpenBoard comes with several applications and tools. You can access them by clicking on on the OpenBoard Library
- Default applications
- You'll find geometric tools, a calculator, Google Map, a QR code generator and more ! Combine them to create stimulating lessons !
-
- Create applications
- Like explained in the Web Mode section, you can create applications from sites, using the internal navigator, or by copy-pasting urls to the Board.
- This way, you can support your lessons with powerful online tools directly on the Board ! Here's some examples of interesting apps to create (Drag and drop them to the Board to test them !) :
-
-
- ... and much more !
-
- You need a more powerful calculator than the one provided by OpenBoard ? Remember ! You can create your own applications ! Simply drag and drop the following link on the Board : https://ti89-simulator.com/
-
-
-
-
-
+
+
+
+
+ Applications
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Access apps
+
+ OpenBoard offers different apps and tools .
+ Find them in the library by clicking on
+ .
+
+
+
+
+
+ Default apps
+
+ You will find geometric tools, a calculator, Google Maps, a QR code generator and much more.
+ Combine them to create engaging educational experiences!
+
+
+
+
+ Example of using OpenBoard built-in applications.
+
+
+
+
+
+ Create your own apps
+
+ As explained in section Web Mode , you can create an application from a site,
+ using the internal browser or by copying and pasting a URL onto the board.
+
+
+ This allows you to enhance your courses with powerful online tools, which can be used directly in OpenBoard.
+ Here are some interesting examples (drag and drop the links onto the board to test them):
+
+
+
+
+ ...and much more!
+
+
+
+
+ Need a more advanced calculator than OpenBoard? Create your own
+ application by dragging and dropping this link onto the table:
+ https://ti89-simulator.com/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/11.html b/resources/startupHints/locales/en/11.html
index 49a409612..ad4627a64 100644
--- a/resources/startupHints/locales/en/11.html
+++ b/resources/startupHints/locales/en/11.html
@@ -1,39 +1,90 @@
-
-
-
-
- Video Capture
-
-
-
-
-
-
-
- Record your class session
- OpenBoard gives you the ability to make an audio and video capture of your class session.
- This, for example, can be helpful to share additional exercises or information via a video clip, or to record a class session in order to share it with missing students.
-
- In Board mode, the toolbars and palettes won't appear in the video clip, so don't worry about them ! Same in Web Mode, where only the current tab will appear on the capture.
-
- You can open this tool like this :
-
-
- You'll see the following interface appear at the bottom right of the whiteboard :
-
-
- Click on the red button to start recording.
-
- You can adjust settings by clicking on . You'll find audio settings (select a microphone, or none), video settings (resolution of the video capture) and configurable publishing options
-
- Once the capture is done, it will be automatically saved to the computer's desktop
-
-
-
-
-
-
+
+
+
+
+ Video Capture
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Record your course
+
+ OpenBoard allows you to save audio and the video of your course.
+ Ideal for sharing additional exercises, publishing a short explanatory clip or
+ make a course available to absent students.
+
+
+
+
+
+ In Board Mode , toolbars and palettes do not appear in the video.
+ In Web Mode , only the active tab is captured.
+
+
+
+
+
+
+ Access the registration tool
+ Open the Snipping Tool as shown below:
+
+
+
+ Quick access to the registration tool from the OpenBoard interface.
+
+
+
+
+
+ Control interface
+ The interface appears at the bottom right of the Table:
+
+
+
+
+
+ Click on the red button to start recording.
+
+
+
+
+ Customize the recording via
+ :
+ selection of microphone (or none), choice of video resolution and options publication .
+
+
+
+
+
+
+ Finish and recover the video
+
+ Once recording is completed, the video is automatically saved to desktop of your computer.
+
+
+
+
+ Stop recording and video file available on Desktop.
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/12.html b/resources/startupHints/locales/en/12.html
index 00d01f9e7..53b93fece 100644
--- a/resources/startupHints/locales/en/12.html
+++ b/resources/startupHints/locales/en/12.html
@@ -1,37 +1,94 @@
-
-
-
-
- Favorite Documents
-
-
-
-
-
-
-
- Add OpenBoard documents to favorites
- Coming with OpenBoard 1.7, you can add OpenBoard documents to your favorites !
- To do so, go to Documents Mode, select a document and click on in the Documents toolbar.
-
-
-
- Quickly switch between documents
- Your favorite documents will appear in the OpenBoard Library, under
- Each OpenBoard document ( ) can then be dragged and dropped to the Board !
-
-
- You can use the search bar at the bottom of the OpenBoard Library to quickly find a document by its name
-
- Recently open documents
- Every document you open is temporary added to the favorites so you can switch between each one of them during a session, without the need for them to be explicitely marked as favorites.
-
- If you want to permanently add a recently open document in your favorites, you can do so via the OpenBoard Library : select it and click on
-
-
-
-
+
+
+
+
+ Favorite documents
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add OpenBoard documents to favorites
+
+ Introduced into the version 1.7 , this functionality allows you to add your OpenBoard documents
+ in favorites .
+
+
+ To do this, go to Documents Mode , select a document and click
+
+ in the toolbar.
+
+
+
+
+
+
+
+
+
+
+ Quickly move from one document to another
+
+ Your favorite documents appear in the library OpenBoard , below
+ .
+
+
+ Each favorite document
+
+ can be dragged and dropped directly onto the Table.
+
+
+
+
+
+
+
+
+
+
+
+
+ Recently opened documents
+
+ Each open document is temporarily added to favorites, to quickly switch from one to another
+ during the same session, without having to explicitly mark them.
+
+
+
+
+
+
+
+
+
+
+ To make permanent a recently opened document, select it from the Favorites folder
+ and click
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/2.html b/resources/startupHints/locales/en/2.html
index 4ac62998b..b3deb104f 100644
--- a/resources/startupHints/locales/en/2.html
+++ b/resources/startupHints/locales/en/2.html
@@ -1,47 +1,122 @@
-
-
-
-
- Board Mode
-
-
-
-
-
-
-
- The Stylus palette
- The Stylus palette gives you access to essential tools when working on a whiteboard.
-
-
- Here you'll find the pen ( ), the eraser ( ) and the marker ( ). OpenBoard also provides other features a classical whiterboard can't provide :
-
- is the selector. With it, you can select objects and interact with them.
- is the magic finger. You can move objects or interact with them without the need for them to be selected.
- is the hand. You can move through the page with it. Very useful when combined with the zoom features !
- give you the possibility to zoom in and out. Just select the one you want and click on the page, where you want to apply the zoom !
- is a laser pointer, useful to point out elements on board without interacting with them.
- is used to draw straight lines easily.
- is a textbox tool, to write text using the keyboard instead of the pen.
-
-
- You can have a finer control of the zoom with the mouse ! Use Ctrl/Cmd + the mouse wheel to zoom in/out more precisely !
-
- The Board toolbar
- The Board toolbar gives you the possibility to change pen's or marker's color and size, among other things.
-
-
- You'll also find the ability to change the board's background, by clicking on
-
-
- You'll also find buttons to undo/redo actions, create and navigate through pages, clear the entire whiteboard, ...
-
- You can clear more precise parts of the board, by long clicking on . Some hidden features on too !
-
-
-
-
+
+
+
+
+ Board Mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The table bar
+
+ The table bar allows you to change the color and/or the size pencil and highlighter, among other things.
+
+
+
+
+
+
+
+ You can also change the background of the table by clicking on
+ .
+
+
+
+
+
+
+
+ Other functions are available: undo/redo , create pages, navigate between pages, clear the table, etc.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/3.html b/resources/startupHints/locales/en/3.html
index 16e87b4fc..889ebe1af 100644
--- a/resources/startupHints/locales/en/3.html
+++ b/resources/startupHints/locales/en/3.html
@@ -1,30 +1,74 @@
-
-
-
-
- Desktop Mode
-
-
-
-
-
-
-
- Interacting with other softwares
- Using Desktop mode, you can interact with your entire computer and other softwares, while keeping OpenBoard as an overlay !
- Just click on the following icon :
-
- Use the selector (
) to interact with the desktop and other softwares.
- Make annotations on top of an application or a website
- You can add annotations on top of any software, using the pen (
) or the marker (
).
-
-
- You can access to more options for , and by doing a long click on them, or by clicking on the small black arrow.
-
-
-
-
+
+
+
+
+ Desktop Mode
+
+
+
+
+
+
+
+
+
+
+
+
+ Interact with other apps
+
+ The Office mode allows you to interact with your operating system and software,
+ while retaining the OpenBoard tools on top.
+
+ Simply click on the following icon:
+
+
+
+
+
+
+ Use the selector
+
+ to interact with the desktop and other applications.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/4.html b/resources/startupHints/locales/en/4.html
index dbdf7b61d..36cb2bd5c 100644
--- a/resources/startupHints/locales/en/4.html
+++ b/resources/startupHints/locales/en/4.html
@@ -1,32 +1,79 @@
-
-
-
-
- Documents Mode
-
-
-
-
-
-
-
- OpenBoard comes with a documents handler. You can access it by simply clicking on
-
-
- Create folders and organize your work
- You can create a folder by clicking on the "New Folder" icon. Name it, and drag and drop your documents in. The same way, you can move an entire folder in another one.
-
-
- Handle pages
- An OpenBoard document can contain multiple pages. You can duplicate them, move them to trash or to another document, create new ones from folders of images, ...
-
-
- Note that available actions are updated according to what is selected
-
-
-
-
+
+
+
+
+ Documents Mode
+
+
+
+
+
+
+
+
+
+
+
+
+ Access the document manager
+
+ OpenBoard offers a document manager . Click on
+
+ to open it.
+
+
+
+
+
+
+
+
+ Create folders and organize your work
+
+ Create a folder via
+ ,
+ name it, then drag and drop your documents inside.
+ Likewise, you can move an entire folder to another.
+
+
+
+ Example of creating and organizing folders.
+
+
+
+
+
+ Page management
+
+ A OpenBoard document can contain several pages . From Documents Mode, you can:
+
+
+ Duplicate pages
+ Send them to the trash
+ Copy them to another document
+ Create new pages from an images folder
+
+
+
+ Example of document handling.
+
+
+
+
+
+ THE actions available adapt according to what is
+ selected (folder, document, page).
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/5.html b/resources/startupHints/locales/en/5.html
index a412ec34b..c4b08ad5a 100644
--- a/resources/startupHints/locales/en/5.html
+++ b/resources/startupHints/locales/en/5.html
@@ -1,39 +1,105 @@
-
-
-
-
- Documents Mode
-
-
-
-
-
-
-
- You'll also find in this mode two very important features : Import and Export.
-
-
- Import
- You can import PDF files (.pdf ), images (.png , .jpg ), OpenBoard documents (.ubz ) or OpenBoard folders (.ubx ), by clicking on
-
- Note that you can also import an OpenBoard document (.ubz ) by double-clicking on it. It will launch OpenBoard if not already launched, and import it (or ask for replacement if it already exists).
- You can also import multiple elements at a time, without having to click on again and again.
- Export
- You can export an OpenBoard document to PDF or UBZ, and an OpenBoard folder to UBX. Thus, you can, for example :
-
- Save the work done during a class session and share it with a missing student
- Share it with other teachers, or store it on an USB device and open it on another computer
- Import a student's homework in the PDF format, annotate it, and export the annotated PDF to send it back to the student
-
-
-
-
- Export all your documents by selecting the "My documents" folder before clicking on the export button, to export it as a UBX file, and then import it on another computer. It's also a good way to make a backup of your work !
-
-
-
-
+
+
+
+
+
+ Import and export
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Import & Export
+
+ In this mode, you have two essential features: import And export .
+
+
+
+
+
+
+
+
+
+ Import content
+
+ You can import files PDF (.pdf ),
+ of the pictures (.png , .jpg ),
+ of the documents OpenBoard (.ubz ) or
+ OpenBoard folders (.ubx ) by clicking on
+ .
+
+
+
+
+
+ Example of importing files into OpenBoard.
+
+
+
+ You can also import a OpenBoard document (.ubz ) in
+ double-click on it from your system. OpenBoard will launch if necessary and
+ will offer to import (or replace if it already exists).
+
+
+
+
+
+ It is possible toimport multiple items at once ,
+ without clicking again
+
+ every time.
+
+
+
+
+
+
+ Export your documents
+
+ You can export a document OpenBoard in format PDF Or UBZ ,
+ and a folder OpenBoard in format UBX . For example :
+
+
+ Record the work done during a lesson and share it with an absent student.
+ Share with other teachers, or save to a USB key to import elsewhere.
+ Import a student's work as a PDF, annotate it, then export the annotated PDF for resend.
+
+
+
+
+ Example of exporting files from OpenBoard.
+
+
+
+
+
+ To export all your documents , first select the root folder
+ My Documents , then click
+ .
+ You will get a UBX importable to another computer — perfect for
+ backup or a archive complete!
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/6.html b/resources/startupHints/locales/en/6.html
index 615001a33..40790c69c 100644
--- a/resources/startupHints/locales/en/6.html
+++ b/resources/startupHints/locales/en/6.html
@@ -1,38 +1,96 @@
-
-
-
-
- Web Mode
-
-
-
-
-
-
-
- The Web Mode is an internal navigator that adds some cool features to a more standard one.
- Use the internal navigator
- Using the internal navigator, you'll be able to browse the Internet without the need for reducing or exiting OpenBoard, with some additional features giving the ability to capture part of the screen or create applications from sites, and add them to the whiteboard !
-
-
-
- Create an application
- You can create an application from any site, in order to add it to the board and interact with it like with default applications.
- To do so, go to the website you want to capture, click on and confirm the creation by clicking on "Create an application".
-
-
- When an application is created, it is automatically saved in the OpenBoard library, so you can use it in any document. You'll find them on the applications folder, under a dedicated one called "Web".
-
-
-
- Use an external navigator
- You can also choose to use an external navigator, by checking the corresponding option in the preferences. Clicking on the Web icon will then launch your favorite navigator in Desktop Mode.
- Using an external navigator, you will still be able to create applications from a site, by copying the URL in the address bar of your navigator, coming back to Board, and pasting it !
-
-
-
-
+
+
+
+
+ Web Mode
+
+
+
+
+
+
+
+
+
+
+
+
+ The integrated browser
+
+ THE Web Mode is a browser internal to OpenBoard which adds to a browser
+ classic, very practical features for the classroom.
+
+
+ It allows you to browse the Internet without leaving OpenBoard, to capture content (partial or
+ full screen) and even create apps from websites for
+ reuse in your documents.
+
+
+
+
+
+
+
+
+
+ Create an application from a site
+
+ From any site, you can generate a application to add it
+ on the board and interact with it as with the default applications.
+
+
+ Go to the desired site, click on
+
+ then confirm by selecting Create an app .
+
+
+
+
+ Creation of an application from web mode.
+
+
+
+ Once created, the application is automatically saved in the
+ library OpenBoard . You will find it under Applications > Web
+ and can reuse it in any document.
+
+
+
+
+ Find an application created in your library.
+
+
+
+
+
+ Use an external browser
+
+ You can choose to open the links in a external browser by checking
+ the corresponding option in the preferences. Click on
+
+ will then launch your favorite browser as Desktop Mode.
+
+
+
+
+
+ Even with an external browser, you can create an app from a site:
+ copy the URL into the browser address bar, return to the Board Mode and stick it
+ when you create the application.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/7.html b/resources/startupHints/locales/en/7.html
index bdf8e0478..dca846742 100644
--- a/resources/startupHints/locales/en/7.html
+++ b/resources/startupHints/locales/en/7.html
@@ -1,44 +1,102 @@
-
-
-
-
- Screen Capture
-
-
-
-
-
-
-
- One of the simplest but really useful features of OpenBoard is screen capture. With it, you can create a snapshot of any particular state of the Board, during your class session.
- In Board Mode
- Search for in the Stylus palette, click on it and select the area to capture. Then, you'll have three options :
-
- Add to current page
- Add in a new page
- Add to library (adds the capture to the Pictures folder, so you can reuse it at any time)
-
-
- Here's an example of the whole process :
-
-
- You don't have to worry about the Stylus palette, the Board's thumbnails view or the OpenBoard Library, they won't be captured by your lasso !
-
- In Desktop Mode
- You can do the same thing in Desktop Mode, to capture your work on other softwares. Go to Desktop Mode by clicking on
- You'll find two icons : to capture the whole screen, and to capture just a part of it. Like in Board Mode, you'll have to choose where to drop the capture you made
-
- Here's an illustration of the whole process
-
-
-
- In Web Mode
- Again, the same process is available in Web Mode, where you will be able to capture just a part of the screen, or capture the current tab with
-
-
-
-
+
+
+
+
+ Screenshot
+
+
+
+
+
+
+
+
+
+
+
+ A simple and very useful feature
+
+ Screenshot allows you to create a instant the state of the board (or your screen)
+ during your course, to archive, share or reuse content.
+
+
+
+
+
+ In Board Mode
+
+ In the Pen palette, click
+ ,
+ then select the area to capture. You can then choose:
+
+
+ Add to current page
+ Add to new page
+
+ Add to library — the capture is saved in the folder Pictures
+ for later reuse.
+
+
+
+
+
+ Example of embedding a screenshot in OpenBoard.
+
+
+
+
+
+ The pen palette, page preview and library tab are not captured
+ by lasso: only your annotations and your content are.
+
+
+
+
+
+
+ In Desktop Mode
+
+ Switch to Desktop Mode via
+
+ to capture other software.
+
+ Two options are available:
+
+
+
+ Full screen capture
+
+
+
+ Capturing an area
+
+
+ As in Board Mode, choose where to add the capture.
+
+
+
+ Full or partial screenshot in Desktop Mode.
+
+
+
+
+
+ In Web Mode
+
+ In Web Mode you can capture an area of the screen or
+ capture active tab from the browser with
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/8.html b/resources/startupHints/locales/en/8.html
index 358f17038..d4a3c2a78 100644
--- a/resources/startupHints/locales/en/8.html
+++ b/resources/startupHints/locales/en/8.html
@@ -1,36 +1,102 @@
-
-
-
-
- Images
-
-
-
-
-
-
-
- In OpenBoard, you can have access to images in several ways.
- Organize your Pictures folder
- Screen captures added to the Library are saved to the Pictures folder : You can create folders using at the bottom of the Library. Then, drag and drop your images in the different folders you created.
-
-
- No matter where you are in the OpenBoard Library, images you add will be automatically placed inside the Pictures folder, to keep things organized.
-
- Add images from your computer
- You can also add images directly from your computer, like illustrated below :
-
-
- Add images from the search engines
- Last but not least, you can search and add to your board royalty free images, using the search engines located in the Web Search folder :
-
-
- Instead of using drag and drop, just click on one of the images returned by your search, to see details about the image, and find an option to add it to the Library, without adding it to your current document. Useful when preparing a lesson !
-
-
-
-
+
+
+
+
+ Pictures
+
+
+
+
+
+
+
+
+
+
+
+ Access and organize your images
+
+ In OpenBoard you can access and add images in different ways from your library . The latter is located on the right of the screen. This is also where you can store sounds, videos and find different applications.
+
+
+
+ Image of the library located on the right in the software.
+
+
+
+
+
+
+
+
+ Add images from your computer
+
+ You can import your own image files directly into OpenBoard, as shown below:
+
+
+
+
+ Importing a local image into OpenBoard.
+
+
+
+
+
+ Add images from the web
+
+ You can also search for royalty free images via integrated search engines,
+ located in the folder Web Search
+ .
+
+
+
+
+ Example of finding and adding images from the web.
+
+
+
+
+
+ No need to drag and drop: click on a found image to view its details
+ and directly use the option Add to library .
+ This is very practical when preparing lessons.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/9.html b/resources/startupHints/locales/en/9.html
index f9fee4aee..c0b5935a4 100644
--- a/resources/startupHints/locales/en/9.html
+++ b/resources/startupHints/locales/en/9.html
@@ -1,43 +1,99 @@
-
-
-
-
- Interactivities
-
-
-
-
-
-
-
- For younger students, you'll find a dedicated set of customizable applications.
- Interactive exercices of OpenBoard
- Using these interactivities, you can create different kinds of custom exercices. These can be about categorization, calculation, memorization, and so on.
- Interactivites are located in the OpenBoard Library : click on to find them.
-
- Example
- As an example, we'll create an exercise using the "Cat egorize pict ures" interactivity :
- Try it ! Move this dialog on a side and reproduce the example on the Board !
- First, drag and drop the interactivity on your board, and click on "Edit"
- Then, change the name of the categories to your needs :
-
-
- You can add or delete categories using the + and - icons
-
- Then, add the images you want in the corresponding category.
-
-
- Finally, Click on "Display" to show the result and do the exercise.
-
-
- You can restart the exercise using the "Reload" icon.
-
-
-
-
-
-
+
+
+
+
+ Interactivities
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Interactive exercises, easy to personalize
+
+ For the youngest students (and not only), OpenBoard provides a set
+ ofinteractivities customizable: categorization, mental calculation, memorization, etc.
+
+
+ They are accessible in the library : click on
+ .
+
+
+
+
+
+ Example: “Categorize Pictures”
+
+ Let’s create an exercise with interactivity
+ cat egorize pict ures (categorize images):
+ .
+
+
+
+
+ 1) Place interactivity and open the editor
+
+ Drag and drop the interactivity onto the Board, then click To modify .
+
+
+ 2) Name the categories
+
+ Rename the categories as needed. You can also
+ add Or DELETE categories with “+” and “−” icons.
+
+
+
+
+ Editing categories: addition, deletion, renaming.
+
+
+ 3) Add the images
+
+ Add images corresponding to each category (drag and drop, selection from library, etc.).
+
+
+
+
+ Associate images with defined categories.
+
+
+ 4) Show and do the exercise
+
+ Click on Display to start the activity in student mode.
+
+
+
+
+ Execution of the exercise: move the images into the correct category.
+
+
+
+
+
+ For relaunch exercise, use the icon Reload .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/en/css/style.css b/resources/startupHints/locales/en/css/style.css
deleted file mode 100644
index de0ecb4d5..000000000
--- a/resources/startupHints/locales/en/css/style.css
+++ /dev/null
@@ -1,36 +0,0 @@
-*{
- font-family: Arial, Helvetica, sans-serif;
-}
-
-.title
-{
- width:100%;
- color: #6682b5;
- text-align: center;
-}
-
-.file-extension
-{
- background: lightgrey;
-}
-
-.image
-{
- text-align:center;
-}
-
-.image img
-{
- max-width: 600px;
-}
-
-.icon
-{
- vertical-align: middle;
-}
-
-.tip
-{
- font-style: italic;
- font-size: 0.8rem;
-}
diff --git a/resources/startupHints/locales/en/error.html b/resources/startupHints/locales/en/error.html
index f998df943..2e4c100ee 100644
--- a/resources/startupHints/locales/en/error.html
+++ b/resources/startupHints/locales/en/error.html
@@ -1,15 +1,20 @@
-
-
-
-
- erreur
-
-
-
-
-
-Quelque chose s'est mal passé ...
-Vérifier l'existence de vos conseils dans le dossier
-/Resources/startupHints/ …
-
-
+
+
+
+
+ Error
+
+
+
+
+
+
+ Loading error
+
+ Something went wrong.
+ Check the presence of tips pages in the folder
+ /Resources/startupHints/ .
+
+
+
+
diff --git a/resources/startupHints/locales/fr/1.html b/resources/startupHints/locales/fr/1.html
index a497619ff..6bf6bebde 100644
--- a/resources/startupHints/locales/fr/1.html
+++ b/resources/startupHints/locales/fr/1.html
@@ -1,26 +1,95 @@
-
-
-
-
- Trucs et astuces
-
-
-
-
-
-
- Bienvenue sur OpenBoard
-
-
-
-
- Voici quelques trucs et astuces pour vous aider à vous familiariser avec OpenBoard.
- OpenBoard est un tableau blanc interactif pensé par des enseignants, pour des enseignants. Il est composé de 4 modes : le mode Tableau, le mode Bureau, le mode Documents et le mode Web.
- Commençons par le premier, et le plus important : le mode Tableau.
-
-
- Vous pouvez réouvrir à tout moment cette fenêtre via le bouton "Trucs et astuces" dans le menu OpenBoard ( )
-
-
-
-
+
+
+
+
+ Bienvenue
+
+
+
+
+
+
+
+
+
+
+
+ Voici quelques trucs et astuces pour vous aider à vous familiariser avec OpenBoard.
+
+
+
+ OpenBoard est un tableau blanc interactif pensé par des enseignants, pour des enseignants.
+ Il propose quatre modes complémentaires pour couvrir vos usages en classe.
+
+
+
+ Les 4 modes d’OpenBoard
+
+
+
+
+ Commençons par le premier, et le plus important : le mode Tableau .
+
+
+
+
+
+ Vous pouvez rouvrir à tout moment cette fenêtre via le bouton
+ « Trucs et astuces » dans le menu OpenBoard
+ .
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/10.html b/resources/startupHints/locales/fr/10.html
index 926cd2566..203e6fc84 100644
--- a/resources/startupHints/locales/fr/10.html
+++ b/resources/startupHints/locales/fr/10.html
@@ -1,44 +1,95 @@
-
+
-
- Applications
-
-
+
+ Applications
+
+
+
+
-
-
- OpenBoard propose différentes applications et outils. Vous pouvez y accéder en cliquant sur dans la bibliothèque OpenBoard
- Applications par défaut
- Vous y trouverez des outils géométriques, une calculatrice, Google Maps, un générateur de code QR et bien plus ! Combinez-les pour créer des expériences pédagogiques stimulantes !
-
- Créez des applications
- Comme expliqué dans la section Mode Web, vous pouvez créer une application depuis un site, en utilisant le navigateur interne, ou en copiant-collant une URL sur le tableau.
- Grâce à cela, vous pouvez agrémenter vos cours avec des outils en ligne puissants, utilisables directement sur le tableau ! Voici quelques illustrations d'applications intéressantes (Glissez-déposez les sur le tableau pour les tester !) :
-
-
- ... et bien plus !
-
- Vous avez besoin d'une calculatrice plus puissante que celle fournie par défaut dans OpenBoard ? Souvenez-vous ! Vous pouvez créer vos propres applications ! Glissez-déposez le lien suivant sur votre tableau : https://ti89-simulator.com/
-
-
-
+
+
+
+
+
+
+ Accéder aux applications
+
+ OpenBoard propose différentes applications et outils .
+ Retrouvez-les dans la bibliothèque en cliquant sur
+ .
+
+
+
+
+
+ Applications par défaut
+
+ Vous y trouverez des outils géométriques, une calculatrice, Google Maps, un générateur de QR codes et bien plus.
+ Combinez-les pour créer des expériences pédagogiques stimulantes !
+
+
+
+
+ Exemple d’utilisation des applications intégrées d’OpenBoard.
+
+
+
+
+
+ Créez vos propres applications
+
+ Comme expliqué dans la section Mode Web , vous pouvez créer une application à partir d’un site,
+ en utilisant le navigateur interne ou en copiant-collant une URL sur le tableau.
+
+
+ Cela vous permet d’agrémenter vos cours avec des outils en ligne puissants, utilisables directement dans OpenBoard.
+ Voici quelques exemples intéressants (glissez-déposez les liens sur le tableau pour les tester) :
+
+
+
+
+ ... et bien plus encore !
+
+
+
+
+ Vous avez besoin d’une calculatrice plus avancée que celle d’OpenBoard ? Créez votre propre
+ application en glissant-déposant ce lien sur le tableau :
+ https://ti89-simulator.com/
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/11.html b/resources/startupHints/locales/fr/11.html
index 6aa7a7f1d..b94572e5d 100644
--- a/resources/startupHints/locales/fr/11.html
+++ b/resources/startupHints/locales/fr/11.html
@@ -1,39 +1,90 @@
-
+
-
- Capture Vidéo
-
-
+
+ Capture Vidéo
+
+
+
+
-
-
- Enregistrez votre cours
- OpenBoard vous offre la possibilité de faire une capture audio et vidéo de votre cours.
- Cela peut, par exemple, être utile pour partager des exercices additionnels ou une information via un clip vidéo, ou encore enregistrer un cours afin de le partager avec des élèves absents.
-
- En mode tableau, les barres d'outils et palettes n'apparaîtront pas dans le clip vidéo, donc vous n'avez pas à vous en soucier ! Idem avec le navigateur interne, où seul l'onglet actif sera capturé.
-
- Vous pouvez accéder à cet outil comme ceci :
-
-
- Vous verrez apparaître l'interface suivante en bas à droite du tableau :
-
-
- Cliquez sur le bouton rouge pour commencer l'enregistrement.
-
- Vous pouvez ajuster les paramètres en cliquant sur . Vous y trouverez des paramètres audio (sélectionner un micro, ou aucun), des paramètres vidéo (résolution de la capture vidéo) et des options de publication configurables
-
- Une fois l'enregistrement terminé, la capture sera sauvegardée et disponible sur le bureau de votre ordinateur
-
-
-
-
+
+
+
+
+
+
+ Enregistrez votre cours
+
+ OpenBoard permet d’enregistrer l’audio et la vidéo de votre cours.
+ Idéal pour partager des exercices additionnels, publier un court clip explicatif ou
+ mettre un cours à disposition des élèves absents.
+
+
+
+
+
+ En Mode Tableau , les barres d’outils et palettes n’apparaissent pas dans la vidéo.
+ En Mode Web , seul l’onglet actif est capturé.
+
+
+
+
+
+
+ Accéder à l’outil d’enregistrement
+ Ouvrez l’outil de capture comme illustré ci-dessous :
+
+
+
+ Accès rapide à l’outil d’enregistrement depuis l’interface d’OpenBoard.
+
+
+
+
+
+ Interface de contrôle
+ L’interface apparaît en bas à droite du Tableau :
+
+
+
+
+
+ Cliquez sur le bouton rouge pour lancer l’enregistrement.
+
+
+
+
+ Personnalisez l’enregistrement via
+ :
+ sélection du micro (ou aucun), choix de la résolution vidéo et options de publication .
+
+
+
+
+
+
+ Terminer et récupérer la vidéo
+
+ Une fois l’enregistrement terminé, la vidéo est automatiquement enregistrée sur le Bureau de votre ordinateur.
+
+
+
+
+ Arrêt de l’enregistrement et fichier vidéo disponible sur le Bureau.
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/12.html b/resources/startupHints/locales/fr/12.html
index ed111ba77..8a536de55 100644
--- a/resources/startupHints/locales/fr/12.html
+++ b/resources/startupHints/locales/fr/12.html
@@ -1,37 +1,94 @@
-
+
-
- Documents favoris
-
-
+
+ Documents favoris
+
+
+
+
-
-
- Ajouter des documents OpenBoard aux favoris
- Nouvelle fonctionnalité de la version 1.7, vous pouvez ajouter des documents OpenBoard à vos favoris !
- Pour ce faire, allez en mode Documents, sélectionnez un document et cliquez sur dans la la barre d'outils du mode Documents.
-
-
-
- Passez rapidement d'un document à l'autre
- Vos documents favoris apparaîtront dans la bibliothèque OpenBoard, sous
- Chacun de ces documents OpenBoard ( ) peut ensuite être glissé-déposé sur le tableau !
-
-
- Vous pouvez utiliser la barre de recherche située en bas de la bibliothèque OpenBoard pour retrouver un document à partir de son nom
-
- Documents récemment ouverts
- Chaque document ouvert sera ajouté temporairement aux favoris afin que vous puissiez passer rapidement de l'un à l'autre durant une même session, sans qu'il soit nécessaire de les marquer explicitement comme favoris.
-
- Si vous voulez ajouter de façon permanente un document récemment ouvert aux favoris, vous pouvez le faire via le dossier Favoris de la bibliothèque OpenBoard : sélectionnez-le et cliquez sur
-
-
+
+
+
+
+
+
+ Ajouter des documents OpenBoard aux favoris
+
+ Introduite dans la version 1.7 , cette fonctionnalité permet d’ajouter vos documents OpenBoard
+ en favoris .
+
+
+ Pour cela, passez en Mode Documents , sélectionnez un document et cliquez sur
+
+ dans la barre d’outils.
+
+
+
+
+
+
+
+
+
+
+ Passer rapidement d’un document à l’autre
+
+ Vos documents favoris apparaissent dans la bibliothèque OpenBoard , sous
+ .
+
+
+ Chaque document favori
+
+ peut être glissé-déposé directement sur le Tableau.
+
+
+
+
+
+
+
+
+
+ Utilisez la barre de recherche en bas de la bibliothèque afin de pouvoir retrouver rapidement un document par son nom.
+
+
+
+
+
+
+
+ Documents récemment ouverts
+
+ Chaque document ouvert est ajouté temporairement aux favoris, pour passer rapidement de l’un à l’autre
+ au cours d’une même session, sans devoir les marquer explicitement.
+
+
+
+
+
+
+
+
+
+
+ Pour rendre permanent un document récemment ouvert, sélectionnez-le dans le dossier Favoris
+ et cliquez sur
+ .
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/2.html b/resources/startupHints/locales/fr/2.html
index 81f24e5c0..2e937325a 100644
--- a/resources/startupHints/locales/fr/2.html
+++ b/resources/startupHints/locales/fr/2.html
@@ -1,46 +1,122 @@
-
+
-
- Mode Tableau
-
-
+
+ Mode Tableau
+
+
+
-
-
- La palette des stylets
- La palette des stylets vous donne accès à des outils essentiels quand on travaille sur un tableau blanc.
-
-
- Vous y trouverez le crayon ( ), la gomme ( ) et le surligneur ( ). OpenBoard fournit également des fonctionnalités qu'un tableau blanc classique ne peut pas fournir :
-
- est le sélecteur. Avec, vous pouvez sélectionner et interagir avec des objets.
- est le doigt magique. Vous pouvez déplacer des objets ou interagir avec eux sans qu'il soit nécessaire de les sélectionner.
- est la main. Vous pouvez déplacer la page avec. Très utile quand combinée avec les fonctionnalités de zoom !
- vous donnent la possibilité de zoomer et dézoomer. Sélectionnez simplement l'effet désiré, et cliquer à l'endroit où vous souhaitez l'appliquer !
- est un pointeur laser, utile pour pointer des éléments sur le tableau sans interagir avec ces derniers.
- est utilisé pour tracer des droites facilement.
- est une boîte de texte, permettant d'écrire au clavier plutôt qu'au crayon.
-
-
- Vous pouvez avoir un contrôle plus fin du zoom avec la souris ! Utilisez Ctrl/Cmd + la molette de la souris afin de zoomer/dézoomer avec plus de précision !
- La barre du tableau
- La barre du tableau vous permet de changer la couleur et/ou la taille du crayon et marqueur, entre autres choses.
-
-
- Vous y trouverez également la possibilité de changer le fond du tableau en cliquant sur
-
-
- Vous y trouverez aussi des fonctionnalités comme annuler/rétablir, créer et naviguer de pages en pages, effacer le tableau, ...
-
- Vous pouvez effacer entièrement des éléments plus spécifiques du tableau, en faisant un clic long sur . Quelques fonctionnalités supplémentaires accessibles également pour !
-
-
+
+
+
+
+
+
+
+
+ La barre du tableau
+
+ La barre du tableau vous permet de changer la couleur et/ou la taille du crayon et du surligneur, entre autres choses.
+
+
+
+
+
+
+
+ Vous pouvez aussi changer le fond du tableau en cliquant sur
+ .
+
+
+
+
+
+
+
+ D’autres fonctions sont disponibles : annuler/rétablir , créer des pages, naviguer entre les pages, effacer le tableau, etc.
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/3.html b/resources/startupHints/locales/fr/3.html
index 0921ed8e8..256a75d69 100644
--- a/resources/startupHints/locales/fr/3.html
+++ b/resources/startupHints/locales/fr/3.html
@@ -1,30 +1,74 @@
-
+
-
- Mode Bureau
-
-
+
+ Mode Bureau
+
+
+
+
-
-
- Interagir avec d'autres applications
- En utilisant le mode Bureau, vous pouvez interagir avec votre système d'exploitation et d'autres logiciels, tout en conservant OpenBoard par dessus !
- Cliquez simplement sur l'icône suivante :
-
- Utilisez le sélecteur (
) pour interagir avec le bureau et les autres applications.
- Annoter des applications ou des sites web
- Vous pouvez annoter n'importe quel logiciel, en utilisant le crayon (
) ou le marqueur (
).
-
-
- Vous pouvez accéder à plus d'options pour , et en faisant en clic long sur eux, ou en cliquant sur la petite flèche noire.
-
-
+
+
+
+
+
+ Interagir avec d’autres applications
+
+ Le mode Bureau vous permet d’interagir avec votre système d’exploitation et vos logiciels,
+ tout en conservant les outils d’OpenBoard par-dessus.
+
+ Cliquez simplement sur l’icône suivante :
+
+
+
+
+
+
+ Utilisez le sélecteur
+
+ pour interagir avec le bureau et les autres applications.
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/4.html b/resources/startupHints/locales/fr/4.html
index cc87807d7..2dc8ec7fe 100644
--- a/resources/startupHints/locales/fr/4.html
+++ b/resources/startupHints/locales/fr/4.html
@@ -1,32 +1,79 @@
-
+
-
- Mode Documents
-
-
+
+ Mode Documents
+
+
+
+
-
-
- OpenBoard propose un gestionnaire de documents. Vous pouvez y accéder en cliquant simplement sur
-
-
- Créez des dossiers et organisez votre travail
- Vous pouvez créer un dossier en cliquant sur . Nommez-le, et glissez-déposez y vos documents. De la même façon, vous pouvez déplacer un dossier entier à l'intérieur d'un autre.
-
+
+
+
+
+
+ Accéder au gestionnaire de documents
+
+ OpenBoard propose un gestionnaire de documents . Cliquez sur
+
+ pour l’ouvrir.
+
+
+
+
+
+
+
+
+ Créez des dossiers et organisez votre travail
+
+ Créez un dossier via
+ ,
+ nommez-le, puis glissez-déposez vos documents à l’intérieur.
+ De la même façon, vous pouvez déplacer un dossier entier dans un autre.
+
+
+
+ Exemple de création et d'organisation de dossiers.
+
+
+
+
+
+ Gestion des pages
+
+ Un document OpenBoard peut contenir plusieurs pages . Depuis le Mode Documents, vous pouvez :
+
+
+ Dupliquer des pages
+ Les envoyer à la corbeille
+ Les copier vers un autre document
+ Créer de nouvelles pages à partir d’un dossier d’images
+
+
+
+ Exemple de manipulation de documents.
+
- Gestion des pages
- Un document OpenBoard peut contenir plusieurs pages. Via le mode Documents, vous pouvez les dupliquer, les mettre à la corbeille ou les copier vers un autre document, en créer de nouvelles à partir d'un dossier d'images, ...
-
-
- À noter que les actions disponibles sont mises à jour en fonction de ce qui est sélectionné.
-
-
-
+
diff --git a/resources/startupHints/locales/fr/5.html b/resources/startupHints/locales/fr/5.html
index d379cad55..93eb11579 100644
--- a/resources/startupHints/locales/fr/5.html
+++ b/resources/startupHints/locales/fr/5.html
@@ -1,39 +1,105 @@
-
+
+
-
- Mode Documents
-
-
+
+ Importer et exporter
+
+
+
+
-
-
- Vous trouverez également dans ce mode deux fonctionnalités très importantes : l'import et l'export.
-
-
- Import
- Vous pouvez importer des fichiers PDF (.pdf ), des images (.png , .jpg ), des documents OpenBoard (.ubz ) ou des dossiers OpenBoard (.ubx ), en cliquant sur
-
- À noter que vous pouvez aussi importer un document OpenBoard (.ubz ) en double-cliquant dessus. Cela lancera OpenBoard s'il n'est pas déjà lancé, et l'importera (ou proposera un remplacement du fichier si déjà existant).
- Vous pouvez également importer plusieurs éléments à la fois, sans qu'il soit nécessaire de cliquer sur encore et encore.
- Export
- Vous pouvez exporter un document OpenBoard au format PDF ou UBZ, et un dossier OpenBoard au format UBX. Ainsi, vous pouvez, par exemple :
-
- Enregistrer le travail fait durant un cours, et le partager avec un élève absent.
- Le partager avec d'autres enseignants, ou le sauvegarder sur une clé USB pour l'importer sur un autre ordinateur.
- Importer le travail d'un élève au format PDF, l'annoter, et exporter le document annoté au format PDF pour le renvoyer à l'élève
-
-
-
-
- Exporter tous vos documents en cliquant sur le dossier racine "Mes Documents", avant de cliquer sur , pour les exporter au format UBX. Vous pourrez alors les importer sur un autre ordinateur. C'est aussi un bon moyen d'effectuer une archive ou une sauvegarde de tout votre travail !
-
-
+
+
+
+
+
+
+ Import & Export
+
+ Dans ce mode, vous disposez de deux fonctionnalités essentielles : l’import et l’export .
+
+
+
+
+
+
+
+
+
+ Importer des contenus
+
+ Vous pouvez importer des fichiers PDF (.pdf ),
+ des images (.png , .jpg ),
+ des documents OpenBoard (.ubz ) ou des
+ dossiers OpenBoard (.ubx ) en cliquant sur
+ .
+
+
+
+
+
+ Exemple d'importation de fichiers dans OpenBoard.
+
+
+
+ Vous pouvez aussi importer un document OpenBoard (.ubz ) en
+ double-cliquant dessus depuis votre système. OpenBoard se lancera si nécessaire et
+ vous proposera d’importer (ou de remplacer s’il existe déjà).
+
+
+
+
+
+ Il est possible d’importer plusieurs éléments en une seule fois ,
+ sans recliquer sur
+
+ à chaque fois.
+
+
+
+
+
+
+ Exporter vos documents
+
+ Vous pouvez exporter un document OpenBoard au format PDF ou UBZ ,
+ et un dossier OpenBoard au format UBX . Par exemple :
+
+
+ Enregistrer le travail fait durant un cours et le partager à un élève absent.
+ Partager à d’autres enseignants, ou sauvegarder sur une clé USB pour l’importer ailleurs.
+ Importer le travail d’un élève en PDF, l’annoter, puis exporter le PDF annoté pour le renvoyer.
+
+
+
+
+ Exemple d'exportation de fichiers depuis OpenBoard.
+
+
+
+
+
+ Pour exporter tous vos documents , sélectionnez d’abord le dossier racine
+ Mes Documents , puis cliquez sur
+ .
+ Vous obtiendrez un UBX importable sur un autre ordinateur — parfait pour une
+ sauvegarde ou une archive complète !
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/6.html b/resources/startupHints/locales/fr/6.html
index 4a444dec9..21a9cd726 100644
--- a/resources/startupHints/locales/fr/6.html
+++ b/resources/startupHints/locales/fr/6.html
@@ -1,38 +1,96 @@
-
+
-
- Mode Web
-
-
+
+ Mode Web
+
+
+
+
-
-
- Le mode Web est un navigateur interne qui ajoute à un navigateur plus traditionnel des fonctionnalités très intéressantes.
- Utilisation du navigateur interne
- En utilisant le navigateur interne, vous aurez la possibilité de parcourir Internet sans le besoin de réduire ou quitter OpenBoard, avec des fonctionnalités supplémentaires vous permettant d'effectuer une capture partielle ou entière de l'écran, ou encore créer des applications à partir de sites, et les ajouter au tableau !
-
-
-
- Créer une application
- Vous pouvez créer une application à partir de n'importe quel site, afin de l'ajouter au tableau et interagir avec, comme avec les applications par défaut.
- Pour ce faire, allez sur le site web que vous souhaitez capturer, cliquez sur et confirmez sa création en cliquant sur "Créer une application".
-
-
- Quand une application est créée, elle est automatiquement sauvegardée dans la bibliothèque OpenBoard, afin que vous puissiez la réutiliser dans n'importe quel document. Vous les retrouverez sous le dossier Applications, dans un sous-dossier appelé "Web"
-
-
-
- Utilisation du navigateur externe
- Vous pouvez également choisir d'utiliser un navigateur externe, en cochant l'option correspondante dans les préférences. Cliquer sur lancera alors votre navigateur préféré en mode Bureau.
- En utilisant un navigateur externe, vous pourrez toujours créer une application depuis un site, en copiant l'URL située dans la barre d'adresse de votre navigateur, puis en la collant une fois de retour dans le mode Tableau !
-
-
+
+
+
+
+
+ Le navigateur intégré
+
+ Le Mode Web est un navigateur interne à OpenBoard qui ajoute à un navigateur
+ classique des fonctionnalités très pratiques pour la classe.
+
+
+ Il permet de parcourir Internet sans quitter OpenBoard, de capturer des contenus (partiels ou
+ plein écran) et même de créer des applications à partir de sites web pour les
+ réutiliser dans vos documents.
+
+
+
+
+
+
+
+
+
+ Créer une application à partir d’un site
+
+ Depuis n’importe quel site, vous pouvez générer une application pour l’ajouter
+ au tableau et interagir avec elle comme avec les applications par défaut.
+
+
+ Rendez-vous sur le site souhaité, cliquez sur
+
+ puis confirmez en sélectionnant Créer une application .
+
+
+
+
+ Création d'une application depuis le mode web.
+
+
+
+ Une fois créée, l’application est automatiquement sauvegardée dans la
+ bibliothèque OpenBoard . Vous la retrouverez sous Applications > Web
+ et pourrez la réutiliser dans n’importe quel document.
+
+
+
+
+ Retrouver une application créée dans sa bibliothèque.
+
+
+
+
+
+ Utiliser un navigateur externe
+
+ Vous pouvez choisir d’ouvrir les liens dans un navigateur externe en cochant
+ l’option correspondante dans les préférences. Cliquer sur
+
+ lancera alors votre navigateur favori en Mode Bureau.
+
+
+
+
+
+ Même avec un navigateur externe, vous pouvez créer une application depuis un site :
+ copiez l’URL dans la barre d’adresse du navigateur, revenez dans le Mode Tableau et collez-la
+ lorsque vous créez l’application.
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/7.html b/resources/startupHints/locales/fr/7.html
index 3e896b291..453d15b6b 100644
--- a/resources/startupHints/locales/fr/7.html
+++ b/resources/startupHints/locales/fr/7.html
@@ -1,44 +1,102 @@
-
+
-
- Capture d'écran
-
-
+
+ Capture d’écran
+
+
+
+
-
-
- Une des fonctionnalités basiques mais vraiment utiles d'OpenBoard est la capture d'écran. Avec, vous pouvez créer un instantané d'un état quelconque du tableau, pendant votre cours.
- En mode Tableau
- Cherchez dans la palette des stylets, cliquez dessus et sélectionnez la zone à capturer. Ensuite, trois options vous seront proposées :
-
- Ajouter à la page courante
- Ajouter à la nouvelle page
- Ajouter à la bibliothèque (ajoute la capture au dossier Images, afin que vous puissiez la réutiliser à tout moment)
-
-
- Voici un exemple du processus complet :
-
-
- Vous n'avez pas à vous inquiéter de la palette des stylets, de l'onglet d'aperçu des pages ou de celui de la bibliothèque OpenBoard, ils ne seront pas capturés par votre lasso !
-
- En mode Bureau
- Vous pouvez faire la même chose en mode Bureau, pour capturer votre travail sur d'autres logiciels. Passez en mode Bureau en cliquant sur
- Vous trouverez deux icônes : pour capturer l'ensemble de l'écran, et pour n'en capturer qu'une partie. Comme en mode Tableau, vous devrez choisir où ajouter la capture
-
- Voici une illustration du processus complet :
-
-
-
- En mode Web
- De la même façon, il est possible de faire ceci en mode Web, où vous pourrez effectuer une capture partielle de l'écran, ou capturer l'onglet actif du navigateur en cliquant sur
-
-
+
+
+
+
+ Une fonctionnalité simple et très utile
+
+ La capture d’écran vous permet de créer un instantané de l’état du tableau (ou de votre écran)
+ pendant votre cours, pour archiver, partager ou réutiliser le contenu.
+
+
+
+
+
+ En Mode Tableau
+
+ Dans la palette des stylets, cliquez sur
+ ,
+ puis sélectionnez la zone à capturer. Vous pourrez ensuite choisir :
+
+
+ Ajouter à la page courante
+ Ajouter à une nouvelle page
+
+ Ajouter à la bibliothèque — la capture est enregistrée dans le dossier Images
+ pour réutilisation ultérieure.
+
+
+
+
+
+ Exemple d'intégration d'une capture d'écran à OpenBoard.
+
+
+
+
+
+ La palette des stylets, l’aperçu des pages et l’onglet de la bibliothèque ne sont pas capturés
+ par le lasso : seules vos annotations et votre contenu le sont.
+
+
+
+
+
+
+ En Mode Bureau
+
+ Passez en Mode Bureau via
+
+ pour capturer d’autres logiciels.
+
+ Deux options sont disponibles :
+
+
+
+ Capture de l’écran entier
+
+
+
+ Capture d’une zone
+
+
+ Comme en Mode Tableau, choisissez où ajouter la capture.
+
+
+
+ Capture d’écran complet ou partiel en Mode Bureau.
+
+
+
+
+
+ En Mode Web
+
+ En Mode Web, vous pouvez capturer une zone de l’écran ou
+ capturer l’onglet actif du navigateur avec
+ .
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/8.html b/resources/startupHints/locales/fr/8.html
index f37dc684b..d48032119 100644
--- a/resources/startupHints/locales/fr/8.html
+++ b/resources/startupHints/locales/fr/8.html
@@ -1,36 +1,102 @@
-
+
-
- Images
-
-
+
+ Images
+
+
+
+
-
-
- Dans OpenBoard, vous pouvez accéder à des images de plusieurs façons.
- Organisez votre dossier Images
- Les captures d'écran ajoutées à la bibliothèque sont trouvables dans le dossier Images : Vous pouvez créer des sous-dossiers en utilisant tout en bas de la Bibliothèque. Ensuite, glissez-déposez vos images dans les différents dossiers que vous avez créés.
-
-
- Peu importe où vous vous situez dans la bibliothèque OpenBoard, les images que vous ajouterez seront automatiquement placées à l'intérieur du dossier , permettant ainsi de maintenir la bibliothèque organisée.
-
- Ajoutez des images depuis votre ordinateur
- Vous pouvez également ajouter des images depuis votre ordinateur, comme illustré ici :
-
-
- Ajoutez des images à partir des moteurs de recherche
- Enfin, vous pouvez chercher et ajouter au tableau des images libres de droit, en utilisant les moteurs de recherche situés dans le dossier "Recherche Web" :
-
-
- Au lieu d'utiliser le glisser-déposer, cliquez simplement sur une image apparaissant en résultat de recherche, pour en voir les détails et y trouver des options telles que Ajouter à la bibliothèque. Utile lors de la préparation d'un cours !
-
-
+
+
+
+
+ Accéder et organiser vos images
+
+ Dans OpenBoard, vous pouvez accéder et ajouter des images de différentes façons depuis votre bibliothèque . Cette dernière se situe à droite de l'écran. C'est également ici que vous pouvez stocker des sons, vidéos et trouver différentes applications.
+
+
+
+ Image de la bibliothèque située à droite dans le logiciel.
+
+
+
+
+
+
+
+
+ Ajoutez des images depuis votre ordinateur
+
+ Vous pouvez importer vos propres fichiers image directement dans OpenBoard, comme illustré ci-dessous :
+
+
+
+
+ Import d’une image locale dans OpenBoard.
+
+
+
+
+
+ Ajoutez des images depuis le Web
+
+ Vous pouvez également rechercher des images libres de droit via les moteurs de recherche intégrés,
+ situés dans le dossier Recherche Web
+ .
+
+
+
+
+ Exemple de recherche et d’ajout d’images depuis le Web.
+
+
+
+
+
+ Pas besoin de glisser-déposer : cliquez sur une image trouvée pour afficher ses détails
+ et utilisez directement l’option Ajouter à la bibliothèque .
+ C’est très pratique lors de la préparation de cours.
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/9.html b/resources/startupHints/locales/fr/9.html
index 6ff5a7c90..d40c27113 100644
--- a/resources/startupHints/locales/fr/9.html
+++ b/resources/startupHints/locales/fr/9.html
@@ -1,41 +1,99 @@
-
+
-
- Interactivités
-
-
+
+ Interactivités
+
+
+
+
-
-
- Pour les plus jeunes élèves, vous trouverez un ensemble d'applications personnalisables qui leur sont dédiées.
- Les exercices interactifs d'OpenBoard
- Avec ces interactivités, vous pouvez créer différents types d'exercices. Il peut s'agir de catégorisation, calcul mental, mémorisation, etc.
- Les interactivités sont situées dans la bibliothèque OpenBoard : cliquez sur pour les trouver.
-
- Exemple
- Nous allons créer un exercice utilisant l'interactivité "Cat egorize pict ures" (traduction : Catégorisez des images) :
- Essayez ! Déplacez cette fenêtre sur un côté et reproduisez l'exemple sur le Tableau !
- Tout d'abord, glissez-déposez l'interactivité sur le tableau, et cliquez sur "Modifier"
- Ensuite, changez les noms des catégories selon vos besoins :
-
-
- Vous pouvez ajouter ou supprimer des catégories en utilisant les icônes + et -
-
- Ensuite, ajoutez les images correspondant à chaque catégorie.
-
-
- Enfin, cliquez sur "Afficher" pour voir le résultat et faire l'exercice.
-
-
- Vous pouvez relancer l'exercice en cliquant sur l'icône "Recharger".
-
-
+
+
+
+
+
+
+ Des exercices interactifs, simples à personnaliser
+
+ Pour les plus jeunes élèves (et pas seulement), OpenBoard fournit un ensemble
+ d’interactivités personnalisables : catégorisation, calcul mental, mémorisation, etc.
+
+
+ Elles sont accessibles dans la bibliothèque : cliquez sur
+ .
+
+
+
+
+
+ Exemple : « Categorize Pictures »
+
+ Créons un exercice avec l’interactivité
+ Cat egorize pict ures (catégoriser des images) :
+ .
+
+
+
+
+ 1) Placer l’interactivité et ouvrir l’éditeur
+
+ Glissez-déposez l’interactivité sur le Tableau, puis cliquez sur Modifier .
+
+
+ 2) Nommer les catégories
+
+ Renommez les catégories selon vos besoins. Vous pouvez aussi
+ ajouter ou supprimer des catégories avec les icônes « + » et « − ».
+
+
+
+
+ Édition des catégories : ajout, suppression, renommage.
+
+
+ 3) Ajouter les images
+
+ Ajoutez les images correspondant à chaque catégorie (glisser-déposer, sélection depuis la bibliothèque, etc.).
+
+
+
+
+ Associer des images aux catégories définies.
+
+
+ 4) Afficher et faire l’exercice
+
+ Cliquez sur Afficher pour lancer l’activité en mode élève.
+
+
+
+
+ Exécution de l’exercice : déplacer les images dans la bonne catégorie.
+
+
+
+
+
+ Pour relancer l’exercice, utilisez l’icône Recharger .
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/fr/css/style.css b/resources/startupHints/locales/fr/css/style.css
deleted file mode 100644
index de0ecb4d5..000000000
--- a/resources/startupHints/locales/fr/css/style.css
+++ /dev/null
@@ -1,36 +0,0 @@
-*{
- font-family: Arial, Helvetica, sans-serif;
-}
-
-.title
-{
- width:100%;
- color: #6682b5;
- text-align: center;
-}
-
-.file-extension
-{
- background: lightgrey;
-}
-
-.image
-{
- text-align:center;
-}
-
-.image img
-{
- max-width: 600px;
-}
-
-.icon
-{
- vertical-align: middle;
-}
-
-.tip
-{
- font-style: italic;
- font-size: 0.8rem;
-}
diff --git a/resources/startupHints/locales/fr/error.html b/resources/startupHints/locales/fr/error.html
index f998df943..a24888b69 100644
--- a/resources/startupHints/locales/fr/error.html
+++ b/resources/startupHints/locales/fr/error.html
@@ -1,15 +1,20 @@
-
-
-
-
- erreur
-
-
-
-
-
-Quelque chose s'est mal passé ...
-Vérifier l'existence de vos conseils dans le dossier
-/Resources/startupHints/ …
-
-
+
+
+
+
+ Erreur
+
+
+
+
+
+
+ Erreur de chargement
+
+ Quelque chose s'est mal passé.
+ Vérifiez la présence des pages d'astuces dans le dossier
+ /Resources/startupHints/ .
+
+
+
+
diff --git a/resources/startupHints/locales/hr/1.html b/resources/startupHints/locales/hr/1.html
index 71537c1f4..ff6e6f57c 100644
--- a/resources/startupHints/locales/hr/1.html
+++ b/resources/startupHints/locales/hr/1.html
@@ -1,26 +1,95 @@
-
+
-
- Savjeti
-
-
+
+ Dobrodošli
+
+
+
-
-
- Dobro došao, dobro došla u OpenBoard
-
-
-
-
- Ovdje se nalaze savjeti koji pomažu naučiti koristiti OpenBoard.
- OpenBoard je interaktivna ploča koju su dizajnirali učitelji za učitelje. Postoje četiri modusa:ploča, radna površina, dokumenti i web.
- Krenimo s prvim i najvažnijim: modus ploče.
-
-
- Dijalog „Savjeti” možeš otvoriti u bilo kojem trenutku pomoću gumba ( ) u OpenBoard izborniku
-
+
+
+
+
+
+
+ Evo nekoliko savjeta i trikova koji će vam pomoći da se upoznate s OpenBoard.
+
+
+
+ OpenBoard je interaktivna ploča koju su dizajnirali učitelji za učitelje.
+ Nudi cetiri nacina koji pokrivaju najcesce potrebe u nastavi.
+
+
+
+
+
+ Počnimo s prvim i najvažnijim: Nacin Ploca .
+
+
+
+
+
+ možete ponovo otvoriti u bilo kojem trenutku ovaj prozor putem gumba
+ "Savjeti i trikovi" u izborniku OpenBoard
+ .
+
+
+
+
+
+
+
-
diff --git a/resources/startupHints/locales/hr/10.html b/resources/startupHints/locales/hr/10.html
index 9c63026a8..64f75e070 100644
--- a/resources/startupHints/locales/hr/10.html
+++ b/resources/startupHints/locales/hr/10.html
@@ -1,44 +1,95 @@
-
-
-
-
- Programi
-
-
-
-
-
-
-
- OpenBoard pruža nekoliko programa i alata. Možeš im pristupiti pritiskom na u OpenBoard biblioteci
- Standardni programi
- Pronaći ćeš geometrijske alate, kalkulator, Google kartu, generator QR koda i još više! Kombiniraj ih za stvaranje poticajnih nastava!
-
- Stvaranje programa
- Kao što je objašnjeno u odjeljku Web modusa, programi s web stranica se mogu izraditi koristeći interni navigator ili kopiranjem i umetanjem URL adresa na ploču.
- Na ovaj način možeš podržati svoju nastavu moćnim online alatima izravno na ploči! Primjeri zanimljivih programa koje se mogu stvoriti (povuci i ispusti ih na ploču za testiranje!):
-
-
- … i još puno više!
-
- Trebaš moćniji kalkulator od onog koji nudi OpenBoard? Misli na to da možeš stvoriti vlastite programe! Jednostavno povuci i ispusti sljedeću poveznicu na ploču: https://ti89-simulator.com/
-
-
-
-
-
+
+
+
+
+ Prijave
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pristup aplikacijama
+
+ OpenBoard nudi drugačije aplikacije i alate .
+ Pronađite ih u knjižnici klikom na
+ .
+
+
+
+
+
+ Zadane aplikacije
+
+ Pronaći ćete geometrijske alate, kalkulator, Google karte, generator QR koda i još mnogo toga.
+ Kombinirajte ih kako biste stvorili privlačna obrazovna iskustva!
+
+
+
+
+ Primjer korištenja ugrađenih aplikacija OpenBoard.
+
+
+
+
+
+ Izradite vlastite aplikacije
+
+ Kao što je objašnjeno u odjeljku Nacin Web , možete izraditi aplikaciju sa stranice,
+ pomoću internog preglednika ili kopiranjem i lijepljenjem URL-a na ploču.
+
+
+ To vam omogućuje da poboljšate svoje tečajeve moćnim online alatima, koji se mogu koristiti izravno u OpenBoard.
+ Evo nekoliko zanimljivih primjera (povucite i ispustite veze na ploču da ih testirate):
+
+
+
+
+ ...i mnogo više!
+
+
+
+
+ Trebate napredniji kalkulator od OpenBoard? Stvorite vlastitu
+ aplikaciju povlačenjem i ispuštanjem ove veze na stol:
+ https://ti89-simulator.com/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/11.html b/resources/startupHints/locales/hr/11.html
index 60b0268fb..04aa87f4d 100644
--- a/resources/startupHints/locales/hr/11.html
+++ b/resources/startupHints/locales/hr/11.html
@@ -1,39 +1,90 @@
-
-
-
-
- Snimanje videa
-
-
-
-
-
-
-
- Snimanje nastave
- OpenBoard omogućuje snimanja videa nastave.
- Vrlo korisno za dijeljenje dodatnih vježbi ili informacija putem videa ili za snimanje nastave za učenike koji nisu prisutni.
-
- U modusu ploče se alatne trake i palete neće vidjeti u videu! Isto vrijedi i za web modus, gdje će se na snimci vidjeti samo trenutačna kartica.
-
- Otvori ovaj alat ovako:
-
-
- U donjem desnom kutu ploče će se pojaviti sljedeće sučelje:
-
-
- Pritisni crveni gumb za pokretanje snimanja.
-
- Postavke se mogu prilagoditi pritiskom na . Tamo se nalaze postavke za zvuk (odaberi mikrofon ili ništa), postavke za video (razlučivost videa) i opcije za objavljivanje
-
- Nakon što je snimanje gotovo, snimka će se automatski spremiti na radnu površinu računala
-
-
-
-
-
-
+
+
+
+
+ Video snimanje
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Snimite svoj tečaj
+
+ OpenBoard vam omogućuje spremanje audio i video vašeg tečaja.
+ Idealno za dijeljenje dodatnih vježbi, objavljivanje kratkog isječka s objašnjenjem ili
+ učiniti tečaj dostupnim odsutnim studentima.
+
+
+
+
+
+ U Nacin Ploca , alatne trake i palete ne pojavljuju se u videu.
+ U Nacin Web , snima se samo aktivna kartica.
+
+
+
+
+
+
+ Pristupite alatu za registraciju
+ Otvorite alat za izrezivanje kao što je prikazano u nastavku:
+
+
+
+ Brzi pristup alatu za registraciju sa sučelja OpenBoard.
+
+
+
+
+
+ Upravljačko sučelje
+ Sučelje se pojavljuje u donjem desnom kutu tablice:
+
+
+
+
+
+ Kliknite na crveni gumb za početak snimanja.
+
+
+
+
+ Prilagodite snimanje putem
+ :
+ izbor od mikrofon (ili nijedan), izbor video rezolucija i opcije objavljivanje .
+
+
+
+
+
+
+ Završite i oporavite videozapis
+
+ Nakon što je snimanje završeno, video se automatski pokreće spremljeno na radnu površinu vašeg računala.
+
+
+
+
+ Zaustavite snimanje i video datoteka dostupna na radnoj površini.
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/12.html b/resources/startupHints/locales/hr/12.html
index 73a9de08c..28c0523ae 100644
--- a/resources/startupHints/locales/hr/12.html
+++ b/resources/startupHints/locales/hr/12.html
@@ -1,37 +1,94 @@
-
-
-
-
- Favoriti
-
-
-
-
-
-
-
- Dodavanje OpenBoard dokumenata u favorite
- OpenBoard verzija 1.7 omogućuje dodavanje OpenBoard dokumenata u favorite!
- Idi u modus dokumenata, odaberi jedan dokument i pritisni na u alatnoj traci dokumenata.
-
-
-
- Brzo prebacivanje s jednog dokumenta na drugi
- Omiljeni dokumenti će se pojaviti u OpenBoard biblioteci pod
- Svaki OpenBoard dokument ( ) se može povući i ispustiti na ploču!
-
-
- Koristi traku za pretraživanje na dnu OpenBoard biblioteke za brzo pronalaženje dokumenta na osnovi imena
-
- Nedavno otvoreni dokumenti
- Svaki dokument koji se otvori privremeno se dodaje u favorite za brzo prebacivanje između dokumenata, bez da moraju biti izričito označeni kao favoriti.
-
- Ako nedavno otvoreni dokument želiš trajno dodati u favorite, to možeš obaviti putem OpenBoard biblioteke: odaberi ga i pritisni na
-
-
-
-
+
+
+
+
+ Omiljeni dokumenti
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dodajte OpenBoard dokumenata u favorite
+
+ Uveden u verzija 1.7 , ova vam funkcija omogućuje dodavanje vaših OpenBoard dokumenata
+ u favoriti .
+
+
+ Da biste to učinili, idite na Nacin Dokumenti , odaberite dokument i kliknite
+
+ na alatnoj traci.
+
+
+
+
+
+
+
+
+
+
+ Brzo prijeđite s jednog dokumenta na drugi
+
+ Vaši omiljeni dokumenti pojavljuju se u knjižnica OpenBoard , u nastavku
+ .
+
+
+ Svaki omiljeni dokument
+
+ može se povući i ispustiti izravno na stol.
+
+
+
+
+
+
+
+
+
+ Koristite traka za pretraživanje na dnu biblioteke tako da možete brzo pronaći dokument po imenu.
+
+
+
+
+
+
+
+ Nedavno otvoreni dokumenti
+
+ Svaki otvoreni dokument privremeno se dodaje u favorite, radi brzog prebacivanja s jednog na drugi
+ tijekom iste sesije, bez potrebe da ih izričito označite.
+
+
+
+
+
+
+
+
+
+
+ Napraviti trajnog nedavno otvoreni dokument, odaberite ga iz mape Favoriti
+ i kliknite
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/2.html b/resources/startupHints/locales/hr/2.html
index 1ab997c6e..831628e93 100644
--- a/resources/startupHints/locales/hr/2.html
+++ b/resources/startupHints/locales/hr/2.html
@@ -1,48 +1,122 @@
-
-
-
-
- Modus ploče
-
-
-
-
-
-
-
- Paleta alata
- Paleta alata sadrži osnovne alate za rad na ploči.
-
-
- Sadrži pisaljku ( ), gumicu ( ) i marker ( ). OpenBoard također sadrži daljnje funkcije koje klasična ploča ne pruža:
-
- je selektor. Omogućuje biranje objekata kao i interakciju s njima.
- je čarobni prst. Omogućuje pomicanje objekata ili interakciju s njima bez da se moraju odabrati.
- je ruka. Omogućuje kretanje po stranici. Vrlo korisno u kombinaciji sa zumiranjem!
- omogućuje zumiranje. Odaberi vrstu zumiranja i pritisni stranicu na koju želiš primijeniti zumiranje!
- je laserski pokazivač. Koristno za označavanje elemenata na ploči bez interakcije s njima.
- se koristi za jednostavno crtanje ravnih crta.
- je alat za pisanje teksta pomoću tipkovnice umjesto pisaljke.
-
-
- Zumiranje možeš preciznije odrediti pomoću miša! Koristi Ctrl/Cmd + kotačić miša za preciznije zumiranje!
-
-
- Alatna traka ploče
- Alatna traka ploče omogućuje pored ostalog mijenjanje boje i debljine pisaljke ili markera.
-
-
- Omogućuje mijenjanje pozadine ploče pritiskom na
-
-
- Sadrži gumbe za poništavanje/ponavljanje radnji, stvaranje i kretanje po stranicama, brisanje cijele ploče …
-
- Dijelove ploče možeš preciznije obrisati dugim pritiskom na . Neke skrivene funkcije i na !
-
-
-
-
+
+
+
+
+ Nacin Ploca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Stolna traka
+
+ Traka tablice omogućuje vam promjenu boja i/ili veličina između ostalog olovka i highlighter.
+
+
+
+
+
+
+
+ Također možete promijeniti pozadina stola klikom na
+ .
+
+
+
+
+
+
+
+ Dostupne su i druge funkcije: poništiti/ponoviti , stvarati stranice, kretati se između stranica, čistiti tablicu itd.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/3.html b/resources/startupHints/locales/hr/3.html
index 16da5b6ee..e23f1e462 100644
--- a/resources/startupHints/locales/hr/3.html
+++ b/resources/startupHints/locales/hr/3.html
@@ -1,30 +1,74 @@
-
-
-
-
- Modus radne površine
-
-
-
-
-
-
-
- Interakcija s drugim programima
- Modus radne površine omogućuje interakciju s računalom i drugim programima, zadržavajući OpenBoard u prednjem planu!
- Jednostavno pritisni sljedeću ikonu:
-
- Koristi selektor (
) za interakciju s radnom površinom i drugim programima.
- Dodavanje pribilješki programu ili web stranici
- Pribilješke se mogu dodati bilo kojem programu koristeći pisaljku (
) ili marker (
).
-
-
- Pristupi daljnjim opcijama za , i dugim pritiskom na ikonu ili pritiskom na malu crnu strelicu.
-
-
-
-
+
+
+
+
+ Nacin Radna Povrsina
+
+
+
+
+
+
+
+
+
+
+
+
+ Interakcija s drugim aplikacijama
+
+ Opcija Uredski način rada omogućuje vam interakciju s vašim operativnim sustavom i softverom,
+ zadržavajući OpenBoard alate na vrhu.
+
+ Jednostavno kliknite na sljedeću ikonu:
+
+
+
+
+
+
+ Koristite selektor
+
+ za interakciju s radnom površinom i drugim aplikacijama.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/4.html b/resources/startupHints/locales/hr/4.html
index dbafab821..36fb32411 100644
--- a/resources/startupHints/locales/hr/4.html
+++ b/resources/startupHints/locales/hr/4.html
@@ -1,32 +1,79 @@
-
-
-
-
- Modus dokumenata
-
-
-
-
-
-
-
- OpenBoard sadrži sustav za upravljanje dokumentima. Jednostavno pritisni
-
-
- Stvaranje mape i organiziranje rada
- Mapa se može stvoriti pritiskom na ikonu „Nova mapa”. Upiši ime za mapu te povuci i ispusti dokumente u mapu. Tehnika povuci i ispusti se može koristiti i za premještanje cijele mape u jednu drugu mapu.
-
-
- Bartanje stranicama
- OpenBoard dokument može sadržati više stranica. Mogu se duplicirati, premjestiti u smeće ili u jedan drugi dokument. Nove stranice se mogu stvoriti i iz mapa sa slikama, …
-
-
- Imaj na umu da se dostupne radnje aktualiziraju prema onome što je odabrano
-
-
-
-
+
+
+
+
+ Nacin Dokumenti
+
+
+
+
+
+
+
+
+
+
+
+
+ Pristupite upravitelju dokumenata
+
+ OpenBoard nudi a upravitelj dokumenata . Kliknite na
+
+ da ga otvorim.
+
+
+
+
+
+
+
+
+ Stvorite mape i organizirajte svoj rad
+
+ Stvorite mapu putem
+ ,
+ ime, onda povuci i ispusti svoje dokumente unutra.
+ Isto tako, možete premjestiti cijelu mapu u drugu.
+
+
+
+ Primjer izrade i organiziranja mapa.
+
+
+
+
+
+ Upravljanje stranicama
+
+ Dokument OpenBoard može sadržavati nekoliko stranica . Iz Nacin Dokumenti možete:
+
+
+ Duplicirane stranice
+ Pošaljite ih u smeće
+ Kopirajte ih u drugi dokument
+ Stvorite nove stranice iz mape slika
+
+
+
+ Primjer obrade dokumenata.
+
+
+
+
+
+ THE dostupnih radnji prilagoditi prema onome što jest
+ odabrano (mapa, dokument, stranica).
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/5.html b/resources/startupHints/locales/hr/5.html
index 8b6b7161b..70188ab92 100644
--- a/resources/startupHints/locales/hr/5.html
+++ b/resources/startupHints/locales/hr/5.html
@@ -1,39 +1,105 @@
-
-
-
-
- Modus dokumenata
-
-
-
-
-
-
-
- U ovom se modusu nalaze dvije važne funkcije: uvoz i izvoz.
-
-
- Uvoz
- Omogućuje uvoz PDF datoteka (.pdf ), slika (.png , .jpg ), OpenBoard dokumenata (.ubz ) ili OpenBoard mapa (.ubx ) pritiskom na
-
- OpenBoard dokument (.ubz ) se može otvoriti i dvostrukim pritiskom na dokument. Ako OpenBoard još nije pokrenut, program će se pokrenuti i dokument će se uvesti (ili će se zatražiti zamjena ako već postoji).
- Također je moguće uvesti više elemenata odjednom, bez potrebe za višestrukim pritiskom na .
- Izvoz
- Omogućuje izvoz OpenBoard dokumenta u PDF ili UBZ format kao i izvoz OpenBoard mape u UBX format. Na taj način je moguće:
-
- Spremiti rad obavljen tijekom predavanja i dijeliti ga s učenicima koji nisu prisutni
- Dijeliti ga s drugim učiteljima ili ga spremiti na USB uređaj i otvoriti ga na jednom drugom računalu
- Uvesti domaću zadaću učenika u PDF formatu, dodati pribilješku te izvesti i učeniku poslati komentirani PDF
-
-
-
-
- Izvezi sve tvoje dokumente biranjem mape „Moji dokumenti” prije pritiskanja gumba za izvoz kako bi se izvezli kao UBX datoteke, a zatim ih uvezi na jednom drugom računalu. To je također dobar način za spremanje sigurnosne kopije tvog rada!
-
-
-
-
+
+
+
+
+
+ Uvoz i izvoz
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Uvoz i izvoz
+
+ U ovom načinu rada imate dvije bitne značajke: uvoz I izvoz .
+
+
+
+
+
+
+
+
+
+ Uvoz sadržaja
+
+ Možete uvesti datoteke PDF (.pdf ),
+ od slike (.png , .jpg ),
+ od dokumenti OpenBoard (.ubz ) ili
+ OpenBoard mapa (.ubx ) klikom na
+ .
+
+
+
+
+
+ Primjer uvoza datoteka u OpenBoard.
+
+
+
+ Također možete uvesti OpenBoard dokument (.ubz ) u
+ dupli klik na njemu iz vašeg sustava. OpenBoard pokrenut će se ako je potrebno i
+ će ponuditi uvoz (ili zamjenu ako već postoji).
+
+
+
+
+
+ Moguće je da seuvoz više stavki odjednom ,
+ bez ponovnog klika
+
+ svaki put.
+
+
+
+
+
+
+ Izvezite svoje dokumente
+
+ Možete izvesti a dokument OpenBoard u formatu PDF Ili UBZ ,
+ i a mapa OpenBoard u formatu UBX . Na primjer:
+
+
+ Zabilježite rad obavljen tijekom lekcije i podijelite ga s odsutnim učenikom.
+ Podijelite s drugim učiteljima ili spremite na USB ključ za uvoz na drugo mjesto.
+ Uvezite studentov rad kao PDF, označite ga, zatim izvezite komentirani PDF za ponovno slanje.
+
+
+
+
+ Primjer izvoza datoteka iz OpenBoard.
+
+
+
+
+
+ Za izvoz sve svoje dokumente , prvo odaberite korijensku mapu
+ Moji dokumenti , zatim kliknite
+ .
+ Dobit ćete a UBX prenosivo na drugo računalo — savršeno za
+ sigurnosna kopija ili a arhiva kompletno!
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/6.html b/resources/startupHints/locales/hr/6.html
index 49e5fc24a..cac5678bd 100644
--- a/resources/startupHints/locales/hr/6.html
+++ b/resources/startupHints/locales/hr/6.html
@@ -1,38 +1,96 @@
-
-
-
-
- Web modus
-
-
-
-
-
-
-
- Web modus je interni navigator s dodatnim funkcijama.
- Korištenje internog navigatora
- Interni navigator omogućuje pregledavanje interneta bez potrebe za smanjivanjem prozora ili zatvaranjem OpenBoarda. Pored toga omogućuje snimanja dijela ekrana ili stvaranje programa iz web stranica koje se mogu dodati na ploču!
-
-
-
- Stvaranje programa
- Program se može stvoriti s bilo kojeg mjesta i dodati na ploču te s njom interagirati kao sa standardnim programima.
- Otvori web stranicu koju želiš snimiti, pritisni na te potvrdi izradu pritiskom na „Stvori program”.
-
-
- Kad je program stvoren, on se automatski sprema u OpenBoard biblioteku, tako da se može koristiti u bilo kojem dokumentu. Programi se nalaze u mapi s programima koja se zove „Web”.
-
-
-
- Korištenje eksternog navigatora
- Označavanjem odgovarajuće opcije u postavkama može se koristiti i eksterni navigator. Tada će se pritiskom na web ikonu pokrenuti favorizirani navigator u modusu radne površine.
- Koristeći eksterni navigator, i dalje ćeš moći stvarati programe s web stranice. Kopiraj URL-adresu u adresnu traku navigatora, vrati se na ploču i umetni je!
-
-
-
-
+
+
+
+
+ Nacin Web
+
+
+
+
+
+
+
+
+
+
+
+
+ Integrirani preglednik
+
+ THE Nacin Web je interni preglednik za OpenBoard koji dodaje pregledniku
+ klasične, vrlo praktične značajke za učionicu.
+
+
+ Omogućuje vam pregledavanje interneta bez napuštanja OpenBoard, za snimanje sadržaja (djelomičnog ili
+ preko cijelog zaslona) i čak stvarati aplikacije s web stranica za
+ ponovno koristiti u svojim dokumentima.
+
+
+
+
+
+
+
+
+
+ Napravite aplikaciju sa stranice
+
+ S bilo kojeg mjesta možete generirati a primjena dodati ga
+ na ploči i komunicirati s njim kao sa zadanim aplikacijama.
+
+
+ Idite na željenu stranicu, kliknite na
+
+ zatim potvrdite odabirom Napravite aplikaciju .
+
+
+
+
+ Izrada aplikacije iz web moda.
+
+
+
+ Jednom kreirana aplikacija se automatski sprema u
+ knjižnica OpenBoard . Naći ćete ga ispod Aplikacije > Web
+ i može ga ponovno koristiti u bilo kojem dokumentu.
+
+
+
+
+ Pronađite aplikaciju stvorenu u svojoj knjižnici.
+
+
+
+
+
+ Koristite vanjski preglednik
+
+ Možete izabrati da otvorite veze u a vanjski preglednik provjerom
+ odgovarajuću opciju u postavkama. Kliknite na
+
+ će zatim pokrenuti vaš omiljeni preglednik kao Nacin Radna Povrsina.
+
+
+
+
+
+ Čak i s vanjskim preglednikom možete izraditi aplikaciju sa stranice:
+ kopirajte URL u adresnu traku preglednika, vratite se na Nacin Ploca i zalijepite ga
+ kada kreirate aplikaciju.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/7.html b/resources/startupHints/locales/hr/7.html
index 702dc2e45..cfcbe9ec0 100644
--- a/resources/startupHints/locales/hr/7.html
+++ b/resources/startupHints/locales/hr/7.html
@@ -1,44 +1,102 @@
-
-
-
-
- Snimanje ekrana
-
-
-
-
-
-
-
- Jedna od najjednostavnijih ali vrlo korisnih OpenBoard funkcija je snimanje ekrana, što omogućuje snimanje bilo kojeg određenog stanja ploče tijekom nastave.
- U modusu ploče
- Traži u paleti alata. Pritisni ikonu i odaberi područje za snimanje. Nakon toga postoje tri mogućnosti:
-
- Dodaj u trenutačnu stranicu
- Dodaj u novu stranicu
- Dodaj u biblioteku (dodaje snimku u mapu „Slike” kako bi se mogla ponovo koristiti u bilo kojem trenutku)
-
-
- Primjer cijelog postupka:
-
-
- Paleta alata, prikaz minijatura te OpenBoard biblioteka se neće snimiti pri odabiru sadržaja!
-
- U modusu radne površine
- Za snimanje vlastitog rada u drugim programima, isto se može obaviti u modusu radne površine. Prijeđi u modus radne površine pritiskom na
- Prikazat će se dvije ikone: za snimanje cijelog ekrana i za snimanje dijelova ekrana. Kao u modusu ploče, morat ćeš odabrati mjesto za ispuštanje snimke
-
- Prikaz cijelog postupka
-
-
-
- U web modusu
- Isti postupak je dostupan u web modusu, gdje ja moguće snimiti dio ekrana ili trenutačnu karticu pomoću
-
-
-
-
+
+
+
+
+ Snimka zaslona
+
+
+
+
+
+
+
+
+
+
+
+ Jednostavna i vrlo korisna značajka
+
+ Snimka zaslona omogućuje vam stvaranje a trenutak stanje ploče (ili vašeg zaslona)
+ tijekom tečaja, za arhiviranje, dijeljenje ili ponovno korištenje sadržaja.
+
+
+
+
+
+ U Nacin Ploca
+
+ U paleti olovke kliknite
+ ,
+ zatim odaberite područje za snimanje. Zatim možete odabrati:
+
+
+ Dodaj trenutnoj stranici
+ Dodaj na novu stranicu
+
+ Dodaj u knjižnicu — snimak se sprema u mapu Slike
+ za kasniju ponovnu upotrebu.
+
+
+
+
+
+ Primjer ugradnje snimke zaslona u OpenBoard.
+
+
+
+
+
+ Paleta olovke, pregled stranice i kartica knjižnice nisu zarobljeni
+ by lasso: samo vaše napomene i vaš sadržaj.
+
+
+
+
+
+
+ U Nacin Radna Povrsina
+
+ Prebacite se na Nacin Radna Povrsina putem
+
+ za snimanje drugog softvera.
+
+ Dostupne su dvije opcije:
+
+
+
+ Snimanje cijelog zaslona
+
+
+
+ Snimanje područja
+
+
+ Kao u Nacin Ploca, odaberite gdje ćete dodati snimanje.
+
+
+
+ Cijeli ili djelomični snimak zaslona u Nacin Radna Povrsina.
+
+
+
+
+
+ U Nacin Web
+
+ U Nacin Web možete uhvatiti područje ekrana ili
+ snimi aktivnu karticu iz preglednika sa
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/8.html b/resources/startupHints/locales/hr/8.html
index d1c36c50f..4caa1a76e 100644
--- a/resources/startupHints/locales/hr/8.html
+++ b/resources/startupHints/locales/hr/8.html
@@ -1,36 +1,102 @@
-
-
-
-
- Slike
-
-
-
-
-
-
-
- OpenBoard omogućuje pristup slikama na nekoliko načina.
- Organiziranje mape „Slike”
- Snimke ekrana koje se dodaju u biblioteku spremaju se u mapu „Slike”: Mape se mogu stvoriti koristeći na dnu biblioteke. Zatim povuci i ispusti slike u stvorene mape.
-
-
- Bez obzira gdje se nalaziš u OpenBoard biblioteci, slike koje dodaš će se automatski smjestiti u mapu „Slike”.
-
- Dodavanje slika iz računala
- Prikaz dodavanja slika koja su spremljena na računalu:
-
-
- Dodavanje slika iz tražilica
- Besplatne slike možeš tražiti i dodati na ploču koristeći tražilice koje se nalaze u mapi „Web pretraga”:
-
-
- Umjesto korištenja tehnike povuci i ispusti, jednostavno pritisni sliku koju je pronašla tražilica za prikaz detalja slike i pronađi opciju za dodavanje slike u biblioteku, bez dodavanja slike u trenutačni dokument. Korisno za pripremanje nastave!
-
-
-
-
+
+
+
+
+ Slike
+
+
+
+
+
+
+
+
+
+
+
+ Pristupite svojim slikama i organizirajte ih
+
+ U OpenBoard možete pristupiti i dodavati slike na različite načine od svojih knjižnica . Potonji se nalazi na desnoj strani ekrana. Ovdje također možete pohraniti zvukove, video zapise i pronaći različite aplikacije.
+
+
+
+ Slika knjižnice koja se nalazi desno u softveru.
+
+
+
+
+
+
+
+
+ Dodajte slike sa svog računala
+
+ Možete uvesti vlastite slikovne datoteke izravno u OpenBoard, kao što je prikazano u nastavku:
+
+
+
+
+ Uvoz lokalne slike u OpenBoard.
+
+
+
+
+
+ Dodajte slike s weba
+
+ Također možete tražiti slike bez naknade putem integriranih tražilica,
+ koji se nalazi u mapi Web pretraživanje
+ .
+
+
+
+
+ Primjer pronalaženja i dodavanja slika s weba.
+
+
+
+
+
+ Nema potrebe za povlačenjem i ispuštanjem: kliknite na pronađenu sliku da vidite njezine detalje
+ i izravno koristiti opciju Dodaj u knjižnicu .
+ Ovo je vrlo praktično kada pripremate lekcije.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/9.html b/resources/startupHints/locales/hr/9.html
index 03fc2b937..6fa8d5ba4 100644
--- a/resources/startupHints/locales/hr/9.html
+++ b/resources/startupHints/locales/hr/9.html
@@ -1,43 +1,99 @@
-
-
-
-
- Interaktivnosti
-
-
-
-
-
-
-
- Za mlađe učenike postoji poseban skup prilagođenih programa.
- Interaktivna vježba za OpenBoard
- Pomoću ovih interaktivnosti mogu se izraditi različite vrste prilagođenih vježbi. To se može odnositi na kategorizaciju, računanje, pamćenje i tako dalje.
- Interaktivnosti se nalaze u OpenBoard biblioteci: pronađi ih pritiskom na .
-
- Primjer
- Kao primjer ćemo izraditi vježbu koristeći interaktivnost „Kategoriziraj sliku ”:
- Probaj! Pomakni ovaj dijalog na stranu i reproduciraj primjer na ploči!
- Najprije povuci i ispusti interaktivnost na tvoju ploču i pritisni „Uredi”
- Zatim promijeni imena kategorija prema svojim potrebama:
-
-
- Kategorije možeš dodati ili izbrisati pomoću ikona + i -
-
- Zatim dodaj željene slike u odgovarajuću kategoriju.
-
-
- Na kraju pritisni „Prikaz” za prikaz rezultata i izvođenje vježbe.
-
-
- Vježbu možeš ponovo pokrenuti pomoću ikone „Učitaj ponovo”.
-
-
-
-
-
-
+
+
+
+
+ Interaktivnosti
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Interaktivne vježbe, jednostavne za personalizaciju
+
+ Za najmlađe učenike (i ne samo), OpenBoard nudi set
+ odinteraktivnosti prilagodljiv: kategorizacija, mentalno računanje, pamćenje itd.
+
+
+ Dostupni su u knjižnica : kliknite na
+ .
+
+
+
+
+
+ Primjer: “Kategoriziraj slike”
+
+ Kreirajmo vježbu s interaktivnošću
+ mačka egorizirati slika ures (kategoriziraj slike):
+ .
+
+
+
+
+ 1) Postavite interaktivnost i otvorite uređivač
+
+ Povucite i ispustite interaktivnost na ploču, zatim kliknite Za izmjenu .
+
+
+ 2) Imenujte kategorije
+
+ Preimenujte kategorije prema potrebi. Možete također
+ dodati Ili IZBRISATI kategorije s ikonama "+" i "−".
+
+
+
+
+ Uređivanje kategorija: dodavanje, brisanje, preimenovanje.
+
+
+ 3) Dodajte slike
+
+ Dodajte slike koje odgovaraju svakoj kategoriji (povuci i ispusti, odabir iz biblioteke itd.).
+
+
+
+
+ Povežite slike s definiranim kategorijama.
+
+
+ 4) Pokažite i napravite vježbu
+
+ Kliknite na Prikaz za pokretanje aktivnosti u studentskom načinu rada.
+
+
+
+
+ Izvođenje vježbe: premjestite slike u odgovarajuću kategoriju.
+
+
+
+
+
+ Za ponovno pokrenuti vježbe, koristite ikonu Ponovno učitaj .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/hr/css/style.css b/resources/startupHints/locales/hr/css/style.css
deleted file mode 100644
index de0ecb4d5..000000000
--- a/resources/startupHints/locales/hr/css/style.css
+++ /dev/null
@@ -1,36 +0,0 @@
-*{
- font-family: Arial, Helvetica, sans-serif;
-}
-
-.title
-{
- width:100%;
- color: #6682b5;
- text-align: center;
-}
-
-.file-extension
-{
- background: lightgrey;
-}
-
-.image
-{
- text-align:center;
-}
-
-.image img
-{
- max-width: 600px;
-}
-
-.icon
-{
- vertical-align: middle;
-}
-
-.tip
-{
- font-style: italic;
- font-size: 0.8rem;
-}
diff --git a/resources/startupHints/locales/hr/error.html b/resources/startupHints/locales/hr/error.html
index 525043180..1c01b9e20 100644
--- a/resources/startupHints/locales/hr/error.html
+++ b/resources/startupHints/locales/hr/error.html
@@ -1,15 +1,20 @@
-
-
-
-
- erreur
-
-
-
-
-
-Dogodila se greška …
-Provjeri postojanje savjeta u datoteci
-/Resources/startupHints/ …
-
-
+
+
+
+
+ Greška
+
+
+
+
+
+
+ Greška pri učitavanju
+
+ Nešto nije u redu.
+ Provjerite prisutnost stranica sa savjetima u mapi
+ /Resursi/startupHints/ .
+
+
+
+
diff --git a/resources/startupHints/locales/it/1.html b/resources/startupHints/locales/it/1.html
index 03a739b0d..1cb2f4404 100644
--- a/resources/startupHints/locales/it/1.html
+++ b/resources/startupHints/locales/it/1.html
@@ -1,26 +1,95 @@
-
+
-
- Suggerimenti e consigli
-
-
+
+ Benvenuto
+
+
+
-
-
- Benvenuti in OpenBoard
-
-
-
-
- Ecco alcuni suggerimenti per aiutarti a familiarizzare con OpenBoard.
- OpenBoard è una lavagna interattiva progettata da insegnanti, per insegnanti. Dispone di 4 modalità: Modalità Lavagna, Modalità Desktop, Modalità Documenti e Modalità Web.
- Iniziamo con la prima e più importante: la Modalità Lavagna.
-
-
- Puoi riaprire il dialogo "Suggerimenti e consigli" in qualsiasi momento, utilizzando il pulsante dedicato nel menu di OpenBoard ( )
-
+
+
+
+
+
+
+ Ecco alcuni suggerimenti per aiutarti a familiarizzare con OpenBoard.
+
+
+
+ OpenBoard e una lavagna interattiva progettata da insegnanti, per insegnanti.
+ Offre quattro modalità complementari per coprire i tuoi usi in classe.
+
+
+
+ Le 4 modalita di OpenBoard
+
+
+
+
+ Prima di tutto, e cosa più importante: Modalita Lavagna .
+
+
+
+
+
+ Puoi riaprire questa finestra in qualsiasi momento tramite il pulsante
+ "Suggerimenti e consigli" nel menu OpenBoard
+ .
+
+
+
+
+
+
+
-
diff --git a/resources/startupHints/locales/it/10.html b/resources/startupHints/locales/it/10.html
index 3ceabe0b8..cf2854aa8 100644
--- a/resources/startupHints/locales/it/10.html
+++ b/resources/startupHints/locales/it/10.html
@@ -1,45 +1,95 @@
-
-
-
-
- Applicazioni
-
-
-
-
-
-
-
- OpenBoard dispone di diverse applicazioni e strumenti. Puoi accedervi cliccando su nella Libreria di OpenBoard
- Applicazioni predefinite
- Troverai strumenti geometrici, una calcolatrice, Google Map, un generatore di codici QR e altro ancora! Combinali per creare lezioni stimolanti!
-
- Crea applicazioni
- Come spiegato nella sezione Modalità Web, puoi creare applicazioni da siti web, utilizzando il navigatore interno, o copiando e incollando gli URL sulla lavagna.
- In questo modo, puoi supportare le tue lezioni con potenti strumenti online direttamente sulla lavagna! Ecco alcuni esempi di app interessanti da creare (Trascinale sulla lavagna per testarle!):
-
-
- ... e molto altro ancora!
-
- Hai bisogno di una calcolatrice più potente di quella fornita da OpenBoard? Ricorda! Puoi creare le tue applicazioni! Trascina semplicemente il seguente link sulla lavagna: https://ti89-simulator.com/
-
-
-
-
-
-
+
+
+
+
+ Applicazioni
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Accedere alle applicazioni
+
+ OpenBoard offre diverse applicazioni e strumenti .
+ Le trovi nella libreria facendo clic su
+ .
+
+
+
+
+
+ Applicazioni predefinite
+
+ Troverai strumenti geometrici, una calcolatrice, Google Maps, un generatore di QR code e molto altro.
+ Combinali per creare esperienze didattiche coinvolgenti.
+
+
+
+
+ Esempio di utilizzo delle applicazioni integrate di OpenBoard.
+
+
+
+
+
+ Crea le tue applicazioni
+
+ Come spiegato nella sezione Modalita Web , puoi creare un'applicazione da un sito,
+ usando il browser interno oppure copiando e incollando un URL sulla lavagna.
+
+
+ Questo ti permette di arricchire le lezioni con strumenti online efficaci, utilizzabili direttamente in OpenBoard.
+ Ecco alcuni esempi interessanti (trascina i link sulla lavagna per provarli):
+
+
+
+
+ ... e molto altro!
+
+
+
+
+ Hai bisogno di una calcolatrice piu avanzata di quella di OpenBoard? Crea la tua
+ applicazione trascinando questo link sulla lavagna:
+ https://ti89-simulator.com/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/11.html b/resources/startupHints/locales/it/11.html
index 86ef8f83b..88ccac629 100644
--- a/resources/startupHints/locales/it/11.html
+++ b/resources/startupHints/locales/it/11.html
@@ -1,40 +1,90 @@
-
-
-
-
- Registrazione Video
-
-
-
-
-
-
-
- Registra la tua lezione
- OpenBoard ti offre la possibilità di registrare un audio e video della tua lezione.
- Questo può essere utile, ad esempio, per condividere esercizi o informazioni aggiuntive tramite un video clip o per registrare una lezione al fine di condividerla con gli studenti assenti.
-
- In modalità Lavagna, le barre degli strumenti e le palette non appariranno nel video clip, quindi non preoccuparti di esse! Lo stesso vale in modalità Web, dove apparirà solo la scheda corrente nella registrazione.
-
- Puoi aprire questo strumento in questo modo:
-
-
- Vedrai apparire l'interfaccia seguente in basso a destra sulla lavagna bianca:
-
-
- Fai clic sul pulsante rosso per avviare la registrazione.
-
- Puoi regolare le impostazioni facendo clic su . Troverai impostazioni audio (seleziona un microfono o nessuno), impostazioni video (risoluzione della registrazione video) e opzioni di pubblicazione configurabili.
-
- Una volta completata la registrazione, verrà automaticamente salvata sul desktop del computer.
-
-
-
-
-
-
-
+
+
+
+
+ Cattura video
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Registra la tua lezione
+
+ OpenBoard permette di registrare audio e video della tua lezione.
+ Ideale per condividere esercizi aggiuntivi, pubblicare un breve video esplicativo
+ o mettere una lezione a disposizione degli studenti assenti.
+
+
+
+
+
+ In modalita Lavagna , barre degli strumenti e palette non compaiono nel video.
+ In modalita Web , viene catturata solo la scheda attiva.
+
+
+
+
+
+
+ Accedere allo strumento di registrazione
+ Apri lo strumento di cattura come mostrato qui sotto:
+
+
+
+ Accesso rapido allo strumento di registrazione dall'interfaccia di OpenBoard.
+
+
+
+
+
+ Interfaccia di controllo
+ L'interfaccia appare in basso a destra della lavagna:
+
+
+
+
+
+ Fai clic sul pulsante rosso per avviare la registrazione.
+
+
+
+
+ Personalizza la registrazione tramite
+ :
+ selezione del microfono (o nessuno), scelta della risoluzione video e opzioni di pubblicazione .
+
+
+
+
+
+
+ Terminare e recuperare il video
+
+ Una volta terminata la registrazione, il video viene automaticamente salvato sul Desktop del tuo computer.
+
+
+
+
+ Arresto della registrazione e file video disponibile sul Desktop.
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/12.html b/resources/startupHints/locales/it/12.html
index 5d621a416..26e7a7a3d 100644
--- a/resources/startupHints/locales/it/12.html
+++ b/resources/startupHints/locales/it/12.html
@@ -1,38 +1,94 @@
-
-
-
-
- Documenti Preferiti
-
-
-
-
-
-
-
- Aggiungi documenti OpenBoard ai preferiti
- Con OpenBoard 1.7, puoi aggiungere documenti OpenBoard ai tuoi preferiti!
- Per farlo, vai alla Modalità Documenti, seleziona un documento e clicca su nella barra degli strumenti dei Documenti.
-
-
-
- Cambia rapidamente tra i documenti
- I tuoi documenti preferiti appariranno nella Libreria OpenBoard, sotto
- Ogni documento OpenBoard ( ) può quindi essere trascinato sulla Lavagna!
-
-
- Puoi utilizzare la barra di ricerca in fondo alla Libreria OpenBoard per trovare rapidamente un documento per il suo nome
-
- Documenti aperti di recente
- Ogni documento che apri viene temporaneamente aggiunto ai preferiti, in modo da poter passare tra ognuno di essi durante una sessione, senza la necessità di contrassegnarli esplicitamente come preferiti.
-
- Se desideri aggiungere permanentemente un documento aperto di recente tra i tuoi preferiti, puoi farlo tramite la Libreria OpenBoard: selezionalo e clicca su
-
-
-
-
-
+
+
+
+
+ Documenti preferiti
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Aggiungere documenti OpenBoard ai preferiti
+
+ Introdotta nella versione 1.7 , questa funzionalita permette di aggiungere i tuoi documenti OpenBoard
+ ai preferiti .
+
+
+ Per farlo, passa alla modalita Documenti , seleziona un documento e fai clic su
+
+ nella barra degli strumenti.
+
+
+
+
+
+
+
+
+
+
+ Passare rapidamente da un documento all'altro
+
+ I documenti preferiti appaiono nella libreria OpenBoard , sotto
+ .
+
+
+ Ogni documento preferito
+
+ puo essere trascinato direttamente sulla lavagna.
+
+
+
+
+
+
+
+
+
+
+
+
+ Documenti aperti di recente
+
+ Ogni documento aperto viene aggiunto temporaneamente ai preferiti, per passare rapidamente da uno all'altro
+ durante la stessa sessione, senza doverli contrassegnare esplicitamente.
+
+
+
+
+
+
+
+
+
+
+ Per rendere permanente un documento aperto di recente, selezionalo nella cartella Preferiti
+ e fai clic su
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/2.html b/resources/startupHints/locales/it/2.html
index cc5e8b1c6..be85591de 100644
--- a/resources/startupHints/locales/it/2.html
+++ b/resources/startupHints/locales/it/2.html
@@ -1,48 +1,122 @@
-
-
-
-
- Modalità Lavagna
-
-
-
-
-
-
-
- La palette della penna
- La palette della penna ti offre accesso agli strumenti essenziali quando lavori su una lavagna.
-
-
- Qui troverai la penna ( ), la gomma ( ) e il marcatore ( ). OpenBoard offre anche altre funzionalità che una lavagna classica non può fornire:
-
- è il selettore. Con esso, puoi selezionare oggetti e interagire con essi.
- è il dito magico. Puoi spostare gli oggetti o interagire con essi senza la necessità di selezionarli.
- è la mano. Puoi muoverti sulla pagina con essa. Molto utile quando combinata con le funzioni di zoom!
- ti danno la possibilità di ingrandire e rimpicciolire. Scegli semplicemente quello che desideri e fai clic sulla pagina dove vuoi applicare lo zoom!
- è un puntatore laser, utile per evidenziare elementi sulla lavagna senza interagire con essi.
- è utilizzato per disegnare linee rette facilmente.
- è uno strumento di testo, per scrivere un testo utilizzando la tastiera invece della penna.
-
-
- Puoi avere un controllo più preciso dello zoom con il mouse! Usa Ctrl/Cmd + la rotellina del mouse per ingrandire/ridurre con maggiore precisione!
-
- La barra degli strumenti della lavagna
- La barra degli strumenti della lavagna ti offre la possibilità di cambiare colore e dimensione della penna o del marcatore, tra altre cose.
-
-
- Troverai anche la possibilità di cambiare lo sfondo della lavagna, cliccando su
-
-
- Troverai anche pulsanti per annullare/ripristinare azioni, creare e navigare tra le pagine, cancellare l'intera lavagna, ...
-
- Puoi cancellare parti più precise della lavagna facendo clic prolungato su . Alcune funzioni nascoste anche su !
-
-
-
-
-
+
+
+
+
+ Modalita Lavagna
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Il tavolo-bar
+
+ La barra della tabella consente di modificare il colore e/o il misurare matita ed evidenziatore, tra le altre cose.
+
+
+
+
+
+
+
+ Puoi anche modificare il file sfondo del tavolo cliccando su
+ .
+
+
+
+
+
+
+
+ Sono disponibili altre funzioni: annullare/rifare , creare pagine, navigare tra le pagine, cancellare la tabella, ecc.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/3.html b/resources/startupHints/locales/it/3.html
index fef4192ba..4874db0b0 100644
--- a/resources/startupHints/locales/it/3.html
+++ b/resources/startupHints/locales/it/3.html
@@ -1,31 +1,74 @@
-
-
-
-
- Modalità Desktop
-
-
-
-
-
-
-
- Interagire con altri software
- Utilizzando la Modalità Desktop, puoi interagire con l'intero computer e altri software, mantenendo OpenBoard come sovrapposizione!
- Basta cliccare sull'icona seguente:
-
- Usa il selettore (
) per interagire con il desktop e altri software.
- Fare annotazioni sopra un'applicazione o un sito web
- Puoi aggiungere annotazioni sopra qualsiasi software, utilizzando la penna (
) o il marcatore (
).
-
-
- Puoi accedere a ulteriori opzioni per , e facendo un clic prolungato su di essi o facendo clic sulla piccola freccia nera.
-
-
-
-
-
+
+
+
+
+ Modalita Desktop
+
+
+
+
+
+
+
+
+
+
+
+
+ Interagire con altre applicazioni
+
+ La modalita Desktop ti permette di interagire con il sistema operativo e le tue applicazioni,
+ mantenendo gli strumenti di OpenBoard sempre in primo piano.
+
+ Fai semplicemente clic sull'icona seguente:
+
+
+
+
+
+
+ Usa il selettore
+
+ per interagire con il desktop e con le altre applicazioni.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/4.html b/resources/startupHints/locales/it/4.html
index c12820ed1..2c498f229 100644
--- a/resources/startupHints/locales/it/4.html
+++ b/resources/startupHints/locales/it/4.html
@@ -1,33 +1,79 @@
-
-
-
-
- Modalità Documenti
-
-
-
-
-
-
-
- OpenBoard dispone di un gestore documenti. Puoi accedervi semplicemente facendo clic su
-
-
- Crea cartelle e organizza il tuo lavoro
- Puoi creare una cartella cliccando sull'icona "Nuova Cartella". Assegnale un nome e trascina i tuoi documenti all'interno. Allo stesso modo, puoi spostare un'intera cartella in un'altra.
-
-
- Gestisci le pagine
- Un documento OpenBoard può contenere molte pagine. Puoi duplicarle, spostarle nel cestino o in un altro documento, crearne di nuove da cartelle di immagini, ...
-
-
- Tieni presente che le azioni disponibili vengono aggiornate in base a ciò che è selezionato
-
-
-
-
-
+
+
+
+
+ Modalita Documenti
+
+
+
+
+
+
+
+
+
+
+
+
+ Accedere al gestore documenti
+
+ OpenBoard offre un gestore documenti . Fai clic su
+
+ per aprirlo.
+
+
+
+
+
+
+
+
+ Crea cartelle e organizza il tuo lavoro
+
+ Crea una cartella tramite
+ ,
+ assegnale un nome, poi trascina e rilascia i documenti al suo interno.
+ Allo stesso modo puoi spostare un'intera cartella dentro un'altra.
+
+
+
+ Esempio di creazione e organizzazione delle cartelle.
+
+
+
+
+
+ Gestione delle pagine
+
+ Un documento OpenBoard puo contenere piu pagine . Dalla modalita Documenti puoi:
+
+
+ Duplicare pagine
+ Inviarle nel cestino
+ Copiarle in un altro documento
+ Creare nuove pagine a partire da una cartella di immagini
+
+
+
+ Esempio di gestione dei documenti.
+
+
+
+
+
+ Le azioni disponibili si adattano in base a cio che e
+ selezionato (cartella, documento, pagina).
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/5.html b/resources/startupHints/locales/it/5.html
index 145fa7b6d..61a3184c4 100644
--- a/resources/startupHints/locales/it/5.html
+++ b/resources/startupHints/locales/it/5.html
@@ -1,40 +1,104 @@
-
-
-
-
- Modalità Documenti
-
-
-
-
-
-
-
- In questa modalità troverai anche due funzionalità molto importanti: Importa ed Esporta.
-
-
- Importa
- Puoi importare file PDF (.pdf ), immagini (.png , .jpg ), documenti OpenBoard (.ubz ) o cartelle OpenBoard (.ubx ) cliccando su
-
- Nota che puoi anche importare un documento OpenBoard (.ubz ) facendo doppio clic su di esso. Si aprirà OpenBoard se non è già aperto e lo importerà (o chiederà di sostituirlo se esiste già).
- Puoi anche importare più elementi contemporaneamente, senza dover fare clic su nuovamente e nuovamente.
- Esporta
- Puoi esportare un documento OpenBoard in formato PDF o UBZ e una cartella OpenBoard in formato UBX. Pertanto, puoi, ad esempio:
-
- Salvare il lavoro svolto durante una sessione di classe e condividerlo con uno studente assente
- Condividerlo con altri insegnanti o archiviarlo su un dispositivo USB e aprirlo su un altro computer
- Importare i compiti di uno studente in formato PDF, annotarli e esportare il PDF annotato per restituirlo allo studente
-
-
-
-
- Esporta tutti i tuoi documenti selezionando la cartella "I miei documenti" prima di fare clic sul pulsante di esportazione, per esportarla come file UBX, e quindi importala su un altro computer. È anche un buon modo per fare un backup del tuo lavoro!
-
-
-
-
-
+
+
+
+
+ Importare ed esportare
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Import & Export
+
+ In questa modalita hai due funzionalita essenziali: importazione ed esportazione .
+
+
+
+
+
+
+
+
+
+ Importare contenuti
+
+ Puoi importare file PDF (.pdf ),
+ immagini (.png , .jpg ),
+ documenti OpenBoard (.ubz ) o
+ cartelle OpenBoard (.ubx ) facendo clic su
+ .
+
+
+
+
+
+ Esempio di importazione di file in OpenBoard.
+
+
+
+ Puoi anche importare un documento OpenBoard (.ubz )
+ facendo doppio clic dal tuo sistema. OpenBoard si avviera, se necessario,
+ e ti proporra di importarlo (o sostituirlo se esiste gia).
+
+
+
+
+
+ E possibile importare piu elementi in una sola volta ,
+ senza dover ricliccare su
+
+ ogni volta.
+
+
+
+
+
+
+ Esportare i tuoi documenti
+
+ Puoi esportare un documento OpenBoard in formato PDF o UBZ ,
+ e una cartella OpenBoard in formato UBX . Ad esempio:
+
+
+ Salvare il lavoro svolto durante una lezione e condividerlo con uno studente assente.
+ Condividerlo con altri insegnanti o salvarlo su una chiavetta USB per importarlo altrove.
+ Importare il lavoro di uno studente in PDF, annotarlo ed esportare il PDF annotato per rimandarlo.
+
+
+
+
+ Esempio di esportazione di file da OpenBoard.
+
+
+
+
+
+ Per esportare tutti i tuoi documenti , seleziona prima la cartella radice
+ I miei documenti , poi fai clic su
+ .
+ Otterrai un file UBX importabile su un altro computer, perfetto per un
+ backup o un archivio completo.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/6.html b/resources/startupHints/locales/it/6.html
index 29d400c2b..cc6d85b91 100644
--- a/resources/startupHints/locales/it/6.html
+++ b/resources/startupHints/locales/it/6.html
@@ -1,39 +1,95 @@
-
-
-
-
- Modalità Web
-
-
-
-
-
-
-
- La Modalità Web è un browser interno che aggiunge alcune funzionalità interessanti a uno più standard.
- Usa il browser interno
- Utilizzando il browser interno, sarai in grado di navigare su Internet senza la necessità di ridurre o uscire da OpenBoard, con alcune funzionalità aggiuntive che ti consentiranno di catturare parte dello schermo o creare applicazioni dai siti web e aggiungerle alla lavagna!
-
-
-
- Crea un'applicazione
- Puoi creare un'applicazione da qualsiasi sito web, in modo da aggiungerla alla lavagna e interagire con essa come con le applicazioni predefinite.
- Per farlo, vai al sito web che desideri catturare, fai clic su e conferma la creazione cliccando su "Crea un'applicazione".
-
-
- Quando un'applicazione viene creata, viene automaticamente salvata nella libreria di OpenBoard, in modo da poterla utilizzare in qualsiasi documento. Le troverai nella cartella delle applicazioni, sotto una dedicata chiamata "Web".
-
-
-
- Usa un browser esterno
- Puoi anche scegliere di utilizzare un browser esterno, selezionando l'opzione corrispondente nelle preferenze. Cliccando sull'icona Web lancerà il tuo browser preferito in Modalità Desktop.
- Usando un browser esterno, sarai comunque in grado di creare applicazioni da un sito web, copiando l'URL nella barra degli indirizzi del tuo browser, tornando su Board e incollandolo!
-
-
-
-
-
+
+
+
+
+ Modalita Web
+
+
+
+
+
+
+
+
+
+
+
+
+ Il browser integrato
+
+ La modalita Web e un browser interno di OpenBoard che aggiunge, rispetto a un browser
+ tradizionale, funzioni molto utili per la didattica.
+
+
+ Permette di navigare su Internet senza uscire da OpenBoard, catturare contenuti (parziali o a schermo intero)
+ e perfino creare applicazioni a partire da siti web per riutilizzarle nei tuoi documenti.
+
+
+
+
+
+
+
+
+
+ Creare un'applicazione a partire da un sito
+
+ Da qualsiasi sito puoi creare una applicazione da aggiungere alla lavagna
+ e utilizzare come le applicazioni predefinite.
+
+
+ Apri il sito desiderato, fai clic su
+
+ e conferma selezionando Crea un'applicazione .
+
+
+
+
+ Creazione di un'applicazione dalla modalita Web.
+
+
+
+ Una volta creata, l'applicazione viene salvata automaticamente nella
+ libreria OpenBoard . La troverai in Applicazioni > Web
+ e potrai riutilizzarla in qualsiasi documento.
+
+
+
+
+ Ritrovare un'applicazione creata nella libreria.
+
+
+
+
+
+ Usare un browser esterno
+
+ Puoi scegliere di aprire i link in un browser esterno attivando
+ l'opzione nelle preferenze. Facendo clic su
+
+ verra avviato il tuo browser preferito in modalita Desktop.
+
+
+
+
+
+ Anche con un browser esterno puoi creare un'applicazione da un sito:
+ copia l'URL dalla barra degli indirizzi, torna in modalita Lavagna e incollala
+ quando crei l'applicazione.
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/7.html b/resources/startupHints/locales/it/7.html
index f5f9484b7..a2c8b7fee 100644
--- a/resources/startupHints/locales/it/7.html
+++ b/resources/startupHints/locales/it/7.html
@@ -1,45 +1,102 @@
-
-
-
-
- Cattura Schermo
-
-
-
-
-
-
-
- Una delle funzionalità più semplici ma davvero utili di OpenBoard è la cattura schermo. Con essa, puoi creare uno snapshot di uno stato particolare della lavagna durante la tua sessione di classe.
- In Modalità Lavagna
- Cerca nella palette dello stilo, cliccaci sopra e seleziona l'area da catturare. Successivamente, avrai tre opzioni :
-
- Aggiungi alla pagina corrente
- Aggiungi in una nuova pagina
- Aggiungi alla libreria (aggiunge la cattura alla cartella Immagini, in modo da poterla riutilizzare in qualsiasi momento)
-
-
- Ecco un esempio di tutto il processo :
-
-
- Non devi preoccuparti della palette dello stilo, della vista delle miniature della lavagna o della libreria di OpenBoard, non verranno catturati dal tuo lasso!
-
- In Modalità Desktop
- Puoi fare la stessa cosa anche in Modalità Desktop per catturare il tuo lavoro su altri software. Vai in Modalità Desktop cliccando su
- Troverai due icone : per catturare l'intero schermo e per catturare solo una parte. Come in Modalità Lavagna, dovrai scegliere dove posizionare la cattura effettuata
-
- Ecco un'illustrazione di tutto il processo
-
-
-
- In Modalità Web
- Di nuovo, lo stesso processo è disponibile in Modalità Web, dove sarai in grado di catturare solo una parte dello schermo o catturare la scheda corrente con
-
-
-
-
-
+
+
+
+
+ Cattura schermo
+
+
+
+
+
+
+
+
+
+
+
+ Une fonctionnalité simple et très utile
+
+ La cattura schermo ti permette di creare un istantanea dello stato della lavagna (o dello schermo)
+ durante la lezione, per archiviare, condividere o riutilizzare i contenuti.
+
+
+
+
+
+ In modalita Lavagna
+
+ Nella palette degli strumenti, fai clic su
+ ,
+ poi seleziona la zona da catturare. In seguito potrai scegliere:
+
+
+ Aggiungi alla pagina corrente
+ Aggiungi a una nuova pagina
+
+ Aggiungi alla libreria — la cattura viene salvata nella cartella Immagini
+ per un uso successivo.
+
+
+
+
+
+ Esempio di integrazione di una cattura schermo in OpenBoard.
+
+
+
+
+
+ La palette strumenti, l'anteprima pagine e la scheda libreria non vengono catturate
+ dal lazo: vengono catturate solo annotazioni e contenuti.
+
+
+
+
+
+
+ In modalita Desktop
+
+ Passa alla modalita Desktop tramite
+
+ per catturare altre applicazioni.
+
+ Sono disponibili due opzioni:
+
+
+
+ Cattura schermo intero
+
+
+
+ Cattura di un'area
+
+
+ Come in modalita Lavagna, scegli dove aggiungere la cattura.
+
+
+
+ Cattura schermo completa o parziale in modalita Desktop.
+
+
+
+
+
+ In modalita Web
+
+ In modalita Web puoi catturare un'area dello schermo oppure
+ catturare la scheda attiva del browser con
+ .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/8.html b/resources/startupHints/locales/it/8.html
index 5f40e7f21..b452fbe01 100644
--- a/resources/startupHints/locales/it/8.html
+++ b/resources/startupHints/locales/it/8.html
@@ -1,37 +1,102 @@
-
-
-
-
- Immagini
-
-
-
-
-
-
-
- In OpenBoard, puoi accedere alle immagini in diversi modi.
- Organizza la tua cartella Immagini
- Le catture dello schermo aggiunte alla Libreria vengono salvate nella cartella Immagini : Puoi creare cartelle utilizzando nella parte inferiore della Libreria. Quindi, trascina e rilascia le tue immagini nelle diverse cartelle che hai creato.
-
-
- Non importa dove ti trovi nella Libreria di OpenBoard, le immagini che aggiungi saranno automaticamente collocate all'interno della cartella Immagini, per mantenere l'organizzazione.
-
- Aggiungi immagini dal tuo computer
- Puoi anche aggiungere immagini direttamente dal tuo computer, come illustrato di seguito :
-
-
- Aggiungi immagini dai motori di ricerca
- Ultimo ma non meno importante, puoi cercare e aggiungere alla tua lavagna immagini royalty free utilizzando i motori di ricerca situati nella cartella Ricerca Web :
-
-
- Al posto di utilizzare il trascinamento, basta fare clic su una delle immagini restituite dalla tua ricerca per visualizzare i dettagli sull'immagine e trovare un'opzione per aggiungerla alla Libreria senza aggiungerla al tuo documento attuale. Utile quando si prepara una lezione!
-
-
-
-
-
+
+
+
+
+ Images
+
+
+
+
+
+
+
+
+
+
+
+ Accedere e organizzare le immagini
+
+ In OpenBoard puoi accedere e aggiungere immagini in diversi modi dalla tua libreria . La libreria si trova a destra dello schermo. Qui puoi anche archiviare suoni, video e trovare varie applicazioni.
+
+
+
+ Vista della libreria posizionata a destra nel software.
+
+
+
+
+
+
+
+
+ Aggiungere immagini dal computer
+
+ Puoi importare i tuoi file immagine direttamente in OpenBoard, come mostrato qui sotto:
+
+
+
+
+ Importazione di un'immagine locale in OpenBoard.
+
+
+
+
+
+ Aggiungere immagini dal Web
+
+ Puoi anche cercare immagini libere da diritti tramite i motori di ricerca integrati,
+ disponibili nella cartella Ricerca Web
+ .
+
+
+
+
+ Esempio di ricerca e aggiunta di immagini dal Web.
+
+
+
+
+
+ Non serve trascinare: fai clic su un'immagine trovata per vedere i dettagli
+ e usa direttamente l'opzione Aggiungi alla libreria .
+ E molto pratico durante la preparazione delle lezioni.
+
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/9.html b/resources/startupHints/locales/it/9.html
index 62545121c..f03391097 100644
--- a/resources/startupHints/locales/it/9.html
+++ b/resources/startupHints/locales/it/9.html
@@ -1,44 +1,99 @@
-
-
-
-
- Interattività
-
-
-
-
-
-
-
- Per gli studenti più giovani, troverai un set dedicato di applicazioni personalizzabili.
- Esercizi interattivi di OpenBoard
- Utilizzando queste interattività, puoi creare diversi tipi di esercizi personalizzati. Questi possono riguardare la categorizzazione, i calcoli, la memorizzazione e così via.
- Le interattività si trovano nella Libreria di OpenBoard : clicca su per trovarle.
-
- Esempio
- Come esempio, creeremo un esercizio utilizzando l'interattività "Cat egorizza immagini " :
- Provalo! Sposta questa finestra di dialogo da un lato e riproduci l'esempio sulla lavagna!
- Prima, trascina e rilascia l'interattività sulla tua lavagna e clicca su "Modifica"
- Quindi, cambia il nome delle categorie secondo le tue esigenze :
-
-
- Puoi aggiungere o eliminare categorie usando le icone + e -
-
- Successivamente, aggiungi le immagini che desideri nella categoria corrispondente.
-
-
- Infine, clicca su "Visualizza" per mostrare il risultato e svolgere l'esercizio.
-
-
- Puoi ripetere l'esercizio utilizzando l'icona "Ricarica".
-
-
-
-
-
-
-
+
+
+
+
+ Interattivita
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Esercizi interattivi, semplici da personalizzare
+
+ Per gli alunni piu giovani (e non solo), OpenBoard offre un insieme di
+ interattivita personalizzabili: categorizzazione, calcolo mentale, memorizzazione, ecc.
+
+
+ Sono disponibili nella libreria : fai clic su
+ .
+
+
+
+
+
+ Esempio: "Categorize Pictures"
+
+ Creiamo un esercizio con l'interattivita
+ Cat egorize pict ures (categorizzare immagini):
+ .
+
+
+
+
+ 1) Posizionare l'interattivita e aprire l'editor
+
+ Trascina l'interattivita sulla lavagna, poi fai clic su Modifica .
+
+
+ 2) Dare un nome alle categorie
+
+ Rinomina le categorie secondo le tue esigenze. Puoi anche
+ aggiungere o eliminare categorie con le icone "+" e "-".
+
+
+
+
+ Modifica categorie: aggiunta, eliminazione, rinomina.
+
+
+ 3) Aggiungere le immagini
+
+ Aggiungi le immagini corrispondenti a ogni categoria (trascinamento, selezione dalla libreria, ecc.).
+
+
+
+
+ Associare immagini alle categorie definite.
+
+
+ 4) Avviare e svolgere l'esercizio
+
+ Fai clic su Mostra per avviare l'attivita in modalita studente.
+
+
+
+
+ Esecuzione dell'esercizio: spostare le immagini nella categoria corretta.
+
+
+
+
+
+ Per riavviare l'esercizio, usa l'icona Ricarica .
+
+
+
+
+
+
+
+
diff --git a/resources/startupHints/locales/it/css/style.css b/resources/startupHints/locales/it/css/style.css
deleted file mode 100644
index de0ecb4d5..000000000
--- a/resources/startupHints/locales/it/css/style.css
+++ /dev/null
@@ -1,36 +0,0 @@
-*{
- font-family: Arial, Helvetica, sans-serif;
-}
-
-.title
-{
- width:100%;
- color: #6682b5;
- text-align: center;
-}
-
-.file-extension
-{
- background: lightgrey;
-}
-
-.image
-{
- text-align:center;
-}
-
-.image img
-{
- max-width: 600px;
-}
-
-.icon
-{
- vertical-align: middle;
-}
-
-.tip
-{
- font-style: italic;
- font-size: 0.8rem;
-}
diff --git a/resources/startupHints/locales/it/error.html b/resources/startupHints/locales/it/error.html
index 05ddb6b3a..cedc7403b 100644
--- a/resources/startupHints/locales/it/error.html
+++ b/resources/startupHints/locales/it/error.html
@@ -1,15 +1,20 @@
-
-
-
-
- errore
-
-
-
-
-
-Qualcosa è andato storto...
-Verifica l'esistenza dei tuoi suggerimenti nella cartella
-/Resources/startupHints/ …
-
-
+
+
+
+
+ Errore
+
+
+
+
+
+
+ Errore di caricamento
+
+ Si e verificato un problema.
+ Verifica la presenza delle pagine dei suggerimenti nella cartella
+ /Resources/startupHints/ .
+
+
+
+
diff --git a/resources/style.qss b/resources/style.qss
index 92bd8d6b5..32840a69d 100644
--- a/resources/style.qss
+++ b/resources/style.qss
@@ -9,24 +9,29 @@ QWidget#UBFeaturesNavigatorWidget,
QWidget#PathList,
QWidget#UBFeaturesCentralWidget
{
- background: #EEEEEE;
+ background: palette(window);
border-radius: 10px;
- border: 2px solid #999999;
+ border: 2px solid palette(mid);
+ color: palette(window-text);
}
QTextEdit,
QLineEdit,
QComboBox#DockPaletteWidgetComboBox QAbstractItemView
{
- selection-background-color: lightgreen;
- selection-color: black;
+ selection-background-color: palette(highlight);
+ selection-color: palette(highlighted-text);
+ background-color: palette(base);
+ color: palette(text);
}
QWidget#mAdditionalDataContainer
{
border-radius: 10px;
- border: 2px solid #999999;
+ border: 2px solid palette(mid);
+ background: palette(window);
+ color: palette(window-text);
}
QWidget#UBMediaVideoContainer
@@ -38,9 +43,10 @@ QWidget#UBMediaVideoContainer
QWidget#UBLibWebView
{
- background: #EEEEEE;
+ background: palette(window);
border-radius : 10px;
- border: 2px solid #999999;
+ border: 2px solid palette(mid);
+ color: palette(window-text);
}
QListView
@@ -55,40 +61,113 @@ QWidget#UBFeatureProperties
QWebView#SearchEngineView
{
- background:white;
+ background: palette(base);
+ color: palette(text);
}
QColorDialog
{
- background: #EEEEEE;
+ background: palette(window);
+ color: palette(window-text);
+}
+
+QToolBar QToolButton
+{
+ margin: 4px;
+ margin-left: 0px;
+ margin-right: 0px;
+ padding: 0px;
+ border: none;
+ height: 58px;
+ background: transparent;
+}
+
+/* Preserve grouped toolbar button geometry across platforms. */
+QToolButton#ubButtonGroupLeft,
+QToolButton#desktop-ubButtonGroupLeft
+{
+ margin-top: 1px;
+ margin-right: 0px;
+ padding: 5px;
+ height: 14px;
+}
+
+QToolButton#ubButtonGroupCenter,
+QToolButton#desktop-ubButtonGroupCenter
+{
+ margin-top: 1px;
+ margin-right: 0px;
+ margin-left: 0px;
+ padding: 5px;
+ height: 14px;
+}
+
+QToolButton#ubButtonGroupRight,
+QToolButton#desktop-ubButtonGroupRight
+{
+ margin-top: 1px;
+ margin-left: 0px;
+ padding: 5px;
+ height: 14px;
+}
+
+QToolButton#ubButtonGroupLeft:checked,
+QToolButton#desktop-ubButtonGroupLeft:checked
+{
+ padding-right: 4px;
+}
+
+QToolButton#ubButtonGroupCenter:checked,
+QToolButton#desktop-ubButtonGroupCenter:checked
+{
+ padding-right: 4px;
+ padding-left: 4px;
+}
+
+QToolButton#ubButtonGroupRight:checked,
+QToolButton#desktop-ubButtonGroupRight:checked
+{
+ padding-left: 4px;
}
QLabel#DockPaletteWidgetTitle
{
- color: #FFFFFF;
+ color: palette(bright-text);
font-size : 18px;
font-weight:bold;
}
+QWidget#UBPageNavigationWidget QLabel
+{
+ color: palette(window-text);
+ background-color: transparent;
+ border: none;
+ font-family: Arial;
+ font-weight: bold;
+ font-size: 20px;
+}
+
QLineEdit#UBTGLineEdit,
QLabel#UBTGMediaDropMeLabel
{
- background: white;
- border: 1 solid #999999;
+ background: palette(base);
+ color: palette(text);
+ border: 1 solid palette(mid);
border-radius : 10px;
padding: 2px;
}
QComboBox#DockPaletteWidgetComboBox
{
- background: white;
+ background: palette(base);
+ color: palette(text);
border-radius : 10px;
padding: 2px;
}
QComboBox#DockPaletteWidgetComboBox:drop-down
{
- background: white;
+ background: palette(base);
width:1px;
height:1px;
margin: 9px 5px 0px 0px;
@@ -96,9 +175,9 @@ QComboBox#DockPaletteWidgetComboBox:drop-down
QComboBox#DockPaletteWidgetComboBox::down-arrow
{
- image:url(:/images/down_arrow.png);
- background:#BBBBBB;
- border: 2px solid #999999;
+ image:url(:/images/down_arrow.svg);
+ background: palette(button);
+ border: 2px solid palette(mid);
height:16px;
width:16px;
padding: 0px 0px 0px 0px;
@@ -108,8 +187,8 @@ QComboBox#DockPaletteWidgetComboBox::down-arrow
QPushButton#DockPaletteWidgetButton
{
- background-color : #DDDDDD;
- color : #555555;
+ background-color : palette(button);
+ color : palette(button-text);
border-radius : 6px;
padding : 5px;
font-weight : bold;
@@ -118,138 +197,87 @@ QPushButton#DockPaletteWidgetButton
QTextEdit#TeacherStudentBox
{
- background: white;
- border: 2px solid #999999;
+ background: palette(base);
+ color: palette(text);
+ border: 2px solid palette(mid);
border-radius: 10px;
}
QPushButton#DockPaletteWidgetButton::checked
{
- background-color: #BBBBBB;
-}
-
-QScrollBar::vertical
-{
- background:transparent;
- margin: 23px 1px 25px 1px;
-}
-
-QScrollBar::handle:vertical
-{
- border: 2px solid #999999;
- border-radius:6px;
- background:#BBBBBB;
- min-height:40px;
-}
-
-QScrollBar::add-line:vertical
-{
- image:url(:/images/down_arrow.png);
- height:16px;
- background:#BBBBBB;
- border:2px solid #999999;
- border-radius:6px;
- margin: 1px 1px 4px 1px;
- subcontrol-position:bottom;
- subcontrol-origin:margin;
-}
-
-QScrollBar::sub-line:vertical
-{
- image:url(:/images/up_arrow.png);
- height:16px;
- background:#BBBBBB;
- border:2px solid #999999;
- border-radius:6px;
- margin: 2px 1px 1px 1px;
- subcontrol-position:top;
- subcontrol-origin:margin;
-}
-
-QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
-{
- background:transparent;
-}
-
-QScrollBar::horizontal
-{
- background:transparent;
- margin: 1px 23px 1px 25px;
-}
-
-QScrollBar::handle:horizontal
-{
- border: 2px solid #999999;
- border-radius:6px;
- background:#BBBBBB;
- min-width:40px;
-}
-
-QScrollBar::add-line:horizontal
-{
- image:url(:/images/right_arrow.png);
- width:16px;
- background:#BBBBBB;
- border:2px solid #999999;
- border-radius:6px;
- margin: 1px 1px 1px 4px;
- subcontrol-position:right;
- subcontrol-origin:margin;
-}
-
-QScrollBar::sub-line:horizontal
-{
- image:url(:/images/left_arrow.png);
- width:16px;
- background:#BBBBBB;
- border:2px solid #999999;
- border-radius:6px;
- margin: 1px 2px 1px 1px;
- subcontrol-position:left;
- subcontrol-origin:margin;
-}
-
-QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
-{
- background:transparent;
+ background-color: palette(highlight);
+ color: palette(highlighted-text);
+ border: 1px solid palette(highlight);
}
QSlider::handle::horizontal
{
- background-color:#EEEEEE;
+ background-color: palette(button);
margin-top:-5px;
margin-bottom:-5px;
height:20px;
width:18px;
border-radius:10px;
- border:1px solid #555555;
+ border: 1px solid palette(dark);
}
QSlider::groove::horizontal
{
- background-color:#999999;
+ background-color: palette(mid);
height:10px;
border-radius:5px;
- border:1px solid #555555;
+ border: 1px solid palette(dark);
+}
+
+QTreeView::branch:has-siblings:!adjoins-item,
+QTreeView::branch:!has-children:!has-siblings:adjoins-item,
+QTreeView::branch:has-siblings:adjoins-item
+{
+ border-image: none;
+ image: none;
+ width: 12px;
+ height: 12px;
+}
+
+QTreeView::branch:has-children:!has-siblings:closed,
+QTreeView::branch:closed:has-children:has-siblings,
+QTreeView::branch:selected:has-children:!has-siblings:closed,
+QTreeView::branch:selected:closed:has-children:has-siblings
+{
+ border-image: none;
+ image: url(:/images/right_arrow.svg);
+ width: 12px;
+ height: 12px;
+}
+
+QTreeView::branch:open:has-children:!has-siblings,
+QTreeView::branch:open:has-children:has-siblings,
+QTreeView::branch:selected:open:has-children:!has-siblings,
+QTreeView::branch:selected:open:has-children:has-siblings
+{
+ border-image: none;
+ image: url(:/images/down_arrow.svg);
+ width: 12px;
+ height: 12px;
}
QLabel#UBTGEditionDocumentTitle
{
- color: black;
+ color: palette(text);
font-size : 14px;
font-weight:bold;
}
QLabel#UBTGPresentationDocumentTitle
{
- color: black;
+ color: palette(text);
font-size : 12px;
font-weight:bold;
}
QLabel#UBTGPageNumberLabel
{
- color: black;
+ color: palette(text);
font-size : 12px;
font-weight:bold;
}
@@ -257,13 +285,13 @@ QLabel#UBTGPageNumberLabel
UBTGAdaptableText#UBTGEditionPageTitle,
UBTGAdaptableText#UBTGEditionComment
{
- color: black;
+ color: palette(text);
font-size : 12px;
}
UBTGAdaptableText#UBTGPresentationPageTitle
{
- color: black;
+ color: palette(text);
font-size:16px;
font-weight:bold;
border : none;
@@ -271,19 +299,67 @@ UBTGAdaptableText#UBTGPresentationPageTitle
UBTGAdaptableText#UBTGPresentationComment
{
- color: black;
+ color: palette(text);
font-size:12px;
border : none;
}
QFrame#UBTGSeparator
{
- background-color: #cccccc;
+ background-color: palette(mid);
}
UBTGAdaptableText {
- background-color: white;
- border:1 solid #999999;
+ background-color: palette(base);
+ color: palette(text);
+ border: 1 solid palette(mid);
border-radius : 10px;
padding: 2px;
}
+
+/* Features Action Bar and Widgets */
+QWidget#UBFeaturesActionBar {
+ background: palette(window);
+ border-radius: 10px;
+ border: 2px solid palette(mid);
+}
+
+QLineEdit#FeaturesSearchBar {
+ background-color: palette(base);
+ color: palette(text);
+ border-radius: 10px;
+ padding: 2px;
+ border: 1px solid palette(mid);
+}
+
+QPushButton#UBFeatureItemButton {
+ background-color: palette(button);
+ color: palette(button-text);
+ border-radius: 6px;
+ padding: 5px;
+ font-weight: bold;
+ font-size: 12px;
+ border: 1px solid palette(mid);
+}
+
+QPushButton#UBFeatureItemButton:pressed,
+QPushButton#UBFeatureItemButton:checked,
+QPushButton#UBFeatureItemButton:default {
+ background-color: palette(highlight);
+ color: palette(highlighted-text);
+ border: 1px solid palette(highlight);
+}
+
+QLabel#UBFeatureInfoLabel {
+ color: palette(mid);
+ font-size: 18px;
+ font-weight: bold;
+}
+
+QLineEdit[invalid="true"] {
+ background: #FFB3C8;
+}
+
+QLineEdit[invalid="false"] {
+ background: palette(base);
+}
diff --git a/resources/style/treeview-branch-closed.png b/resources/style/treeview-branch-closed.png
deleted file mode 100644
index 2c566533e..000000000
Binary files a/resources/style/treeview-branch-closed.png and /dev/null differ
diff --git a/resources/style/treeview-branch-open.png b/resources/style/treeview-branch-open.png
deleted file mode 100644
index 58fa30625..000000000
Binary files a/resources/style/treeview-branch-open.png and /dev/null differ
diff --git a/src/adaptors/CMakeLists.txt b/src/adaptors/CMakeLists.txt
index ef91e1096..107edbafc 100644
--- a/src/adaptors/CMakeLists.txt
+++ b/src/adaptors/CMakeLists.txt
@@ -1,10 +1,6 @@
target_sources(${PROJECT_NAME} PRIVATE
- UBCFFSubsetAdaptor.cpp
- UBCFFSubsetAdaptor.h
UBExportAdaptor.cpp
UBExportAdaptor.h
- UBExportCFF.cpp
- UBExportCFF.h
UBExportDocument.cpp
UBExportDocument.h
UBExportDocumentSetAdaptor.cpp
@@ -17,8 +13,6 @@ target_sources(${PROJECT_NAME} PRIVATE
UBExportWeb.h
UBImportAdaptor.cpp
UBImportAdaptor.h
- UBImportCFF.cpp
- UBImportCFF.h
UBImportDocument.cpp
UBImportDocument.h
UBImportDocumentSetAdaptor.cpp
@@ -29,6 +23,8 @@ target_sources(${PROJECT_NAME} PRIVATE
UBImportPDF.h
UBMetadataDcSubsetAdaptor.cpp
UBMetadataDcSubsetAdaptor.h
+ UBPageMapper.cpp
+ UBPageMapper.h
UBSvgSubsetAdaptor.cpp
UBSvgSubsetAdaptor.h
UBThumbnailAdaptor.cpp
diff --git a/src/adaptors/UBCFFSubsetAdaptor.cpp b/src/adaptors/UBCFFSubsetAdaptor.cpp
deleted file mode 100644
index bec770dcf..000000000
--- a/src/adaptors/UBCFFSubsetAdaptor.cpp
+++ /dev/null
@@ -1,1570 +0,0 @@
-/*
- * Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
- *
- * Copyright (C) 2013 Open Education Foundation
- *
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
- * l'Education Numérique en Afrique (GIP ENA)
- *
- * This file is part of OpenBoard.
- *
- * OpenBoard 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).
- *
- * OpenBoard is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenBoard. If not, see .
- */
-
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "core/UBApplication.h"
-#include "core/UBDisplayManager.h"
-#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/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, std::shared_ptr 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(std::shared_ptrproxy, 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(' '), UB::SplitBehavior::SkipEmptyParts);
-
- foreach(const QString sPoint, ts) {
- QStringList sCoord = sPoint.split(QLatin1Char(','), UB::SplitBehavior::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.toString());
-
- }
- 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();
- mRefToUuidMap.insert(element.attribute(aId), uuid.toString());
- 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(' '),
- UB::SplitBehavior::SkipEmptyParts);
-
- foreach(const QString sPoint, ts) {
- QStringList sCoord = sPoint.split(QLatin1Char(','), UB::SplitBehavior::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.toString());
-
- }
- 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 lines
- //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. / UBApplication::displayManager->logicalDpi(ScreenRole::Control);
-
- 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()) {
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
- format.setFontFamilies(QStringList(fontFamilyText));
-#else
- format.setFontFamily(fontFamilyText);
-#endif
- }
- 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().windowText().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).boundingRect(element.text()).width() + 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().windowText().color());
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
- textFormat.setFontFamilies(QStringList("Arial"));
-#else
- textFormat.setFontFamily("Arial");
-#endif
- 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();
- }
-
-
-
- const auto keys = strokesGroupsContainer.keys();
- for (const QString &key : keys)
- {
- 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;
- pStrokesGroup = nullptr;
- }
-
- 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);
- std::shared_ptr 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%)'
- static const QRegularExpression regexp(QRegularExpression::anchoredPattern("rgb\\(([0-9]+%{0,1}),([0-9]+%{0,1}),([0-9]+%{0,1})\\)"));
- QRegularExpressionMatch match = regexp.match(clrString);
- if (match.hasMatch())
- {
- if (match.lastCapturedIndex() == 3 && match.capturedTexts().at(0).length() == clrString.length())
- {
- int r = match.capturedTexts().at(1).toInt();
- if (match.capturedTexts().at(1).indexOf("%") != -1)
- r = r * 255 / 100;
- int g = match.capturedTexts().at(2).toInt();
- if (match.capturedTexts().at(2).indexOf("%") != -1)
- g = g * 255 / 100;
- int b = match.capturedTexts().at(3).toInt();
- if (match.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(" ", UB::SplitBehavior::SkipEmptyParts))
- {
- //check pattern for strings like 'rotate(10)'
- static const QRegularExpression rotate1(QRegularExpression::anchoredPattern("rotate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *\\)"));
- QRegularExpressionMatch match = rotate1.match(trStr);
- if (match.hasMatch()) {
- angle = match.capturedTexts().at(1).toDouble();
- if (item)
- {
- item->setTransformOriginPoint(QPointF(0, 0));
- item->setRotation(angle);
- }
- continue;
- };
-
- //check pattern for strings like 'rotate(10,20,20)' or 'rotate(10.1,10.2,34.2)'
- static const QRegularExpression rotate3(QRegularExpression::anchoredPattern("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]*) *\\)"));
- match = rotate3.match(trStr);
- if (match.hasMatch()) {
- angle = match.capturedTexts().at(1).toDouble();
- dxr = match.capturedTexts().at(2).toDouble();
- dyr = match.capturedTexts().at(3).toDouble();
- if (item)
- {
- item->setTransformOriginPoint(QPointF(dxr, dyr)-item->pos());
- item->setRotation(angle);
- }
- continue;
- }
-
- //check pattern for strings like 'translate(11.0, 12.34)'
- static const QRegularExpression translate2(QRegularExpression::anchoredPattern("translate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *,*([-+]{0,1}[0-9]*\\.{0,1}[0-9]*)*\\)"));
- match = translate2.match(trStr);
- if (match.hasMatch()) {
- dx = match.capturedTexts().at(1).toDouble();
- dy = match.capturedTexts().at(2).toDouble();
- tr.translate(dx,dy);
- continue;
- }
- }
- return tr;
-}
-
-bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getViewBoxDimenstions(const QString& viewBox)
-{
- QStringList capturedTexts = viewBox.split(" ", UB::SplitBehavior::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(UBApplication::displayManager->logicalDpi(ScreenRole::Control));
- 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
deleted file mode 100644
index dc268e5cd..000000000
--- a/src/adaptors/UBCFFSubsetAdaptor.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
- *
- * Copyright (C) 2013 Open Education Foundation
- *
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
- * l'Education Numérique en Afrique (GIP ENA)
- *
- * This file is part of OpenBoard.
- *
- * OpenBoard 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).
- *
- * OpenBoard is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenBoard. 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, std::shared_ptr pDocument);
-
-private:
- class UBCFFSubsetReader
- {
- public:
- UBCFFSubsetReader(std::shared_ptrproxy, QFile *content);
- ~UBCFFSubsetReader();
-
- std::shared_ptrmProxy;
- QString pwdContent;
-
- bool parse();
-
- private:
- QString mTempFilePath;
- std::shared_ptr 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/UBExportCFF.cpp b/src/adaptors/UBExportCFF.cpp
deleted file mode 100644
index 65016fff2..000000000
--- a/src/adaptors/UBExportCFF.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
- *
- * Copyright (C) 2013 Open Education Foundation
- *
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
- * l'Education Numérique en Afrique (GIP ENA)
- *
- * This file is part of OpenBoard.
- *
- * OpenBoard 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).
- *
- * OpenBoard is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenBoard. If not, see .
- */
-
-
-
-#include "UBExportCFF.h"
-#include "UBCFFAdaptor.h"
-#include "document/UBDocumentProxy.h"
-#include "core/UBDocumentManager.h"
-#include "core/UBApplication.h"
-#include "core/memcheck.h"
-#include "document/UBDocumentController.h"
-
-#include
-#include
-
-
-UBExportCFF::UBExportCFF(QObject *parent)
-: UBExportAdaptor(parent)
-{
-
-}
-
-UBExportCFF::~UBExportCFF()
-{
-
-}
-QString UBExportCFF::exportName()
-{
- return tr("Export to IWB");
-}
-
-QString UBExportCFF::exportExtention()
-{
- return QString(".iwb");
-}
-
-void UBExportCFF::persist(std::shared_ptr pDocument)
-{
- QString src = pDocument->persistencePath();
-
- if (!pDocument)
- return;
-
- QString filename = askForFileName(pDocument, tr("Export as IWB File"));
-
- if (filename.length() > 0)
- {
- QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-
- if (mIsVerbose)
- UBApplication::showMessage(tr("Exporting document..."));
-
- UBCFFAdaptor toIWBExporter;
- if (toIWBExporter.convertUBZToIWB(src, filename))
- {
- if (mIsVerbose)
- UBApplication::showMessage(tr("Export successful."));
- }
- else
- if (mIsVerbose)
- UBApplication::showMessage(tr("Export failed."));
-
- showErrorsList(toIWBExporter.getConversionMessages());
-
- QApplication::restoreOverrideCursor();
-
- }
-
-
-}
-
-bool UBExportCFF::associatedActionactionAvailableFor(const QModelIndex &selectedIndex)
-{
- const UBDocumentTreeModel *docModel = qobject_cast(selectedIndex.model());
- if (!selectedIndex.isValid() || docModel->isCatalog(selectedIndex)) {
- return false;
- }
-
- return true;
-}
diff --git a/src/adaptors/UBExportDocument.cpp b/src/adaptors/UBExportDocument.cpp
index 12fb98cfb..2c35b7566 100644
--- a/src/adaptors/UBExportDocument.cpp
+++ b/src/adaptors/UBExportDocument.cpp
@@ -31,13 +31,15 @@
#include "frameworks/UBPlatformUtils.h"
+#include "adaptors/UBPageMapper.h"
+
#include "core/UBDocumentManager.h"
#include "core/UBApplication.h"
+#include "core/UBSettings.h"
#include "document/UBDocumentProxy.h"
#include "document/UBDocumentController.h"
-
-#include "globals/UBGlobals.h"
+#include "document/UBDocumentToc.h"
#ifdef Q_OS_OSX
#include
@@ -78,8 +80,18 @@ bool UBExportDocument::persistsDocument(std::shared_ptr pDocume
QDir documentDir = QDir(pDocumentProxy->persistencePath());
+ // try to load a TOC for mapping and check version number
+ UBDocumentToc toc{pDocumentProxy->persistencePath()};
+ std::unique_ptr mapper{nullptr};
+ const auto version = QVersionNumber::fromString(pDocumentProxy->metaData(UBSettings::documentVersion).toString());
+
+ if (toc.load() && version >= QVersionNumber::fromString(UBSettings::currentFileVersion))
+ {
+ mapper = std::unique_ptr{new UBPageMapper{pDocumentProxy->persistencePath(), &toc}};
+ }
+
QuaZipFile outFile(&zip);
- UBFileSystemUtils::compressDirInZip(documentDir, "", &outFile, true, this);
+ UBFileSystemUtils::compressDirInZip(documentDir, "", &outFile, true, mapper.get(), this);
zip.close();
diff --git a/src/adaptors/UBExportDocumentSetAdaptor.cpp b/src/adaptors/UBExportDocumentSetAdaptor.cpp
index 752b5ea38..70c49d38f 100644
--- a/src/adaptors/UBExportDocumentSetAdaptor.cpp
+++ b/src/adaptors/UBExportDocumentSetAdaptor.cpp
@@ -28,6 +28,8 @@
#include "UBExportDocumentSetAdaptor.h"
#include "UBExportDocument.h"
+#include "adaptors/UBPageMapper.h"
+
#include "frameworks/UBPlatformUtils.h"
#include "core/UBDocumentManager.h"
@@ -35,10 +37,9 @@
#include "document/UBDocumentProxy.h"
#include "document/UBDocumentController.h"
+#include "document/UBDocumentToc.h"
-#include "globals/UBGlobals.h"
#include "core/UBPersistenceManager.h"
-#include "core/UBForeignObjectsHandler.h"
#ifdef Q_OS_OSX
#include
@@ -165,18 +166,22 @@ bool UBExportDocumentSetAdaptor::addDocumentToZip(const QModelIndex &pIndex, UBD
std::shared_ptrpDocumentProxy = model->proxyForIndex(parentIndex);
if (pDocumentProxy) {
-
-// Q_ASSERT(QFileInfo(pDocumentProxy->persistencePath()).exists());
-// UBForeighnObjectsHandler cleaner;
-// cleaner.cure(pDocumentProxy->persistencePath());
-
- //UniboardSankoreTransition document;
QString documentPath(pDocumentProxy->persistencePath());
- //document.checkDocumentDirectory(documentPath);
QDir documentDir = QDir(pDocumentProxy->persistencePath());
+
+ // try to load a TOC for mapping and check version number
+ UBDocumentToc toc{pDocumentProxy->persistencePath()};
+ std::unique_ptr mapper{nullptr};
+ const auto version = QVersionNumber::fromString(pDocumentProxy->metaData(UBSettings::documentVersion).toString());
+
+ if (toc.load() && version >= QVersionNumber::fromString(UBSettings::currentFileVersion))
+ {
+ mapper = std::unique_ptr{new UBPageMapper{pDocumentProxy->persistencePath(), &toc}};
+ }
+
QuaZipFile zipFile(&zip);
- UBFileSystemUtils::compressDirInZip(documentDir, QFileInfo(documentPath).fileName() + "/", &zipFile, false);
+ UBFileSystemUtils::compressDirInZip(documentDir, QFileInfo(documentPath).fileName() + "/", &zipFile, false, mapper.get());
if(zip.getZipError() != 0)
{
diff --git a/src/adaptors/UBExportFullPDF.cpp b/src/adaptors/UBExportFullPDF.cpp
index 71d22b52c..8c8ef936c 100644
--- a/src/adaptors/UBExportFullPDF.cpp
+++ b/src/adaptors/UBExportFullPDF.cpp
@@ -40,14 +40,12 @@
#include "core/UBPersistenceManager.h"
#include "domain/UBGraphicsScene.h"
-#include "domain/UBGraphicsSvgItem.h"
#include "domain/UBGraphicsPDFItem.h"
+#include "document/UBDocument.h"
#include "document/UBDocumentProxy.h"
#include "document/UBDocumentController.h"
-#include "pdf/GraphicsPDFItem.h"
-
#include "UBExportPDF.h"
#include
@@ -79,7 +77,9 @@ UBExportFullPDF::~UBExportFullPDF()
void UBExportFullPDF::saveOverlayPdf(std::shared_ptr pDocumentProxy, const QString& filename)
{
- if (!pDocumentProxy || filename.length() == 0 || pDocumentProxy->pageCount() == 0)
+ auto document = UBDocument::getDocument(pDocumentProxy);
+
+ if (!document || filename.length() == 0 || document->pageCount() == 0)
return;
/*
@@ -105,12 +105,18 @@ void UBExportFullPDF::saveOverlayPdf(std::shared_ptr pDocumentP
QPainter* pdfPainter = 0;
- for(int pageIndex = 0 ; pageIndex < pDocumentProxy->pageCount(); pageIndex++)
+ for(int pageIndex = 0 ; pageIndex < document->pageCount(); pageIndex++)
{
- std::shared_ptr scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, pageIndex);
+ std::shared_ptr scene = document->loadScene(pageIndex);
+
+ if (!scene)
+ {
+ continue;
+ }
+
// set background according to PDF export settings
bool isDark = scene->isDarkBackground();
- UBPageBackground pageBackground = scene->pageBackground();
+ const auto sceneBackground = scene->background();
bool exportDark = isDark && UBSettings::settings()->exportBackgroundColor->get().toBool();
@@ -148,15 +154,15 @@ void UBExportFullPDF::saveOverlayPdf(std::shared_ptr pDocumentP
if (sceneHasPDFBackground)
{
scene->setDrawingMode(true);
- scene->setBackground(false, UBPageBackground::plain);
+ scene->setSceneBackground(false, nullptr);
}
else if (UBSettings::settings()->exportBackgroundGrid->get().toBool())
{
- scene->setBackground(exportDark, pageBackground);
+ scene->setSceneBackground(exportDark, sceneBackground);
}
else
{
- scene->setBackground(exportDark, UBPageBackground::plain);
+ scene->setSceneBackground(exportDark, nullptr);
}
//render to PDF
@@ -168,7 +174,7 @@ void UBExportFullPDF::saveOverlayPdf(std::shared_ptr pDocumentP
//restore background state
scene->setDrawingMode(false);
- scene->setBackground(isDark, pageBackground);
+ scene->setSceneBackground(isDark, sceneBackground);
}
if (pdfPainter) delete pdfPainter;
@@ -219,11 +225,18 @@ bool UBExportFullPDF::persistsDocument(std::shared_ptr pDocumen
// factor between scene coordinates and PDF coordinates
double dpiScale = 72. / pDocumentProxy->pageDpi();
- int existingPageCount = pDocumentProxy->pageCount();
+ auto document = UBDocument::getDocument(pDocumentProxy);
+ int existingPageCount = document->pageCount();
for(int pageIndex = 0 ; pageIndex < existingPageCount; pageIndex++)
{
- std::shared_ptr scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, pageIndex);
+ std::shared_ptr scene = document->loadScene(pageIndex);
+
+ if (!scene)
+ {
+ continue;
+ }
+
UBGraphicsPDFItem *pdfItem = qgraphicsitem_cast(scene->backgroundObject());
if (pdfItem)
diff --git a/src/adaptors/UBExportPDF.cpp b/src/adaptors/UBExportPDF.cpp
index 3c5155429..c9c6fee05 100644
--- a/src/adaptors/UBExportPDF.cpp
+++ b/src/adaptors/UBExportPDF.cpp
@@ -41,14 +41,11 @@
#include "core/UBPersistenceManager.h"
#include "domain/UBGraphicsScene.h"
-#include "domain/UBGraphicsSvgItem.h"
-#include "domain/UBGraphicsPDFItem.h"
+#include "document/UBDocument.h"
#include "document/UBDocumentProxy.h"
#include "document/UBDocumentController.h"
-#include "pdf/GraphicsPDFItem.h"
-
#include "core/memcheck.h"
UBExportPDF::UBExportPDF(QObject *parent)
@@ -97,26 +94,33 @@ bool UBExportPDF::persistsDocument(std::shared_ptr pDocumentPro
QPainter pdfPainter;
bool painterNeedsBegin = true;
- int existingPageCount = pDocumentProxy->pageCount();
+ auto document = UBDocument::getDocument(pDocumentProxy);
+ int existingPageCount = document->pageCount();
for(int pageIndex = 0 ; pageIndex < existingPageCount; pageIndex++) {
- std::shared_ptr scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocumentProxy, pageIndex);
+ std::shared_ptr scene = document->loadScene(pageIndex);
+
+ if (!scene)
+ {
+ continue;
+ }
+
UBApplication::showMessage(tr("Exporting page %1 of %2").arg(pageIndex + 1).arg(existingPageCount));
// set background to white, no crossing for PDF output
bool isDark = scene->isDarkBackground();
- UBPageBackground pageBackground = scene->pageBackground();
+ const auto pageBackground = scene->background();
bool exportDark = isDark && UBSettings::settings()->exportBackgroundColor->get().toBool();
if (UBSettings::settings()->exportBackgroundGrid->get().toBool())
{
- scene->setBackground(exportDark, pageBackground);
+ scene->setSceneBackground(exportDark, pageBackground);
}
else
{
- scene->setBackground(exportDark, UBPageBackground::plain);
+ scene->setSceneBackground(exportDark, nullptr);
}
// pageSize is the output PDF page size; it is set to equal the scene's boundary size; if the contents
@@ -146,7 +150,7 @@ bool UBExportPDF::persistsDocument(std::shared_ptr pDocumentPro
scene->setRenderingQuality(UBItem::RenderingQualityNormal, UBItem::CacheAllowed);
// Restore background state
- scene->setBackground(isDark, pageBackground);
+ scene->setSceneBackground(isDark, pageBackground);
}
if(!painterNeedsBegin)
diff --git a/src/adaptors/UBImportCFF.cpp b/src/adaptors/UBImportCFF.cpp
deleted file mode 100644
index 1af076f39..000000000
--- a/src/adaptors/UBImportCFF.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
- *
- * Copyright (C) 2013 Open Education Foundation
- *
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
- * l'Education Numérique en Afrique (GIP ENA)
- *
- * This file is part of OpenBoard.
- *
- * OpenBoard 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).
- *
- * OpenBoard is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenBoard. 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
-#ifdef Q_OS_OSX
- #include
- #include
- #include
-#else
- #include "quazip.h"
- #include "quazipfile.h"
- #include "quazipfileinfo.h"
-#endif
-//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(std::shared_ptr 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
- std::shared_ptr destDocument = std::make_shared(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());
- UBApplication::showMessage(tr("Import successful."));
- return true;
- }
- else
- {
- UBFileSystemUtils::deleteDir(destDocument->persistencePath());
- 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;
-}
-
-
-std::shared_ptr 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
- std::shared_ptr destDocument = std::make_shared(UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath());
- QDir dir;
- dir.mkdir(destDocument->persistencePath());
- if (pGroup.length() > 0)
- destDocument->setMetaData(UBSettings::documentGroupName, pGroup);
- if (!fi.baseName().isEmpty())
- destDocument->setMetaData(UBSettings::documentName, fi.baseName());
-
- destDocument->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion);
- destDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime()));
-
- std::shared_ptr newDocument = nullptr;
- //try to import cff to document
- if (UBCFFSubsetAdaptor::ConvertCFFFileToUbz(contentFile, destDocument))
- {
- newDocument = UBPersistenceManager::persistenceManager()->createDocumentFromDir(destDocument->persistencePath()
- ,""
- ,""
- ,false
- ,false
- ,true);
-
- UBApplication::showMessage(tr("Import successful."));
- }
- else
- {
- UBFileSystemUtils::deleteDir(destDocument->persistencePath());
- UBApplication::showMessage(tr("Import failed."));
- }
-
- if (documentRootFolder.length() != 0)
- UBFileSystemUtils::deleteDir(documentRootFolder);
- return newDocument;
- }
-}
diff --git a/src/adaptors/UBImportCFF.h b/src/adaptors/UBImportCFF.h
deleted file mode 100644
index a8c058832..000000000
--- a/src/adaptors/UBImportCFF.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015-2022 Département de l'Instruction Publique (DIP-SEM)
- *
- * Copyright (C) 2013 Open Education Foundation
- *
- * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
- * l'Education Numérique en Afrique (GIP ENA)
- *
- * This file is part of OpenBoard.
- *
- * OpenBoard 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).
- *
- * OpenBoard is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenBoard. 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(std::shared_ptr pDocument, const QFile& pFile);
- virtual std::shared_ptr importFile(const QFile& pFile, const QString& pGroup);
-
- private:
- QString expandFileToDir(const QFile& pZipFile, const QString& pDir);
-};
-
-#endif // UBIMPORTCFF_H
diff --git a/src/adaptors/UBMetadataDcSubsetAdaptor.cpp b/src/adaptors/UBMetadataDcSubsetAdaptor.cpp
index 7fe4ae0f1..236b4a002 100644
--- a/src/adaptors/UBMetadataDcSubsetAdaptor.cpp
+++ b/src/adaptors/UBMetadataDcSubsetAdaptor.cpp
@@ -117,7 +117,6 @@ void UBMetadataDcSubsetAdaptor::persist(std::shared_ptr proxy)
// introduced in UB 4.2
xmlWriter.writeTextElement(nsDc, "identifier", proxy->metaData(UBSettings::documentIdentifer).toString());
- xmlWriter.writeTextElement(UBSettings::uniboardDocumentNamespaceUri, "version", UBSettings::currentFileVersion);
QString width = QString::number(proxy->defaultDocumentSize().width());
QString height = QString::number(proxy->defaultDocumentSize().height());
xmlWriter.writeTextElement(UBSettings::uniboardDocumentNamespaceUri, "size", QString("%1x%2").arg(width).arg(height));
@@ -125,6 +124,9 @@ void UBMetadataDcSubsetAdaptor::persist(std::shared_ptr proxy)
// introduced in UB 4.4
xmlWriter.writeTextElement(UBSettings::uniboardDocumentNamespaceUri, "updated-at", UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTimeUtc()));
+ // write as last element to cope with parsing problem
+ xmlWriter.writeTextElement(UBSettings::uniboardDocumentNamespaceUri, "version", UBSettings::currentFileVersion);
+
xmlWriter.writeEndElement(); //dc:Description
xmlWriter.writeEndElement(); //RDF
@@ -157,6 +159,7 @@ QMap UBMetadataDcSubsetAdaptor::load(QString pPath)
}
QXmlStreamReader xml(&file);
+ QString docVersion = "4.1"; // untagged doc version 4.1
while (!xml.atEnd())
{
@@ -164,7 +167,6 @@ QMap UBMetadataDcSubsetAdaptor::load(QString pPath)
if (xml.isStartElement())
{
- QString docVersion = "4.1"; // untagged doc version 4.1
QString name = xml.name().toString();
if (name == "title")
@@ -225,7 +227,6 @@ QMap UBMetadataDcSubsetAdaptor::load(QString pPath)
metadata.insert(UBSettings::documentUpdatedAt, xml.readElementText());
updatedAtFound = true;
}
- metadata.insert(UBSettings::documentVersion, docVersion);
}
if (xml.hasError())
@@ -234,6 +235,7 @@ QMap UBMetadataDcSubsetAdaptor::load(QString pPath)
}
}
+ metadata.insert(UBSettings::documentVersion, docVersion);
file.close();
}
diff --git a/src/adaptors/UBPageMapper.cpp b/src/adaptors/UBPageMapper.cpp
new file mode 100644
index 000000000..79e01637d
--- /dev/null
+++ b/src/adaptors/UBPageMapper.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015-2025 Département de l'Instruction Publique (DIP-SEM)
+ *
+ * This file is part of OpenBoard.
+ *
+ * OpenBoard 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).
+ *
+ * OpenBoard is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with OpenBoard. If not, see .
+ */
+
+
+#include "UBPageMapper.h"
+
+#include "core/UBPersistenceManager.h"
+#include "document/UBDocumentToc.h"
+
+UBPageMapper::UBPageMapper(const QString& documentPath, UBDocumentToc* toc)
+ : mDocumentPath{documentPath}
+ , mSourceToc{toc}
+{
+ if (!mTempDir.isValid())
+ {
+ qWarning() << "UBPageMapper: unable to create temporary directory";
+ return;
+ }
+
+ auto pm = UBPersistenceManager::persistenceManager();
+ mMappedToc = std::unique_ptr{new UBDocumentToc(*mSourceToc, mTempDir.path())};
+
+ // create page map and target TOC
+ for (int index = 0; index < mSourceToc->pageCount(); ++index)
+ {
+ const auto id = mSourceToc->pageId(index);
+
+ // remove the leading "/" from the scene and thumbnail file names
+ mFileMap[pm->sceneFilenameForId(id).mid(1)] = pm->sceneFilenameForId(index).mid(1);
+ mFileMap[pm->thumbnailFilenameForId(id).mid(1)] = pm->thumbnailFilenameForId(index).mid(1);
+
+ // set id to be same as index in the mapped TOC
+ mMappedToc->setPageId(index, index);
+ }
+
+ mMappedToc->save();
+}
+
+UBPageMapper::MapResult UBPageMapper::map(const QString& filename) const
+{
+ if (!mMappedToc)
+ {
+ return {QFileInfo{mDocumentPath + "/" + filename}, filename};
+ }
+
+ if (filename.startsWith("toc."))
+ {
+ // return the mapped TOC
+ return {QFileInfo(mTempDir.path() + "/" + filename), filename};
+ }
+
+ const auto mappedFilename = mFileMap.value(filename);
+
+ if (!mappedFilename.isEmpty())
+ {
+ // return the mapped file
+ return {QFileInfo{mDocumentPath + "/" + filename}, mappedFilename};
+ }
+
+ // return unmapped file
+ return {QFileInfo{mDocumentPath + "/" + filename}, filename};
+}
diff --git a/src/adaptors/UBPageMapper.h b/src/adaptors/UBPageMapper.h
new file mode 100644
index 000000000..f4016c218
--- /dev/null
+++ b/src/adaptors/UBPageMapper.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015-2025 Département de l'Instruction Publique (DIP-SEM)
+ *
+ * This file is part of OpenBoard.
+ *
+ * OpenBoard 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).
+ *
+ * OpenBoard is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with OpenBoard. If not, see .
+ */
+
+
+#pragma once
+
+#include
+#include
+#include
+
+#include
+
+// forward
+class UBDocumentToc;
+
+/**
+ * @brief The UBPageMapper maps a file name which should be saved in a ZIP
+ * file for export to an input file and an output file name.
+ *
+ * This function is used to sequentially renumber pages on export. Page file
+ * names are created according to the page sequence in the TOC. Additionally
+ * an updated TOC is created which reflects the renamed page files.
+ */
+class UBPageMapper
+{
+public:
+ struct MapResult
+ {
+ QFileInfo input; ///< file for reading
+ QString output; ///< file name for the output file in the ZIP archive
+ };
+
+public:
+ UBPageMapper(const QString& documentPath, UBDocumentToc* toc);
+
+ MapResult map(const QString& filename) const;
+
+private:
+ const QString mDocumentPath;
+ const UBDocumentToc* mSourceToc{nullptr};
+ std::unique_ptr mMappedToc;
+ QHash mFileMap;
+ QTemporaryDir mTempDir;
+};
diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp
index 5f2a30840..03cf4e22d 100644
--- a/src/adaptors/UBSvgSubsetAdaptor.cpp
+++ b/src/adaptors/UBSvgSubsetAdaptor.cpp
@@ -51,6 +51,8 @@
#include "domain/UBGraphicsGroupContainerItemDelegate.h"
#include "domain/UBItem.h"
+#include "gui/UBBackgroundRuling.h"
+#include "gui/UBBackgroundManager.h"
#include "tools/UBGraphicsRuler.h"
#include "tools/UBGraphicsAxes.h"
#include "tools/UBGraphicsCompass.h"
@@ -63,7 +65,6 @@
#include "board/UBBoardView.h"
#include "board/UBBoardController.h"
-#include "board/UBDrawingController.h"
#include "board/UBBoardPaletteManager.h"
#include "frameworks/UBFileSystemUtils.h"
@@ -145,26 +146,9 @@ static bool itemZIndexComp(const QGraphicsItem* item1,
}
-void UBSvgSubsetAdaptor::upgradeScene(std::shared_ptr proxy, const int pageIndex)
+QDomDocument UBSvgSubsetAdaptor::loadSceneDocument(std::shared_ptr proxy, const int pageId)
{
- //4.2
- QDomDocument doc = loadSceneDocument(proxy, pageIndex);
- QDomElement elSvg = doc.documentElement(); // SVG tag
- QString ubVersion = elSvg.attributeNS(UBSettings::uniboardDocumentNamespaceUri, "version", "4.1"); // default to 4.1
-
- if (ubVersion.startsWith("4.1") || ubVersion.startsWith("4.2") || ubVersion.startsWith("4.3"))
- {
- // migrate to 4.2.1 (or latter)
- std::shared_ptr scene = loadScene(proxy, pageIndex);
- scene->setModified(true);
- persistScene(proxy, scene, pageIndex);
- }
-}
-
-
-QDomDocument UBSvgSubsetAdaptor::loadSceneDocument(std::shared_ptr proxy, const int pPageIndex)
-{
- QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg",pPageIndex);
+ QString fileName = proxy->persistencePath() + UBPersistenceManager::persistenceManager()->sceneFilenameForId(pageId);
QFile file(fileName);
QDomDocument doc("page");
@@ -177,7 +161,11 @@ QDomDocument UBSvgSubsetAdaptor::loadSceneDocument(std::shared_ptr= QT_VERSION_CHECK(6, 5, 0))
+ doc.setContent(&file, QDomDocument::ParseOption::UseNamespaceProcessing);
+#else
doc.setContent(&file, true);
+#endif
file.close();
}
@@ -185,54 +173,63 @@ QDomDocument UBSvgSubsetAdaptor::loadSceneDocument(std::shared_ptr proxy, const int pageIndex, QUuid pUuid)
+void UBSvgSubsetAdaptor::setSceneUuid(std::shared_ptr proxy, const int pageId, QUuid pUuid)
{
- QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg",pageIndex);
+ const QString path = proxy->persistencePath() + UBPersistenceManager::persistenceManager()->sceneFilenameForId(pageId);
+ replicateScene(path, path, pUuid);
+}
- QFile file(fileName);
+void UBSvgSubsetAdaptor::replicateScene(const QString& sourcePath, const QString& targetPath, QUuid uuid)
+{
+ QFile fromFile(sourcePath);
- if (!file.exists() || !file.open(QIODevice::ReadOnly))
+ if (!fromFile.exists() || !fromFile.open(QIODevice::ReadOnly))
+ {
return;
+ }
- QTextStream textReadStream(&file);
+ QTextStream textReadStream(&fromFile);
QString xmlContent = textReadStream.readAll();
- int uuidIndex = xmlContent.indexOf("uuid");
+ fromFile.close();
+ const int uuidIndex = xmlContent.indexOf("uuid");
+
if (-1 == uuidIndex)
{
- qWarning() << "Cannot read UUID from file" << fileName << "to set new UUID";
- file.close();
+ qWarning() << "Cannot read UUID from file" << sourcePath << "to set new UUID";
return;
}
+
int quoteStartIndex = xmlContent.indexOf('"', uuidIndex);
+
if (-1 == quoteStartIndex)
{
- qWarning() << "Cannot read UUID from file" << fileName << "to set new UUID";
- file.close();
+ qWarning() << "Cannot read UUID from file" << sourcePath << "to set new UUID";
return;
}
+
int quoteEndIndex = xmlContent.indexOf('"', quoteStartIndex + 1);
+
if (-1 == quoteEndIndex)
{
- qWarning() << "Cannot read UUID from file" << fileName << "to set new UUID";
- file.close();
+ qWarning() << "Cannot read UUID from file" << sourcePath << "to set new UUID";
return;
}
- file.close();
-
QString newXmlContent = xmlContent.left(quoteStartIndex + 1);
- newXmlContent.append(UBStringUtils::toCanonicalUuid(pUuid));
+ newXmlContent.append(uuid.toString(QUuid::WithoutBraces));
newXmlContent.append(xmlContent.right(xmlContent.length() - quoteEndIndex));
- if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ QFile toFile(targetPath);
+
+ if (toFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
- QTextStream textWriteStream(&file);
+ QTextStream textWriteStream(&toFile);
textWriteStream << newXmlContent;
- file.close();
+ toFile.close();
}
else
{
- qWarning() << "Cannot open file" << fileName << "to write UUID";
+ qWarning() << "Cannot open file" << targetPath << "to write UUID";
}
}
@@ -242,35 +239,9 @@ QString UBSvgSubsetAdaptor::uniboardDocumentNamespaceUriFromVersion(int mFileVer
}
-std::shared_ptr UBSvgSubsetAdaptor::loadScene(std::shared_ptr proxy, const int pageIndex)
+QByteArray UBSvgSubsetAdaptor::loadSceneAsText(std::shared_ptr proxy, const int pageId)
{
- UBApplication::showMessage(QObject::tr("Loading scene (%1/%2)").arg(pageIndex+1).arg(proxy->pageCount()));
- QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex);
- qInfo() << "loading scene. Filename is : " << fileName;
- QFile file(fileName);
-
- if (file.exists())
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- qWarning() << "Cannot open file " << fileName << " for reading ...";
- return 0;
- }
-
- std::shared_ptr scene = loadScene(proxy, file.readAll());
-
- file.close();
-
- return scene;
- }
-
- return 0;
-}
-
-
-QByteArray UBSvgSubsetAdaptor::loadSceneAsText(std::shared_ptr proxy, const int pageIndex)
-{
- QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex);
+ QString fileName = proxy->persistencePath() + UBPersistenceManager::persistenceManager()->sceneFilenameForId(pageId);
qDebug() << fileName;
QFile file(fileName);
@@ -291,9 +262,9 @@ QByteArray UBSvgSubsetAdaptor::loadSceneAsText(std::shared_ptr
}
-QUuid UBSvgSubsetAdaptor::sceneUuid(std::shared_ptr proxy, const int pageIndex)
+QUuid UBSvgSubsetAdaptor::sceneUuid(std::shared_ptr proxy, const int pageId)
{
- QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex);
+ QString fileName = proxy->persistencePath() + UBPersistenceManager::persistenceManager()->sceneFilenameForId(pageId);
QFile file(fileName);
@@ -337,6 +308,64 @@ QUuid UBSvgSubsetAdaptor::sceneUuid(std::shared_ptr proxy, cons
return uuid;
}
+QUuid UBSvgSubsetAdaptor::sceneUuid(const QString& xmlContent)
+{
+ const int uuidIndex = xmlContent.indexOf("uuid");
+
+ if (-1 == uuidIndex)
+ {
+ qWarning() << "Cannot find uuid attribute";
+ return {};
+ }
+
+ int quoteStartIndex = xmlContent.indexOf('"', uuidIndex);
+
+ if (-1 == quoteStartIndex)
+ {
+ qWarning() << "Cannot find start of uuid attribute value";
+ return {};
+ }
+
+ int quoteEndIndex = xmlContent.indexOf('"', quoteStartIndex + 1);
+
+ if (-1 == quoteEndIndex)
+ {
+ qWarning() << "Cannot find end of uuid attribute value";
+ return {};
+ }
+
+ return QUuid{xmlContent.mid(quoteStartIndex + 1, quoteEndIndex - quoteStartIndex - 1)};
+}
+
+QVersionNumber UBSvgSubsetAdaptor::sceneVersion(const QString& xmlContent)
+{
+ const int versionIndex = xmlContent.indexOf("ub:version");
+
+ if (-1 == versionIndex)
+ {
+ qWarning() << "Cannot find ub:version attribute";
+ return {};
+ }
+
+ int quoteStartIndex = xmlContent.indexOf('"', versionIndex);
+
+ if (-1 == quoteStartIndex)
+ {
+ qWarning() << "Cannot find start of ub:version attribute value";
+ return {};
+ }
+
+ int quoteEndIndex = xmlContent.indexOf('"', quoteStartIndex + 1);
+
+ if (-1 == quoteEndIndex)
+ {
+ qWarning() << "Cannot find end of ub:version attribute value";
+ return {};
+ }
+
+ return QVersionNumber::fromString(xmlContent.mid(quoteStartIndex + 1, quoteEndIndex - quoteStartIndex - 1));
+}
+
std::shared_ptr UBSvgSubsetAdaptor::loadScene(std::shared_ptr proxy, const QByteArray& pArray)
{
@@ -344,9 +373,10 @@ std::shared_ptr UBSvgSubsetAdaptor::loadScene(std::shared_ptr UBSvgSubsetAdaptor::prepareLoadingScene(std::shared_ptr proxy, const int pageIndex)
+std::shared_ptr UBSvgSubsetAdaptor::prepareLoadingScene(std::shared_ptr proxy,
+ const int pageId, std::optional xmlContent)
{
- const auto fileContent = loadSceneAsText(proxy, pageIndex);
+ const auto fileContent = xmlContent.value_or(loadSceneAsText(proxy, pageId));
auto context = std::make_shared(proxy, fileContent);
return context;
}
@@ -481,6 +511,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetReader::processElement()
bool darkBackground = false;
bool crossedBackground = false;
bool ruledBackground = false;
+ bool intermediateLines = false;
auto ubDarkBackground = mXmlReader.attributes().value(mNamespaceUri, "dark-background");
@@ -500,42 +531,30 @@ void UBSvgSubsetAdaptor::UBSvgSubsetReader::processElement()
mScene->setBackgroundGridSize(gridSize);
}
- if (crossedBackground) {
-
- auto ubIntermediateLines = mXmlReader.attributes().value(mNamespaceUri, "intermediate-lines");
-
- if (!ubIntermediateLines.isNull()) {
- bool intermediateLines = ubIntermediateLines.toInt();
-
- mScene->setIntermediateLines(intermediateLines);
- }
- }
-
auto ubRuledBackground = mXmlReader.attributes().value(mNamespaceUri, "ruled-background");
if (!ubRuledBackground.isNull())
ruledBackground = (ubRuledBackground.toString() == xmlTrue);
- if (ruledBackground && !crossedBackground) { // if for some reason both are true, the background will be a grid
+ if (ruledBackground || crossedBackground) {
auto ubIntermediateLines = mXmlReader.attributes().value(mNamespaceUri, "intermediate-lines");
if (!ubIntermediateLines.isNull()) {
- bool intermediateLines = ubIntermediateLines.toInt();
-
- mScene->setIntermediateLines(intermediateLines);
+ intermediateLines = ubIntermediateLines.toInt();
}
}
- UBPageBackground bg;
- if (crossedBackground)
- bg = UBPageBackground::crossed;
- else if (ruledBackground)
- bg = UBPageBackground::ruled;
- else
- bg = UBPageBackground::plain;
+ const UBBackgroundRuling* background{nullptr};
+
+ // guess background pattern from attributes
+ if (crossedBackground || ruledBackground)
+ {
+ const auto bgManager = UBApplication::boardController->backgroundManager();
+ background = bgManager->guessBackground(crossedBackground, ruledBackground, intermediateLines);
+ }
- mScene->setBackground(darkBackground, bg);
+ mScene->setSceneBackground(darkBackground, background);
auto pageNominalSize = mXmlReader.attributes().value(mNamespaceUri, "nominal-size");
if (!pageNominalSize.isNull())
@@ -557,6 +576,18 @@ void UBSvgSubsetAdaptor::UBSvgSubsetReader::processElement()
}
}
+ else if (name == "background")
+ {
+ UBBackgroundRuling bg;
+ bg.parseXml(mXmlReader);
+
+ if (bg.isValid())
+ {
+ const auto bgManager = UBApplication::boardController->backgroundManager();
+ bgManager->addBackground(bg);
+ mScene->setSceneBackground(mScene->isDarkBackground(), bgManager->background(bg.uuid()));
+ }
+ }
else if (name == "g")
{
strokesGroup = new UBGraphicsStrokesGroup();
@@ -894,22 +925,6 @@ void UBSvgSubsetAdaptor::UBSvgSubsetReader::processElement()
currentWidget = 0;
}
}
- else if (src.contains(".wdgt")) // NOTE @letsfindaway obsolete
- {
- UBGraphicsAppleWidgetItem* appleWidgetItem = graphicsAppleWidgetFromSvg();
- if (appleWidgetItem)
- {
- appleWidgetItem->setFlag(QGraphicsItem::ItemIsSelectable, true);
-
- appleWidgetItem->resize(foreignObjectWidth, foreignObjectHeight);
-
- mScene->addItem(appleWidgetItem);
-
- appleWidgetItem->show();
-
- currentWidget = appleWidgetItem;
- }
- }
else if (src.contains(".wgt"))
{
UBGraphicsW3CWidgetItem* w3cWidgetItem = graphicsW3CWidgetFromSvg();
@@ -1177,17 +1192,17 @@ QGraphicsItem *UBSvgSubsetAdaptor::UBSvgSubsetReader::readElementFromGroup()
return result;
}
-void UBSvgSubsetAdaptor::persistScene(std::shared_ptr proxy, std::shared_ptr pScene, const int pageIndex)
+void UBSvgSubsetAdaptor::persistScene(std::shared_ptr proxy, std::shared_ptr pScene, const int pageId)
{
- UBSvgSubsetWriter writer(proxy, pScene, pageIndex);
- writer.persistScene(proxy, pageIndex);
+ UBSvgSubsetWriter writer(proxy, pScene, pageId);
+ writer.persistScene(proxy, pageId);
}
-UBSvgSubsetAdaptor::UBSvgSubsetWriter::UBSvgSubsetWriter(std::shared_ptr proxy, std::shared_ptr pScene, const int pageIndex)
+UBSvgSubsetAdaptor::UBSvgSubsetWriter::UBSvgSubsetWriter(std::shared_ptr proxy, std::shared_ptr pScene, const int pageId)
: mScene(pScene)
, mDocumentPath(proxy->persistencePath())
- , mPageIndex(pageIndex)
+ , mPageId(pageId)
{
// NOOP
@@ -1217,8 +1232,9 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::writeSvgElement(std::shared_ptrisDarkBackground() ? xmlTrue : xmlFalse);
- bool crossedBackground = mScene->pageBackground() == UBPageBackground::crossed;
- bool ruledBackground = mScene->pageBackground() == UBPageBackground::ruled;
+ bool crossedBackground = mScene->background() && mScene->background()->isCrossed();
+ bool ruledBackground = mScene->background() && mScene->background()->isRuled();
+ bool intermediateLines = mScene->background() && mScene->background()->hasIntermediateLines();
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "crossed-background", crossedBackground ? xmlTrue : xmlFalse);
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "ruled-background", ruledBackground ? xmlTrue : xmlFalse);
@@ -1227,8 +1243,6 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::writeSvgElement(std::shared_ptrintermediateLines();
-
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "intermediate-lines", QString::number(intermediateLines));
}
@@ -1248,9 +1262,9 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::writeSvgElement(std::shared_ptr proxy, int pageIndex)
+bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(std::shared_ptr proxy, int pageId)
{
- Q_UNUSED(pageIndex);
+ Q_UNUSED(pageId);
//Creating dom structure to store information
QDomDocument groupDomDocument;
@@ -1271,6 +1285,11 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(std::shared_ptrbackground())
+ {
+ mScene->background()->toXml(mXmlWriter);
+ }
+
// Get the items from the scene
QList items = mScene->items();
@@ -1409,14 +1428,6 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(std::shared_ptr (item);
- if (appleWidgetItem && appleWidgetItem->isVisible())
- {
- graphicsAppleWidgetToSvg(appleWidgetItem);
- continue;
- }
-
// Is the item a W3C?
UBGraphicsW3CWidgetItem *w3cWidgetItem = qgraphicsitem_cast (item);
if (w3cWidgetItem && w3cWidgetItem->isVisible())
@@ -1550,7 +1561,7 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(std::shared_ptrsceneFilenameForId(mPageId);
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
@@ -1567,7 +1578,8 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(std::shared_ptr(groupItem);
+ QUuid uuid = ubitem ? ubitem->uuid() : QUuid{};
if (!uuid.isNull()) {
QDomElement curGroupElement = groupDomDocument->createElement(tGroup);
curGroupElement.setAttribute(aId, uuid.toString());
@@ -1591,7 +1603,8 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistGroupToDom(QGraphicsItem *gro
}
curParent->appendChild(curGroupElement);
foreach (QGraphicsItem *item, groupItem->childItems()) {
- QUuid tmpUuid = UBGraphicsScene::getPersonalUuid(item);
+ UBItem* ubitem = dynamic_cast(item);
+ QUuid tmpUuid = ubitem ? ubitem->uuid() : QUuid{};
if (!tmpUuid.isNull()) {
if (item->type() == UBGraphicsGroupContainerItem::Type && item->childItems().count())
persistGroupToDom(item, curParent, groupDomDocument);
@@ -1688,7 +1701,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::strokeToSvgPolyline(UBGraphicsStroke
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(firstPolygonItem->uuid()));
if (firstPolygonItem->parentItem()) {
- mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "parent", UBStringUtils::toCanonicalUuid(UBGraphicsItem::getOwnUuid(firstPolygonItem->strokesGroup())));
+ mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "parent", firstPolygonItem->strokesGroup()->uuid().toString(QUuid::WithoutBraces));
}
mXmlWriter.writeEndElement();
@@ -2147,15 +2160,11 @@ QList UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItem
void UBSvgSubsetAdaptor::UBSvgSubsetWriter::pixmapItemToLinkedImage(UBGraphicsPixmapItem* pixmapItem)
{
- // find image file
- QDir imageDir = mDocumentPath + "/" + UBPersistenceManager::imageDirectory;
- QStringList imageFiles = imageDir.entryList({pixmapItem->uuid().toString() + ".*"});
-
- if (imageFiles.size() >= 1)
+ if (!pixmapItem->mediaAssets().isEmpty())
{
mXmlWriter.writeStartElement("image");
- QString fileName = UBPersistenceManager::imageDirectory + "/" + imageFiles.last();
+ QString fileName = pixmapItem->mediaAssets().at(0);
mXmlWriter.writeAttribute(nsXLink, "href", fileName);
@@ -2176,11 +2185,13 @@ UBGraphicsPixmapItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::pixmapItemFromSvg()
{
pixmapItem = new UBGraphicsPixmapItem();
QString href = imageHref.toString();
- QImageReader rdr(mDocumentPath + "/" + UBFileSystemUtils::normalizeFilePath(href));
+ const auto asset = UBFileSystemUtils::normalizeFilePath(href);
+ QImageReader rdr(mDocumentPath + "/" + asset);
rdr.setAutoTransform(true);
QImage img = rdr.read();
QPixmap pix = QPixmap::fromImage(img);
pixmapItem->setPixmap(pix);
+ pixmapItem->setMediaAsset(mDocumentPath, asset);
graphicsItemFromSvg(pixmapItem);
}
else
@@ -2197,7 +2208,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::svgItemToLinkedSvg(UBGraphicsSvgItem
mXmlWriter.writeStartElement("image");
- QString fileName = UBPersistenceManager::imageDirectory + "/" + svgItem->uuid().toString() + ".svg";
+ QString fileName = svgItem->mediaAssets().at(0);
mXmlWriter.writeAttribute(nsXLink, "href", fileName);
@@ -2219,6 +2230,7 @@ UBGraphicsSvgItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::svgItemFromSvg()
QString href = imageHref.toString();
svgItem = new UBGraphicsSvgItem(mDocumentPath + "/" + UBFileSystemUtils::normalizeFilePath(href));
+ svgItem->setMediaAsset(mDocumentPath, href);
}
else
{
@@ -2238,25 +2250,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::pdfItemToLinkedPDF(UBGraphicsPDFItem
mXmlWriter.writeStartElement("foreignObject");
mXmlWriter.writeAttribute("requiredExtensions", "http://ns.adobe.com/pdf/1.3/");
- QString fileName = UBPersistenceManager::objectDirectory + "/" + pdfItem->fileUuid().toString() + ".pdf";
-
- QString path = mDocumentPath + "/" + fileName;
-
- if (!QFile::exists(path))
- {
- QDir dir;
- dir.mkdir(mDocumentPath + "/" + UBPersistenceManager::objectDirectory);
-
- QFile file(path);
- if (!file.open(QIODevice::WriteOnly))
- {
- qWarning() << "cannot open file for writing embeded pdf content " << path;
- return;
- }
-
- file.write(pdfItem->fileData());
- file.close();
- }
+ const auto fileName = pdfItem->mediaAssets().at(0);
mXmlWriter.writeAttribute(nsXLink, "href", fileName + "#page=" + QString::number(pdfItem->pageNumber()));
@@ -2302,7 +2296,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::audioItemToLinkedAudio(UBGraphicsAud
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "position", QString("%1").arg(pos));
}
- QString audioFileHref = "audios/" + audioItem->mediaFileUrl().fileName();
+ QString audioFileHref = audioItem->mediaAssets().at(0);
mXmlWriter.writeAttribute(nsXLink, "href", audioFileHref);
mXmlWriter.writeEndElement();
@@ -2329,7 +2323,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::videoItemToLinkedVideo(UBGraphicsVid
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "position", QString("%1").arg(pos));
}
- QString videoFileHref = "videos/" + videoItem->mediaFileUrl().fileName();
+ QString videoFileHref = videoItem->mediaAssets().at(0);
mXmlWriter.writeAttribute(nsXLink, "href", videoFileHref);
mXmlWriter.writeEndElement();
@@ -2480,11 +2474,6 @@ void UBSvgSubsetAdaptor::UBSvgSubsetReader::graphicsItemFromSvg(QGraphicsItem* g
ubItem->setUuid(QUuid(ubUuid.toString()));
else
ubItem->setUuid(QUuid::createUuid());
-
- auto ubSource = mXmlReader.attributes().value(mNamespaceUri, "source");
-
- if (!ubSource.isNull())
- ubItem->setSourceUrl(QUrl(ubSource.toString()));
}
auto ubLocked = mXmlReader.attributes().value(mNamespaceUri, "locked");
@@ -2582,11 +2571,6 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::graphicsItemToSvg(QGraphicsItem* ite
if (ubItem)
{
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(ubItem->uuid()));
-
- QUrl sourceUrl = ubItem->sourceUrl();
-
- if (!sourceUrl.isEmpty())
- mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "source", sourceUrl.path());
}
QVariant layer = item->data(UBGraphicsItemData::ItemLayerType);
@@ -2611,14 +2595,6 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::graphicsItemToSvg(QGraphicsItem* ite
}
}
-
-
-// NOTE @letsfindaway obsolete
-void UBSvgSubsetAdaptor::UBSvgSubsetWriter::graphicsAppleWidgetToSvg(UBGraphicsAppleWidgetItem* item)
-{
- graphicsWidgetToSvg(item);
-}
-
void UBSvgSubsetAdaptor::UBSvgSubsetWriter::graphicsW3CWidgetToSvg(UBGraphicsW3CWidgetItem* item)
{
graphicsWidgetToSvg(item);
@@ -2634,7 +2610,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::graphicsWidgetToSvg(UBGraphicsWidget
QFileInfo fi(widgetRootDir);
QString extension = fi.suffix();
- QString widgetTargetDir = widgetDirectoryPath + "/" + item->uuid().toString() + "." + extension;
+ QString widgetTargetDir = item->mediaAssets().at(0);
QString path = mDocumentPath + "/" + widgetTargetDir;
QDir dir(path);
@@ -2715,34 +2691,6 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::graphicsWidgetToSvg(UBGraphicsWidget
mXmlWriter.writeEndElement();
}
-// NOTE @letsfindaway obsolete
-UBGraphicsAppleWidgetItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::graphicsAppleWidgetFromSvg()
-{
-
- auto widgetUrl = mXmlReader.attributes().value(mNamespaceUri, "src");
-
- if (widgetUrl.isNull())
- {
- qWarning() << "cannot make sens of widget src value";
- return 0;
- }
-
- QString href = widgetUrl.toString();
-
- QUrl url(href);
-
- if (url.isRelative())
- {
- href = mDocumentPath + "/" + UBFileSystemUtils::normalizeFilePath(widgetUrl.toString());
- }
-
- UBGraphicsAppleWidgetItem* widgetItem = new UBGraphicsAppleWidgetItem(QUrl::fromLocalFile(href));
-
- graphicsItemFromSvg(widgetItem);
-
- return widgetItem;
-}
-
UBGraphicsW3CWidgetItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::graphicsW3CWidgetFromSvg()
{
auto widgetUrl = mXmlReader.attributes().value(mNamespaceUri, "src");
@@ -3436,75 +3384,6 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::cacheToSvg(UBGraphicsCache* item)
mXmlWriter.writeEndElement();
}
-void UBSvgSubsetAdaptor::convertPDFObjectsToImages(std::shared_ptr proxy)
-{
- for (int i = 0; i < proxy->pageCount(); i++)
- {
- std::shared_ptr scene = loadScene(proxy, i);
-
- if (scene)
- {
- bool foundPDFItem = false;
-
- foreach(QGraphicsItem* item, scene->items())
- {
- UBGraphicsPDFItem *pdfItem = dynamic_cast(item);
-
- if (pdfItem)
- {
- foundPDFItem = true;
- UBGraphicsPixmapItem* pixmapItem = pdfItem->toPixmapItem();
-
- scene->removeItem(pdfItem);
- scene->addItem(pixmapItem);
-
- }
- }
-
- if (foundPDFItem)
- {
- scene->setModified(true);
- persistScene(proxy, scene, i);
- }
- }
-
- }
-}
-
-
-void UBSvgSubsetAdaptor::convertSvgImagesToImages(std::shared_ptr proxy)
-{
- for (int i = 0; i < proxy->pageCount(); i++)
- {
- std::shared_ptr scene = loadScene(proxy, i);
-
- if (scene)
- {
- bool foundSvgItem = false;
-
- foreach(QGraphicsItem* item, scene->items())
- {
- UBGraphicsSvgItem *svgItem = dynamic_cast(item);
-
- if (svgItem)
- {
- foundSvgItem = true;
- UBGraphicsPixmapItem* pixmapItem = svgItem->toPixmapItem();
-
- scene->removeItem(svgItem);
- scene->addItem(pixmapItem);
- }
- }
-
- if (foundSvgItem)
- {
- scene->setModified(true);
- persistScene(proxy, scene, i);
- }
- }
- }
-}
-
UBSvgSubsetAdaptor::UBSvgReaderContext::UBSvgReaderContext(std::shared_ptr proxy, const QByteArray& pXmlData)
{
reader = new UBSvgSubsetReader(proxy, pXmlData);
@@ -3530,3 +3409,8 @@ std::shared_ptr UBSvgSubsetAdaptor::UBSvgReaderContext::scene()
{
return reader->scene();
}
+
+std::shared_ptr UBSvgSubsetAdaptor::UBSvgReaderContext::proxy() const
+{
+ return reader->mProxy;
+}
diff --git a/src/adaptors/UBSvgSubsetAdaptor.h b/src/adaptors/UBSvgSubsetAdaptor.h
index 689d4034b..66913ab13 100644
--- a/src/adaptors/UBSvgSubsetAdaptor.h
+++ b/src/adaptors/UBSvgSubsetAdaptor.h
@@ -34,6 +34,8 @@
#include
#include
+#include
+
#include "frameworks/UBGeometryUtils.h"
class UBGraphicsSvgItem;
@@ -44,7 +46,6 @@ class UBGraphicsWidgetItem;
class UBGraphicsMediaItem;
class UBGraphicsVideoItem;
class UBGraphicsAudioItem;
-class UBGraphicsAppleWidgetItem;
class UBGraphicsW3CWidgetItem;
class UBGraphicsTextItem;
class UBGraphicsCurtainItem;
@@ -78,24 +79,23 @@ class UBSvgSubsetAdaptor
bool isFinished() const;
void step();
std::shared_ptr scene() const;
+ std::shared_ptr proxy() const;
private:
UBSvgSubsetReader* reader = nullptr;
};
- static std::shared_ptr loadScene(std::shared_ptr proxy, const int pageIndex);
- static QByteArray loadSceneAsText(std::shared_ptr proxy, const int pageIndex);
+ static QByteArray loadSceneAsText(std::shared_ptr proxy, const int pageId);
static std::shared_ptr loadScene(std::shared_ptr proxy, const QByteArray& pArray);
- static std::shared_ptr prepareLoadingScene(std::shared_ptr proxy, const int pageIndex);
-
- static void persistScene(std::shared_ptr proxy, std::shared_ptr pScene, const int pageIndex);
- static void upgradeScene(std::shared_ptr proxy, const int pageIndex);
+ static std::shared_ptr prepareLoadingScene(std::shared_ptr proxy, const int pageId, std::optional xmlContent = {});
- static QUuid sceneUuid(std::shared_ptr proxy, const int pageIndex);
- static void setSceneUuid(std::shared_ptr proxy, const int pageIndex, QUuid pUuid);
+ static void persistScene(std::shared_ptr proxy, std::shared_ptr pScene, const int pageId);
- static void convertPDFObjectsToImages(std::shared_ptr proxy);
- static void convertSvgImagesToImages(std::shared_ptr proxy);
+ static QUuid sceneUuid(std::shared_ptr proxy, const int pageId);
+ static QUuid sceneUuid(const QString& xmlContent);
+ static QVersionNumber sceneVersion(const QString& xmlContent);
+ static void setSceneUuid(std::shared_ptr proxy, const int pageId, QUuid pUuid);
+ static void replicateScene(const QString& sourcePath, const QString& targetPath, QUuid uuid);
static const QString nsSvg;
static const QString nsXLink;
@@ -111,7 +111,7 @@ class UBSvgSubsetAdaptor
private:
- static QDomDocument loadSceneDocument(std::shared_ptr proxy, const int pPageIndex);
+ static QDomDocument loadSceneDocument(std::shared_ptr proxy, const int pageId);
static QString uniboardDocumentNamespaceUriFromVersion(int fileVersion);
@@ -137,6 +137,7 @@ class UBSvgSubsetAdaptor
std::shared_ptr scene();
private:
+ friend class UBSvgReaderContext;
UBGraphicsPolygonItem* polygonItemFromLineSvg(const QColor& pDefaultBrushColor);
@@ -154,8 +155,6 @@ class UBSvgSubsetAdaptor
UBGraphicsMediaItem* audioItemFromSvg();
- UBGraphicsAppleWidgetItem* graphicsAppleWidgetFromSvg();
-
UBGraphicsW3CWidgetItem* graphicsW3CWidgetFromSvg();
UBGraphicsTextItem* textItemFromSvg();
@@ -209,9 +208,9 @@ class UBSvgSubsetAdaptor
{
public:
- UBSvgSubsetWriter(std::shared_ptr proxy, std::shared_ptr pScene, const int pageIndex);
+ UBSvgSubsetWriter(std::shared_ptr proxy, std::shared_ptr pScene, const int pageId);
- bool persistScene(std::shared_ptr proxy, int pageIndex);
+ bool persistScene(std::shared_ptr proxy, int pageId);
virtual ~UBSvgSubsetWriter(){}
@@ -270,7 +269,6 @@ class UBSvgSubsetAdaptor
void videoItemToLinkedVideo(UBGraphicsVideoItem *videoItem);
void audioItemToLinkedAudio(UBGraphicsAudioItem *audioItem);
void graphicsItemToSvg(QGraphicsItem *item);
- void graphicsAppleWidgetToSvg(UBGraphicsAppleWidgetItem *item);
void graphicsW3CWidgetToSvg(UBGraphicsW3CWidgetItem *item);
void graphicsWidgetToSvg(UBGraphicsWidgetItem *item);
void textItemToSvg(UBGraphicsTextItem *item);
@@ -288,7 +286,7 @@ class UBSvgSubsetAdaptor
std::shared_ptr mScene;
QXmlStreamWriter mXmlWriter;
QString mDocumentPath;
- int mPageIndex;
+ int mPageId;
};
};
diff --git a/src/adaptors/UBThumbnailAdaptor.cpp b/src/adaptors/UBThumbnailAdaptor.cpp
index 3e7c44c28..d198b2ebe 100644
--- a/src/adaptors/UBThumbnailAdaptor.cpp
+++ b/src/adaptors/UBThumbnailAdaptor.cpp
@@ -29,116 +29,69 @@
#include "UBThumbnailAdaptor.h"
-#include
-
-#include "frameworks/UBFileSystemUtils.h"
-
-#include "core/UBPersistenceManager.h"
#include "core/UBApplication.h"
#include "core/UBSettings.h"
-#include "board/UBBoardController.h"
-#include "board/UBBoardPaletteManager.h"
-
-#include "document/UBDocumentProxy.h"
+#include "document/UBDocument.h"
#include "domain/UBGraphicsScene.h"
-#include "UBSvgSubsetAdaptor.h"
-
#include "core/memcheck.h"
-void UBThumbnailAdaptor::generateMissingThumbnails(std::shared_ptr