diff options
Diffstat (limited to 'src/notecontent.cpp')
-rw-r--r-- | src/notecontent.cpp | 1935 |
1 files changed, 1935 insertions, 0 deletions
diff --git a/src/notecontent.cpp b/src/notecontent.cpp new file mode 100644 index 0000000..39d4688 --- /dev/null +++ b/src/notecontent.cpp @@ -0,0 +1,1935 @@ +/*************************************************************************** + * Copyright (C) 2003 by S�astien Laot * + * slaout@linux62.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <qfile.h> +#include <qdir.h> +#include <qdom.h> +#include <qpainter.h> +#include <qstylesheet.h> +#include <qfontmetrics.h> +#include <qwidget.h> +#include <qcursor.h> +#include <qstringlist.h> +#include <qbuffer.h> +#include <ktextedit.h> +#include <kservice.h> +#include <kcolordialog.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <kglobalsettings.h> +#include <kpixmapeffect.h> +#include <qbitmap.h> +#include <kurifilter.h> +//#include <kstringhandler.h> +#include <kfilemetainfo.h> +#include <qdatetime.h> +#include <kmultipledrag.h> + +#include <qfileinfo.h> +//#include <kio/kfileitem.h> +#include <kfileitem.h> +#include <kio/previewjob.h> +#include <kio/global.h> + +#include <iostream> + +#include "notecontent.h" +#include "note.h" +#include "noteedit.h" +#include "tag.h" +#include "basket.h" +#include "filter.h" +#include "xmlwork.h" +#include "tools.h" +#include "notefactory.h" +#include "linklabel.h" +#include "global.h" +#include "settings.h" +#include "focusedwidgets.h" +#include "debugwindow.h" +#include "kcolorcombo2.h" +#include "htmlexporter.h" + +#include "config.h" +#ifndef WITHOUT_ARTS + #include <arts/kplayobject.h> + #include <arts/kplayobjectfactory.h> + #include <arts/kartsserver.h> + #include <arts/kartsdispatcher.h> +#endif + +/** class NoteContent: + */ + +const int NoteContent::FEEDBACK_DARKING = 105; + +NoteContent::NoteContent(Note *parent, const QString &fileName) + : m_note(parent) +{ + parent->setContent(this); + setFileName(fileName); +} + +void NoteContent::saveToNode(QDomDocument &doc, QDomElement &content) +{ + if (useFile()) { + QDomText textNode = doc.createTextNode(fileName()); + content.appendChild(textNode); + } +} + +QRect NoteContent::zoneRect(int zone, const QPoint &/*pos*/) +{ + if (zone == Note::Content) + return QRect(0, 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() + else + return QRect(); +} + +KURL NoteContent::urlToOpen(bool /*with*/) +{ + return (useFile() ? KURL(fullPath()) : KURL()); +} + +void NoteContent::setFileName(const QString &fileName) +{ + m_fileName = fileName; +} + +bool NoteContent::trySetFileName(const QString &fileName) +{ + if (useFile() && fileName != m_fileName) { + QString newFileName = Tools::fileNameForNewFile(fileName, basket()->fullPath()); + QDir dir; + dir.rename(fullPath(), basket()->fullPathForFileName(newFileName)); + return true; + } + + return false; // !useFile() or unsuccesful rename +} + +QString NoteContent::fullPath() +{ + if (note() && useFile()) + return note()->fullPath(); + else + return ""; +} + +void NoteContent::contentChanged(int newMinWidth) +{ + m_minWidth = newMinWidth; + if (note()) { +// note()->unbufferize(); + note()->requestRelayout(); // TODO: It should re-set the width! m_width = 0 ? contentChanged: setWidth, geteight, if size havent changed, only repaint and not relayout + } +} + +Basket* NoteContent::basket() +{ + if (note()) + return note()->basket(); + else + return 0; +} + +void NoteContent::setEdited() +{ + note()->setLastModificationDate(QDateTime::currentDateTime()); + basket()->save(); +} + +/** All the Content Classes: + */ + +NoteType::Id TextContent::type() { return NoteType::Text; } +NoteType::Id HtmlContent::type() { return NoteType::Html; } +NoteType::Id ImageContent::type() { return NoteType::Image; } +NoteType::Id AnimationContent::type() { return NoteType::Animation; } +NoteType::Id SoundContent::type() { return NoteType::Sound; } +NoteType::Id FileContent::type() { return NoteType::File; } +NoteType::Id LinkContent::type() { return NoteType::Link; } +NoteType::Id LauncherContent::type() { return NoteType::Launcher; } +NoteType::Id ColorContent::type() { return NoteType::Color; } +NoteType::Id UnknownContent::type() { return NoteType::Unknown; } + +QString TextContent::typeName() { return i18n("Plain Text"); } +QString HtmlContent::typeName() { return i18n("Text"); } +QString ImageContent::typeName() { return i18n("Image"); } +QString AnimationContent::typeName() { return i18n("Animation"); } +QString SoundContent::typeName() { return i18n("Sound"); } +QString FileContent::typeName() { return i18n("File"); } +QString LinkContent::typeName() { return i18n("Link"); } +QString LauncherContent::typeName() { return i18n("Launcher"); } +QString ColorContent::typeName() { return i18n("Color"); } +QString UnknownContent::typeName() { return i18n("Unknown"); } + +QString TextContent::lowerTypeName() { return "text"; } +QString HtmlContent::lowerTypeName() { return "html"; } +QString ImageContent::lowerTypeName() { return "image"; } +QString AnimationContent::lowerTypeName() { return "animation"; } +QString SoundContent::lowerTypeName() { return "sound"; } +QString FileContent::lowerTypeName() { return "file"; } +QString LinkContent::lowerTypeName() { return "link"; } +QString LauncherContent::lowerTypeName() { return "launcher"; } +QString ColorContent::lowerTypeName() { return "color"; } +QString UnknownContent::lowerTypeName() { return "unknown"; } + +QString NoteContent::toText(const QString &cuttedFullPath) +{ + return (cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); +} + +QString TextContent::toText(const QString &/*cuttedFullPath*/) { return text(); } +QString HtmlContent::toText(const QString &/*cuttedFullPath*/) { return Tools::htmlToText(html()); } +QString LinkContent::toText(const QString &/*cuttedFullPath*/) +{ + if (autoTitle()) + return url().prettyURL(); + else if (title().isEmpty() && url().isEmpty()) + return ""; + else if (url().isEmpty()) + return title(); + else if (title().isEmpty()) + return url().prettyURL(); + else + return QString("%1 <%2>").arg(title(), url().prettyURL()); +} +QString ColorContent::toText(const QString &/*cuttedFullPath*/) { return color().name(); } +QString UnknownContent::toText(const QString &/*cuttedFullPath*/) { return ""; } + +// TODO: If imageName.isEmpty() return fullPath() because it's for external use, else return fileName() because it's to display in a tooltip +QString TextContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/) +{ return Tools::textToHTMLWithoutP(text()); } + +QString HtmlContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/) +{ return Tools::htmlToParagraph(html()); } + +QString ImageContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath) +{ return QString("<img src=\"%1\">").arg(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); } + +QString AnimationContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath) +{ return QString("<img src=\"%1\">").arg(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); } + +QString SoundContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath) +{ return QString("<a href=\"%1\">%2</a>").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), fileName()); } // With the icon? + +QString FileContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath) +{ return QString("<a href=\"%1\">%2</a>").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), fileName()); } // With the icon? + +QString LinkContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/) +{ return QString("<a href=\"%1\">%2</a>").arg(url().prettyURL(), title()); } // With the icon? + +QString LauncherContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath) +{ return QString("<a href=\"%1\">%2</a>").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), name()); } // With the icon? + +QString ColorContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/) +{ return QString("<span style=\"color: %1\">%2</span>").arg(color().name(), color().name()); } + +QString UnknownContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/) +{ return ""; } + +QPixmap ImageContent::toPixmap() { return pixmap(); } +QPixmap AnimationContent::toPixmap() { return movie().framePixmap(); } + +void NoteContent::toLink(KURL *url, QString *title, const QString &cuttedFullPath) +{ + if (useFile()) { + *url = KURL(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); + *title = (cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); + } else { + *url = KURL(); + *title = QString(); + } +} +void LinkContent::toLink(KURL *url, QString *title, const QString &/*cuttedFullPath*/) +{ + *url = this->url(); + *title = this->title(); +} + +void LauncherContent::toLink(KURL *url, QString *title, const QString &cuttedFullPath) +{ + *url = KURL(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); + *title = name(); +} +void UnknownContent::toLink(KURL *url, QString *title, const QString &/*cuttedFullPath*/) +{ + *url = KURL(); + *title = QString(); +} + +bool TextContent::useFile() { return true; } +bool HtmlContent::useFile() { return true; } +bool ImageContent::useFile() { return true; } +bool AnimationContent::useFile() { return true; } +bool SoundContent::useFile() { return true; } +bool FileContent::useFile() { return true; } +bool LinkContent::useFile() { return false; } +bool LauncherContent::useFile() { return true; } +bool ColorContent::useFile() { return false; } +bool UnknownContent::useFile() { return true; } + +bool TextContent::canBeSavedAs() { return true; } +bool HtmlContent::canBeSavedAs() { return true; } +bool ImageContent::canBeSavedAs() { return true; } +bool AnimationContent::canBeSavedAs() { return true; } +bool SoundContent::canBeSavedAs() { return true; } +bool FileContent::canBeSavedAs() { return true; } +bool LinkContent::canBeSavedAs() { return true; } +bool LauncherContent::canBeSavedAs() { return true; } +bool ColorContent::canBeSavedAs() { return false; } +bool UnknownContent::canBeSavedAs() { return false; } + +QString TextContent::saveAsFilters() { return "text/plain"; } +QString HtmlContent::saveAsFilters() { return "text/html"; } +QString ImageContent::saveAsFilters() { return "image/png"; } // TODO: Offer more types +QString AnimationContent::saveAsFilters() { return "image/gif"; } // TODO: MNG... +QString SoundContent::saveAsFilters() { return "audio/x-mp3"; } // TODO: OGG... +QString FileContent::saveAsFilters() { return "*"; } // TODO: Get MIME type of the url target +QString LinkContent::saveAsFilters() { return "*"; } // TODO: idem File + If isDir(): return +QString LauncherContent::saveAsFilters() { return "application/x-desktop"; } +QString ColorContent::saveAsFilters() { return ""; } +QString UnknownContent::saveAsFilters() { return ""; } + +bool TextContent::match(const FilterData &data) { return (text().find(data.string, /*index=*/0, /*cs=*/false) != -1); } +bool HtmlContent::match(const FilterData &data) { return (m_textEquivalent/*toText("")*/.find(data.string, /*index=*/0, /*cs=*/false) != -1); } //OPTIM_FILTER +bool ImageContent::match(const FilterData &/*data*/) { return false; } +bool AnimationContent::match(const FilterData &/*data*/) { return false; } +bool SoundContent::match(const FilterData &data) { return (fileName().find(data.string, /*index=*/0, /*cs=*/false) != -1); } +bool FileContent::match(const FilterData &data) { return (fileName().find(data.string, /*index=*/0, /*cs=*/false) != -1); } +bool LinkContent::match(const FilterData &data) { return (title().find(data.string, 0, false) != -1 || url().prettyURL().find(data.string, 0, false) != -1); } +bool LauncherContent::match(const FilterData &data) { return (exec().find(data.string, 0, false) != -1 || name().find(data.string, 0, false) != -1); } +bool ColorContent::match(const FilterData &data) { return (color().name().find(data.string, /*index=*/0, /*cs=*/false) != -1); } +bool UnknownContent::match(const FilterData &data) { return (mimeTypes().find(data.string, /*index=*/0, /*cs=*/false) != -1); } + +QString TextContent::editToolTipText() { return i18n("Edit this plain text"); } +QString HtmlContent::editToolTipText() { return i18n("Edit this text"); } +QString ImageContent::editToolTipText() { return i18n("Edit this image"); } +QString AnimationContent::editToolTipText() { return i18n("Edit this animation"); } +QString SoundContent::editToolTipText() { return i18n("Edit the file name of this sound"); } +QString FileContent::editToolTipText() { return i18n("Edit the name of this file"); } +QString LinkContent::editToolTipText() { return i18n("Edit this link"); } +QString LauncherContent::editToolTipText() { return i18n("Edit this launcher"); } +QString ColorContent::editToolTipText() { return i18n("Edit this color"); } +QString UnknownContent::editToolTipText() { return i18n("Edit this unknown object"); } + +QString TextContent::cssClass() { return ""; } +QString HtmlContent::cssClass() { return ""; } +QString ImageContent::cssClass() { return ""; } +QString AnimationContent::cssClass() { return ""; } +QString SoundContent::cssClass() { return "sound"; } +QString FileContent::cssClass() { return "file"; } +QString LinkContent::cssClass() { return (LinkLook::lookForURL(m_url) == LinkLook::localLinkLook ? "local" : "network"); } +QString LauncherContent::cssClass() { return "launcher"; } +QString ColorContent::cssClass() { return "" ; } +QString UnknownContent::cssClass() { return ""; } + +void TextContent::fontChanged() { setText(text()); } +void HtmlContent::fontChanged() { setHtml(html()); } +void ImageContent::fontChanged() { setPixmap(pixmap()); } +void AnimationContent::fontChanged() { setMovie(movie()); } +void FileContent::fontChanged() { setFileName(fileName()); } +void LinkContent::fontChanged() { setLink(url(), title(), icon(), autoTitle(), autoIcon()); } +void LauncherContent::fontChanged() { setLauncher(name(), icon(), exec()); } +void ColorContent::fontChanged() { setColor(color()); } +void UnknownContent::fontChanged() { loadFromFile(/*lazyLoad=*/false); } // TODO: Optimize: setMimeTypes() + +//QString TextContent::customOpenCommand() { return (Settings::isTextUseProg() && ! Settings::textProg().isEmpty() ? Settings::textProg() : QString()); } +QString HtmlContent::customOpenCommand() { return (Settings::isHtmlUseProg() && ! Settings::htmlProg().isEmpty() ? Settings::htmlProg() : QString()); } +QString ImageContent::customOpenCommand() { return (Settings::isImageUseProg() && ! Settings::imageProg().isEmpty() ? Settings::imageProg() : QString()); } +QString AnimationContent::customOpenCommand() { return (Settings::isAnimationUseProg() && ! Settings::animationProg().isEmpty() ? Settings::animationProg() : QString()); } +QString SoundContent::customOpenCommand() { return (Settings::isSoundUseProg() && ! Settings::soundProg().isEmpty() ? Settings::soundProg() : QString()); } + +void LinkContent::serialize(QDataStream &stream) { stream << url() << title() << icon() << (Q_UINT64)autoTitle() << (Q_UINT64)autoIcon(); } +void ColorContent::serialize(QDataStream &stream) { stream << color(); } + +QPixmap TextContent::feedbackPixmap(int width, int height) +{ + QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, width, height, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, text()); + QPixmap pixmap( QMIN(width, textRect.width()), QMIN(height, textRect.height()) ); + pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); + QPainter painter(&pixmap); + painter.setPen(note()->textColor()); + painter.setFont(note()->font()); + painter.drawText(0, 0, pixmap.width(), pixmap.height(), Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, text()); + painter.end(); + return pixmap; +} + +QPixmap HtmlContent::feedbackPixmap(int width, int height) +{ + QSimpleRichText richText(html(), note()->font()); + richText.setWidth(width); + QColorGroup colorGroup(basket()->colorGroup()); + colorGroup.setColor(QColorGroup::Text, note()->textColor()); + colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); + QPixmap pixmap( QMIN(width, richText.widthUsed()), QMIN(height, richText.height()) ); + pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); + QPainter painter(&pixmap); + painter.setPen(note()->textColor()); + richText.draw(&painter, 0, 0, QRect(0, 0, pixmap.width(), pixmap.height()), colorGroup); + painter.end(); + return pixmap; +} + +QPixmap ImageContent::feedbackPixmap(int width, int height) +{ + if (width >= m_pixmap.width() && height >= m_pixmap.height()) { // Full size + if (m_pixmap.hasAlpha()) { + QPixmap opaque(m_pixmap.width(), m_pixmap.height()); + opaque.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); + QPainter painter(&opaque); + painter.drawPixmap(0, 0, m_pixmap); + painter.end(); + return opaque; + } else + return m_pixmap; + } else { // Scalled down + QImage imageToScale = m_pixmap.convertToImage(); + QPixmap pmScaled; + pmScaled.convertFromImage(imageToScale./*smoothScale*/scale(width, height, QImage::ScaleMin)); + if (pmScaled.hasAlpha()) { + QPixmap opaque(pmScaled.width(), pmScaled.height()); + opaque.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); + QPainter painter(&opaque); + painter.drawPixmap(0, 0, pmScaled); + painter.end(); + return opaque; + } else + return pmScaled; + } +} + +QPixmap AnimationContent::feedbackPixmap(int width, int height) +{ + QPixmap pixmap = m_movie.framePixmap(); + if (width >= pixmap.width() && height >= pixmap.height()) // Full size + return pixmap; + else { // Scalled down + QImage imageToScale = pixmap.convertToImage(); + QPixmap pmScaled; + pmScaled.convertFromImage(imageToScale./*smoothScale*/scale(width, height, QImage::ScaleMin)); + return pmScaled; + } +} + +QPixmap LinkContent::feedbackPixmap(int width, int height) +{ + QColorGroup colorGroup(basket()->colorGroup()); + colorGroup.setColor(QColorGroup::Text, note()->textColor()); + colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); + return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor()); +} + +QPixmap ColorContent::feedbackPixmap(int width, int height) +{ + // TODO: Duplicate code: make a rect() method! + QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name()); + int rectHeight = (textRect.height() + 2)*3/2; + int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. + + QColorGroup colorGroup(basket()->colorGroup()); + colorGroup.setColor(QColorGroup::Text, note()->textColor()); + colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); + + QPixmap pixmap( QMIN(width, rectWidth + RECT_MARGIN + textRect.width() + RECT_MARGIN), QMIN(height, rectHeight) ); + pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); + QPainter painter(&pixmap); + paint(&painter, pixmap.width(), pixmap.height(), colorGroup, false, false, false); // We don't care of the three last boolean parameters. + painter.end(); + return pixmap; +} + +QPixmap FileContent::feedbackPixmap(int width, int height) +{ + QColorGroup colorGroup(basket()->colorGroup()); + colorGroup.setColor(QColorGroup::Text, note()->textColor()); + colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); + return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor()); +} + +QPixmap LauncherContent::feedbackPixmap(int width, int height) +{ + QColorGroup colorGroup(basket()->colorGroup()); + colorGroup.setColor(QColorGroup::Text, note()->textColor()); + colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); + return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor()); +} + +QPixmap UnknownContent::feedbackPixmap(int width, int height) +{ + QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, /*width=*/1, 500000, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, m_mimeTypes); + + QColorGroup colorGroup(basket()->colorGroup()); + colorGroup.setColor(QColorGroup::Text, note()->textColor()); + colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); + + QPixmap pixmap( QMIN(width, DECORATION_MARGIN + textRect.width() + DECORATION_MARGIN), QMIN(height, DECORATION_MARGIN + textRect.height() + DECORATION_MARGIN) ); + QPainter painter(&pixmap); + paint(&painter, pixmap.width() + 1, pixmap.height(), colorGroup, false, false, false); // We don't care of the three last boolean parameters. + painter.setPen(note()->backgroundColor().dark(FEEDBACK_DARKING)); + painter.drawPoint(0, 0); + painter.drawPoint(pixmap.width() - 1, 0); + painter.drawPoint(0, pixmap.height() - 1); + painter.drawPoint(pixmap.width() - 1, pixmap.height() - 1); + painter.end(); + return pixmap; +} + + +/** class TextContent: + */ + +TextContent::TextContent(Note *parent, const QString &fileName, bool lazyLoad) + : NoteContent(parent, fileName), m_simpleRichText(0) +{ + basket()->addWatchedFile(fullPath()); + loadFromFile(lazyLoad); +} + +TextContent::~TextContent() +{ + delete m_simpleRichText; +} + +int TextContent::setWidthAndGetHeight(int width) +{ + if (m_simpleRichText) { + width -= 1; + m_simpleRichText->setWidth(width); + return m_simpleRichText->height(); + } else + return 10; // Lazy loaded +} + +void TextContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) +{ + if (m_simpleRichText) { + width -= 1; + m_simpleRichText->draw(painter, 0, 0, QRect(0, 0, width, height), colorGroup); + } +} + +bool TextContent::loadFromFile(bool lazyLoad) +{ + DEBUG_WIN << "Loading TextContent From " + basket()->folderName() + fileName(); + + QString content; + bool success = basket()->loadFromFile(fullPath(), &content, /*isLocalEncoding=*/true); + + if (success) + setText(content, lazyLoad); + else { + std::cout << "FAILED TO LOAD TextContent: " << fullPath() << std::endl; + setText("", lazyLoad); + if (!QFile::exists(fullPath())) + saveToFile(); // Reserve the fileName so no new note will have the same name! + } + return success; +} + +bool TextContent::finishLazyLoad() +{ + int width = (m_simpleRichText ? m_simpleRichText->width() : 1); + delete m_simpleRichText; + QString html = "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body>" + Tools::tagURLs(Tools::textToHTML(m_text)); // Don't collapse multiple spaces! + m_simpleRichText = new QSimpleRichText(html, note()->font()); + m_simpleRichText->setWidth(1); // We put a width of 1 pixel, so usedWidth() is egual to the minimum width + int minWidth = m_simpleRichText->widthUsed(); + m_simpleRichText->setWidth(width); + contentChanged(minWidth + 1); + + return true; +} + +bool TextContent::saveToFile() +{ + return basket()->saveToFile(fullPath(), text(), /*isLocalEncoding=*/true); +} + +QString TextContent::linkAt(const QPoint &pos) +{ + if (m_simpleRichText) + return m_simpleRichText->anchorAt(pos); + else + return ""; // Lazy loaded +} + + +QString TextContent::messageWhenOpenning(OpenMessage where) +{ + switch (where) { + case OpenOne: return i18n("Opening plain text..."); + case OpenSeveral: return i18n("Opening plain texts..."); + case OpenOneWith: return i18n("Opening plain text with..."); + case OpenSeveralWith: return i18n("Opening plain texts with..."); + case OpenOneWithDialog: return i18n("Open plain text with:"); + case OpenSeveralWithDialog: return i18n("Open plain texts with:"); + default: return ""; + } +} + +void TextContent::setText(const QString &text, bool lazyLoad) +{ + m_text = text; + if (!lazyLoad) + finishLazyLoad(); + else + contentChanged(10); +} + +void TextContent::exportToHTML(HTMLExporter *exporter, int indent) +{ + QString spaces; + QString html = "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body>" + + Tools::tagURLs(Tools::textToHTMLWithoutP(text().replace("\t", " "))); // Don't collapse multiple spaces! + exporter->stream << html.replace(" ", " ").replace("\n", "\n" + spaces.fill(' ', indent + 1)); +} + +/** class HtmlContent: + */ + +HtmlContent::HtmlContent(Note *parent, const QString &fileName, bool lazyLoad) + : NoteContent(parent, fileName), m_simpleRichText(0) +{ + basket()->addWatchedFile(fullPath()); + loadFromFile(lazyLoad); +} + +HtmlContent::~HtmlContent() +{ + delete m_simpleRichText; +} + +int HtmlContent::setWidthAndGetHeight(int width) +{ + if (m_simpleRichText) { + width -= 1; + m_simpleRichText->setWidth(width); + return m_simpleRichText->height(); + } else + return 10; // Lazy loaded +} + +void HtmlContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) +{ + if (m_simpleRichText) { + width -= 1; + m_simpleRichText->draw(painter, 0, 0, QRect(0, 0, width, height), colorGroup); + } +} + +bool HtmlContent::loadFromFile(bool lazyLoad) +{ + DEBUG_WIN << "Loading HtmlContent From " + basket()->folderName() + fileName(); + + QString content; + bool success = basket()->loadFromFile(fullPath(), &content, /*isLocalEncoding=*/true); + + if (success) + setHtml(content, lazyLoad); + else { + std::cout << "FAILED TO LOAD HtmlContent: " << fullPath() << std::endl; + setHtml("", lazyLoad); + if (!QFile::exists(fullPath())) + saveToFile(); // Reserve the fileName so no new note will have the same name! + } + return success; +} + +bool HtmlContent::finishLazyLoad() +{ + int width = (m_simpleRichText ? m_simpleRichText->width() : 1); + delete m_simpleRichText; + m_simpleRichText = new QSimpleRichText(Tools::tagURLs(m_html), note()->font()); + m_simpleRichText->setWidth(1); // We put a width of 1 pixel, so usedWidth() is egual to the minimum width + int minWidth = m_simpleRichText->widthUsed(); + m_simpleRichText->setWidth(width); + contentChanged(minWidth + 1); + + return true; +} + +bool HtmlContent::saveToFile() +{ + return basket()->saveToFile(fullPath(), html(), /*isLocalEncoding=*/true); +} + +QString HtmlContent::linkAt(const QPoint &pos) +{ + if (m_simpleRichText) + return m_simpleRichText->anchorAt(pos); + else + return ""; // Lazy loaded +} + + +QString HtmlContent::messageWhenOpenning(OpenMessage where) +{ + switch (where) { + case OpenOne: return i18n("Opening text..."); + case OpenSeveral: return i18n("Opening texts..."); + case OpenOneWith: return i18n("Opening text with..."); + case OpenSeveralWith: return i18n("Opening texts with..."); + case OpenOneWithDialog: return i18n("Open text with:"); + case OpenSeveralWithDialog: return i18n("Open texts with:"); + default: return ""; + } +} + +void HtmlContent::setHtml(const QString &html, bool lazyLoad) +{ + m_html = html; + m_textEquivalent = toText(""); //OPTIM_FILTER + if (!lazyLoad) + finishLazyLoad(); + else + contentChanged(10); +} + +void HtmlContent::exportToHTML(HTMLExporter *exporter, int indent) +{ + QString spaces; + exporter->stream << Tools::htmlToParagraph(Tools::tagURLs(html().replace("\t", " "))) + .replace(" ", " ") + .replace("\n", "\n" + spaces.fill(' ', indent + 1)); +} + +/** class ImageContent: + */ + +ImageContent::ImageContent(Note *parent, const QString &fileName, bool lazyLoad) + : NoteContent(parent, fileName), m_format(0) +{ + basket()->addWatchedFile(fullPath()); + loadFromFile(lazyLoad); +} + +int ImageContent::setWidthAndGetHeight(int width) +{ + width -= 1; + // Don't store width: we will get it on paint! + if (width >= m_pixmap.width()) // Full size + return m_pixmap.height(); + else { // Scalled down + double height = m_pixmap.height() * (double)width / m_pixmap.width(); + return int((double)(int)height <= (height - 0.5) ? height + 1 : height); + } +} + +void ImageContent::paint(QPainter *painter, int width, int /*height*/, const QColorGroup &/*colorGroup*/, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) +{ + width -= 1; +// KPixmap pixmap = m_pixmap; +// if (note()->isSelected()) +// pixmap = KPixmapEffect::selectedPixmap(m_pixmap, KGlobalSettings::highlightColor()); + + if (width >= m_pixmap.width()) // Full size + painter->drawPixmap(0, 0, m_pixmap); + else { // Scalled down + double scale = ((double)width) / m_pixmap.width(); + painter->scale(scale, scale); + painter->drawPixmap(0, 0, m_pixmap); // TODO: Smooth !!! + } +} + +bool ImageContent::loadFromFile(bool lazyLoad) +{ + if (lazyLoad) + return true; + else + return finishLazyLoad(); +} + +bool ImageContent::finishLazyLoad() +{ + DEBUG_WIN << "Loading ImageContent From " + basket()->folderName() + fileName(); + + QByteArray content; + + if (basket()->loadFromFile(fullPath(), &content)) + { + QBuffer buffer(content); + + buffer.open(IO_ReadOnly); + m_format = (char* /* from const char* */)QImageIO::imageFormat(&buffer); // See QImageIO to know what formats can be supported. + buffer.close(); + if (m_format) { + m_pixmap.loadFromData(content); + setPixmap(m_pixmap); + return true; + } + } + + std::cout << "FAILED TO LOAD ImageContent: " << fullPath() << std::endl; + m_format = (char*)"PNG"; // If the image is set later, it should be saved without destruction, so we use PNG by default. + m_pixmap.resize(1, 1); // Create a 1x1 pixels image instead of an undefined one. + m_pixmap.fill(); + m_pixmap.setMask(m_pixmap.createHeuristicMask()); + setPixmap(m_pixmap); + if (!QFile::exists(fullPath())) + saveToFile(); // Reserve the fileName so no new note will have the same name! + return false; +} + +bool ImageContent::saveToFile() +{ + QByteArray ba; + QBuffer buffer(ba); + + buffer.open(IO_WriteOnly); + m_pixmap.save(&buffer, m_format); + return basket()->saveToFile(fullPath(), ba); +} + + +void ImageContent::toolTipInfos(QStringList *keys, QStringList *values) +{ + keys->append(i18n("Size")); + values->append(i18n("%1 by %2 pixels").arg(QString::number(m_pixmap.width()), QString::number(m_pixmap.height()))); +} + +QString ImageContent::messageWhenOpenning(OpenMessage where) +{ + switch (where) { + case OpenOne: return i18n("Opening image..."); + case OpenSeveral: return i18n("Opening images..."); + case OpenOneWith: return i18n("Opening image with..."); + case OpenSeveralWith: return i18n("Opening images with..."); + case OpenOneWithDialog: return i18n("Open image with:"); + case OpenSeveralWithDialog: return i18n("Open images with:"); + default: return ""; + } +} + +void ImageContent::setPixmap(const QPixmap &pixmap) +{ + m_pixmap = pixmap; + // Since it's scalled, the height is always greater or equal to the size of the tag emblems (16) + contentChanged(16 + 1); // TODO: always good? I don't think... +} + +void ImageContent::exportToHTML(HTMLExporter *exporter, int /*indent*/) +{ + int width = m_pixmap.width(); + int height = m_pixmap.height(); + int contentWidth = note()->width() - note()->contentX() - 1 - Note::NOTE_MARGIN; + + QString imageName = exporter->copyFile(fullPath(), /*createIt=*/true); + + if (contentWidth <= m_pixmap.width()) { // Scalled down + double scale = ((double)contentWidth) / m_pixmap.width(); + width = (int)(m_pixmap.width() * scale); + height = (int)(m_pixmap.height() * scale); + exporter->stream << "<a href=\"" << exporter->dataFolderName << imageName << "\" title=\"" << i18n("Click for full size view") << "\">"; + } + + exporter->stream << "<img src=\"" << exporter->dataFolderName << imageName + << "\" width=\"" << width << "\" height=\"" << height << "\" alt=\"\">"; + + if (contentWidth <= m_pixmap.width()) // Scalled down + exporter->stream << "</a>"; +} + +/** class AnimationContent: + */ + +int AnimationContent::INVALID_STATUS = -100; + +AnimationContent::AnimationContent(Note *parent, const QString &fileName, bool lazyLoad) + : NoteContent(parent, fileName), m_oldStatus(INVALID_STATUS) +{ + basket()->addWatchedFile(fullPath()); + loadFromFile(lazyLoad); +} + +int AnimationContent::setWidthAndGetHeight(int /*width*/) +{ + /*width -= 1*/; + return m_movie.framePixmap().height() ; // TODO!!! +} + +void AnimationContent::paint(QPainter *painter, int width, int /*height*/, const QColorGroup &/*colorGroup*/, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) +{ + /*width -= 1*/; +// DEBUG_WIN << "AnimationContent::paint()"; + const QPixmap &frame = m_movie.framePixmap(); + if (width >= frame.width()) // Full size + painter->drawPixmap(0, 0, frame); + else // Scalled down + painter->drawPixmap(0, 0, frame); // TODO: Scall down +} + +bool AnimationContent::loadFromFile(bool lazyLoad) +{ + if (lazyLoad) + return true; + else + return finishLazyLoad(); +} + +bool AnimationContent::finishLazyLoad() +{ + DEBUG_WIN << "Loading MovieContent From " + basket()->folderName() + fileName(); +// return setMovie(QMovie(fullPath())); + + bool success = false; + QByteArray content; + if (basket()->loadFromFile(fullPath(), &content)) + success = setMovie(QMovie(content, content.size())); + if (!success) + setMovie(QMovie()); + return success; +} + +bool AnimationContent::saveToFile() +{ + // Impossible! + return false; +} + + +QString AnimationContent::messageWhenOpenning(OpenMessage where) +{ + switch (where) { + case OpenOne: return i18n("Opening animation..."); + case OpenSeveral: return i18n("Opening animations..."); + case OpenOneWith: return i18n("Opening animation with..."); + case OpenSeveralWith: return i18n("Opening animations with..."); + case OpenOneWithDialog: return i18n("Open animation with:"); + case OpenSeveralWithDialog: return i18n("Open animations with:"); + default: return ""; + } +} + +bool AnimationContent::setMovie(const QMovie &movie) +{ + if (!m_movie.isNull()) { + // Disconnect? + return false; + } + m_movie = movie; + m_movie.connectUpdate( this, SLOT(movieUpdated(const QRect&)) ); + m_movie.connectResize( this, SLOT(movieResized(const QSize&)) ); + m_movie.connectStatus( this, SLOT(movieStatus(int)) ); + contentChanged( m_movie.framePixmap().width() + 1 ); // TODO + return true; +} + +void AnimationContent::movieUpdated(const QRect&) +{ + note()->unbufferize(); + note()->update(); +} + +void AnimationContent::movieResized(const QSize&) +{ + note()->requestRelayout(); // ? +} + +/** When a user drop a .gif file, for instance, we don't know if it is an image + * or an animtion (gif file contain multiple images). + * To determin that, we assume this is an animation and count the number of images. + * QMovie send, in this order: + * - For a unique image: QMovie::EndOfFrame, QMovie::EndOfLoop, QMovie::EndOfMovie. + * - For animation: QMovie::EndOfFrame... (for each image), QMovie::EndOfLoop, + * and it then restart that for each loop. + */ +void AnimationContent::movieStatus(int status) +{ + DEBUG_WIN << "movieStatus()"; + + // At least two frames: it's an animation, everything is OK + if (m_oldStatus == QMovie::EndOfFrame && status == QMovie::EndOfFrame) { + movie().disconnectStatus(this); + m_oldStatus = INVALID_STATUS; +// if (note()->isFocused()) // When inserting a new note we ensure it visble +// basket()->ensureNoteVisible(note()); // But after loading it has certainly grown and if it was + } + // Only one image: it's an image, change note's type + else if (m_oldStatus == QMovie::EndOfFrame && status == QMovie::EndOfLoop) { + movie().disconnectStatus(this); + m_oldStatus = INVALID_STATUS; + note()->setContent(new ImageContent(note(), fileName())); + basket()->save(); + //delete this; // CRASH, as always !!!!!!!!! + //QTimer::singleShot(0, this, SLOT(loadContent())); // Delayed to avoid crash! + //QTimer::singleShot(100, this, SLOT(saveProperties())); // We should save it's an image and not an animation +// if (note()->isFocused()) +// QTimer::singleShot(25, note(), SLOT(delayedEnsureVisible())); + } + else + m_oldStatus = status; +} + +void AnimationContent::exportToHTML(HTMLExporter *exporter, int /*indent*/) +{ + exporter->stream << QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">") + .arg( exporter->dataFolderName + exporter->copyFile(fullPath(), /*createIt=*/true), + QString::number(movie().framePixmap().size().width()), + QString::number(movie().framePixmap().size().height()) ); +} + +/** class FileContent: + */ + +FileContent::FileContent(Note *parent, const QString &fileName) + : NoteContent(parent, fileName), m_previewJob(0) +{ + basket()->addWatchedFile(fullPath()); + setFileName(fileName); // FIXME: TO THAT HERE BECAUSE NoteContent() constructor seems to don't be able to call virtual methods??? +} + +int FileContent::setWidthAndGetHeight(int width) +{ + m_linkDisplay.setWidth(width); + return m_linkDisplay.height(); +} + +void FileContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered) +{ + m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0); +} + +bool FileContent::loadFromFile(bool /*lazyLoad*/) +{ + setFileName(fileName()); // File changed: get new file preview! + return true; +} + +void FileContent::toolTipInfos(QStringList *keys, QStringList *values) +{ + // Get the size of the file: + uint size = QFileInfo(fullPath()).size(); + QString humanFileSize = KIO::convertSize((KIO::filesize_t)size); + + keys->append(i18n("Size")); + values->append(humanFileSize); + + KMimeType::Ptr mime = KMimeType::findByURL(KURL(fullPath())); + if (mime) { + keys->append(i18n("Type")); + values->append(mime->comment()); + } + + KFileMetaInfo infos = KFileMetaInfo(KURL(fullPath())); + if (infos.isValid() && !infos.isEmpty()) { + QStringList groups = infos.preferredKeys(); + int i = 0; + for (QStringList::Iterator it = groups.begin(); i < 6 && it != groups.end(); ++it) { + KFileMetaInfoItem metaInfoItem = infos.item(*it); + if (!metaInfoItem.string().isEmpty()) { + keys->append(metaInfoItem.translatedKey()); + values->append(metaInfoItem.string()); + ++i; + } + } + } +} + +int FileContent::zoneAt(const QPoint &pos) +{ + return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0); +} + +QRect FileContent::zoneRect(int zone, const QPoint &/*pos*/) +{ + QRect linkRect = m_linkDisplay.iconButtonRect(); + + if (zone == Note::Custom0) + return QRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() + else if (zone == Note::Content) + return linkRect; + else + return QRect(); +} + +QString FileContent::zoneTip(int zone) +{ + return (zone == Note::Custom0 ? i18n("Open this file") : QString()); +} + +void FileContent::setCursor(QWidget *widget, int zone) +{ + if (zone == Note::Custom0) + widget->setCursor(Qt::PointingHandCursor); +} + + +int FileContent::xEditorIndent() +{ + return m_linkDisplay.iconButtonRect().width() + 2; +} + + +QString FileContent::messageWhenOpenning(OpenMessage where) +{ + switch (where) { + case OpenOne: return i18n("Opening file..."); + case OpenSeveral: return i18n("Opening files..."); + case OpenOneWith: return i18n("Opening file with..."); + case OpenSeveralWith: return i18n("Opening files with..."); + case OpenOneWithDialog: return i18n("Open file with:"); + case OpenSeveralWithDialog: return i18n("Open files with:"); + default: return ""; + } +} + +void FileContent::setFileName(const QString &fileName) +{ + NoteContent::setFileName(fileName); + KURL url = KURL(fullPath()); + if (linkLook()->previewEnabled()) + m_linkDisplay.setLink(fileName, NoteFactory::iconForURL(url), linkLook(), note()->font()); // FIXME: move iconForURL outside of NoteFactory !!!!! + else + m_linkDisplay.setLink(fileName, NoteFactory::iconForURL(url), QPixmap(), linkLook(), note()->font()); + startFetchingUrlPreview(); + contentChanged(m_linkDisplay.minWidth()); +} + +void FileContent::linkLookChanged() +{ + fontChanged(); + //setFileName(fileName()); + //startFetchingUrlPreview(); +} + +void FileContent::newPreview(const KFileItem*, const QPixmap &preview) +{ + LinkLook *linkLook = this->linkLook(); + m_linkDisplay.setLink(fileName(), NoteFactory::iconForURL(KURL(fullPath())), (linkLook->previewEnabled() ? preview : QPixmap()), linkLook, note()->font()); + contentChanged(m_linkDisplay.minWidth()); +} + +void FileContent::removePreview(const KFileItem*) +{ + newPreview(0, QPixmap()); +} + +void FileContent::startFetchingUrlPreview() +{ + KURL url(fullPath()); + LinkLook *linkLook = this->linkLook(); + +// delete m_previewJob; + if (!url.isEmpty() && linkLook->previewSize() > 0) { + KURL filteredUrl = NoteFactory::filteredURL(url);//KURIFilter::self()->filteredURI(url); + KURL::List urlList; + urlList.append(filteredUrl); + m_previewJob = KIO::filePreview(urlList, linkLook->previewSize(), linkLook->previewSize(), linkLook->iconSize()); + connect( m_previewJob, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)), this, SLOT(newPreview(const KFileItem*, const QPixmap&)) ); + connect( m_previewJob, SIGNAL(failed(const KFileItem*)), this, SLOT(removePreview(const KFileItem*)) ); + } +} + +void FileContent::exportToHTML(HTMLExporter *exporter, int indent) +{ + QString spaces; + QString fileName = exporter->copyFile(fullPath(), true); + exporter->stream << m_linkDisplay.toHtml(exporter, KURL(exporter->dataFolderName + fileName), "").replace("\n", "\n" + spaces.fill(' ', indent + 1)); +} + +/** class SoundContent: + */ + +SoundContent::SoundContent(Note *parent, const QString &fileName) + : FileContent(parent, fileName) +{ + setFileName(fileName); // FIXME: TO THAT HERE BECAUSE NoteContent() constructor seems to don't be able to call virtual methods??? +} + + +QString SoundContent::zoneTip(int zone) +{ + return (zone == Note::Custom0 ? i18n("Open this sound") : QString()); +} + +void SoundContent::setHoveredZone(int oldZone, int newZone) +{ +#ifdef WITHOUT_ARTS + Q_UNUSED(oldZone); + if (newZone == Note::Custom0 || newZone == Note::Content) + std::cout << "Compiled without aRts: sound is not played." << std::endl; +#else + static KArtsDispatcher *s_dispatcher = new KArtsDispatcher(); // Needed for s_playObj (we don't use it directly) + static KArtsServer *s_playServer = new KArtsServer(); + static KDE::PlayObjectFactory *s_playFactory = new KDE::PlayObjectFactory(s_playServer); + static KDE::PlayObject *s_playObj = 0; + + Q_UNUSED(s_dispatcher); // Avoid the compiler to tell us it is not used! + if (newZone == Note::Custom0 || newZone == Note::Content) { + // Start the sound preview: + if (oldZone != Note::Custom0 && oldZone != Note::Content) { // Don't restart if it was already in one of those zones + s_playObj = s_playFactory->createPlayObject(fullPath(), true); + s_playObj->play(); + } + } else { + // Stop the sound preview, if it was started: + if (s_playObj) { + s_playObj->halt(); + delete s_playObj; + s_playObj = 0; + } + } +#endif +} + + +QString SoundContent::messageWhenOpenning(OpenMessage where) +{ + switch (where) { + case OpenOne: return i18n("Opening sound..."); + case OpenSeveral: return i18n("Opening sounds..."); + case OpenOneWith: return i18n("Opening sound with..."); + case OpenSeveralWith: return i18n("Opening sounds with..."); + case OpenOneWithDialog: return i18n("Open sound with:"); + case OpenSeveralWithDialog: return i18n("Open sounds with:"); + default: return ""; + } +} + +/** class LinkContent: + */ + +LinkContent::LinkContent(Note *parent, const KURL &url, const QString &title, const QString &icon, bool autoTitle, bool autoIcon) + : NoteContent(parent), m_previewJob(0) +{ + setLink(url, title, icon, autoTitle, autoIcon); +} + +int LinkContent::setWidthAndGetHeight(int width) +{ + m_linkDisplay.setWidth(width); + return m_linkDisplay.height(); +} + +void LinkContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered) +{ + m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0); +} + +void LinkContent::saveToNode(QDomDocument &doc, QDomElement &content) +{ + content.setAttribute("title", title() ); + content.setAttribute("icon", icon() ); + content.setAttribute("autoTitle", (autoTitle() ? "true" : "false")); + content.setAttribute("autoIcon", (autoIcon() ? "true" : "false")); + QDomText textNode = doc.createTextNode(url().prettyURL()); + content.appendChild(textNode); +} + + +void LinkContent::toolTipInfos(QStringList *keys, QStringList *values) +{ + keys->append(i18n("Target")); + values->append(m_url.prettyURL()); +} + +int LinkContent::zoneAt(const QPoint &pos) +{ + return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0); +} + +QRect LinkContent::zoneRect(int zone, const QPoint &/*pos*/) +{ + QRect linkRect = m_linkDisplay.iconButtonRect(); + + if (zone == Note::Custom0) + return QRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() + else if (zone == Note::Content) + return linkRect; + else + return QRect(); +} + +QString LinkContent::zoneTip(int zone) +{ + return (zone == Note::Custom0 ? i18n("Open this link") : QString()); +} + +void LinkContent::setCursor(QWidget *widget, int zone) +{ + if (zone == Note::Custom0) + widget->setCursor(Qt::PointingHandCursor); +} + +QString LinkContent::statusBarMessage(int zone) +{ + if (zone == Note::Custom0 || zone == Note::Content) + return m_url.prettyURL(); + else + return ""; +} + + +KURL LinkContent::urlToOpen(bool /*with*/) +{ + return NoteFactory::filteredURL(url());//KURIFilter::self()->filteredURI(url()); +} + +QString LinkContent::messageWhenOpenning(OpenMessage where) +{ + if (url().isEmpty()) + return i18n("Link have no URL to open."); + + switch (where) { + case OpenOne: return i18n("Opening link target..."); + case OpenSeveral: return i18n("Opening link targets..."); + case OpenOneWith: return i18n("Opening link target with..."); + case OpenSeveralWith: return i18n("Opening link targets with..."); + case OpenOneWithDialog: return i18n("Open link target with:"); + case OpenSeveralWithDialog: return i18n("Open link targets with:"); + default: return ""; + } +} + +void LinkContent::setLink(const KURL &url, const QString &title, const QString &icon, bool autoTitle, bool autoIcon) +{ + m_autoTitle = autoTitle; + m_autoIcon = autoIcon; + m_url = NoteFactory::filteredURL(KURL(url));//KURIFilter::self()->filteredURI(url); + m_title = (autoTitle ? NoteFactory::titleForURL(m_url) : title); + m_icon = (autoIcon ? NoteFactory::iconForURL(m_url) : icon); + + LinkLook *look = LinkLook::lookForURL(m_url); + if (look->previewEnabled()) + m_linkDisplay.setLink(m_title, m_icon, look, note()->font()); + else + m_linkDisplay.setLink(m_title, m_icon, QPixmap(), look, note()->font()); + startFetchingUrlPreview(); + contentChanged(m_linkDisplay.minWidth()); +} + +void LinkContent::linkLookChanged() +{ + fontChanged(); +} + +void LinkContent::newPreview(const KFileItem*, const QPixmap &preview) +{ + LinkLook *linkLook = LinkLook::lookForURL(url()); + m_linkDisplay.setLink(title(), icon(), (linkLook->previewEnabled() ? preview : QPixmap()), linkLook, note()->font()); + contentChanged(m_linkDisplay.minWidth()); +} + +void LinkContent::removePreview(const KFileItem*) +{ + newPreview(0, QPixmap()); +} + +// Code dupicated from FileContent::startFetchingUrlPreview() +void LinkContent::startFetchingUrlPreview() +{ + KURL url = this->url(); + LinkLook *linkLook = LinkLook::lookForURL(this->url()); + +// delete m_previewJob; + if (!url.isEmpty() && linkLook->previewSize() > 0) { + KURL filteredUrl = NoteFactory::filteredURL(url);//KURIFilter::self()->filteredURI(url); + KURL::List urlList; + urlList.append(filteredUrl); + m_previewJob = KIO::filePreview(urlList, linkLook->previewSize(), linkLook->previewSize(), linkLook->iconSize()); + connect( m_previewJob, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)), this, SLOT(newPreview(const KFileItem*, const QPixmap&)) ); + connect( m_previewJob, SIGNAL(failed(const KFileItem*)), this, SLOT(removePreview(const KFileItem*)) ); + } +} + +void LinkContent::exportToHTML(HTMLExporter *exporter, int indent) +{ + QString linkTitle = title(); + +// TODO: +// // Append address (useful for print version of the page/basket): +// if (exportData.formatForImpression && (!autoTitle() && title() != NoteFactory::titleForURL(url().prettyURL()))) { +// // The address is on a new line, unless title is empty (empty lines was replaced by ): +// if (linkTitle == " "/*" "*/) +// linkTitle = url().prettyURL()/*""*/; +// else +// linkTitle = linkTitle + " <" + url().prettyURL() + ">"/*+ "<br>"*/; +// //linkTitle += "<i>" + url().prettyURL() + "</i>"; +// } + + KURL linkURL; +/* + QFileInfo fInfo(url().path()); +// DEBUG_WIN << url().path() +// << "IsFile:" + QString::number(fInfo.isFile()) +// << "IsDir:" + QString::number(fInfo.isDir()); + if (exportData.embedLinkedFiles && fInfo.isFile()) { +// DEBUG_WIN << "Embed file"; + linkURL = exportData.dataFolderName + Basket::copyFile(url().path(), exportData.dataFolderPath, true); + } else if (exportData.embedLinkedFolders && fInfo.isDir()) { +// DEBUG_WIN << "Embed folder"; + linkURL = exportData.dataFolderName + Basket::copyFile(url().path(), exportData.dataFolderPath, true); + } else { +// DEBUG_WIN << "Embed LINK"; +*/ + linkURL = url(); +/* + } +*/ + + QString spaces; + exporter->stream << m_linkDisplay.toHtml(exporter, linkURL, linkTitle).replace("\n", "\n" + spaces.fill(' ', indent + 1)); +} + +/** class LauncherContent: + */ + +LauncherContent::LauncherContent(Note *parent, const QString &fileName) + : NoteContent(parent, fileName) +{ + basket()->addWatchedFile(fullPath()); + loadFromFile(/*lazyLoad=*/false); +} + +int LauncherContent::setWidthAndGetHeight(int width) +{ + m_linkDisplay.setWidth(width); + return m_linkDisplay.height(); +} + +void LauncherContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered) +{ + m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0); +} + +bool LauncherContent::loadFromFile(bool /*lazyLoad*/) // TODO: saveToFile() ?? Is it possible? +{ + DEBUG_WIN << "Loading LauncherContent From " + basket()->folderName() + fileName(); + KService service(fullPath()); + setLauncher(service.name(), service.icon(), service.exec()); + return true; +} + + +void LauncherContent::toolTipInfos(QStringList *keys, QStringList *values) +{ + KService service(fullPath()); + + QString exec = service.exec(); + if (service.terminal()) + exec = i18n("%1 <i>(run in terminal)</i>").arg(exec); + + if (!service.comment().isEmpty() && service.comment() != service.name()) { + keys->append(i18n("Comment")); + values->append(service.comment()); + } + + keys->append(i18n("Command")); + values->append(exec); +} + +int LauncherContent::zoneAt(const QPoint &pos) +{ + return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0); +} + +QRect LauncherContent::zoneRect(int zone, const QPoint &/*pos*/) +{ + QRect linkRect = m_linkDisplay.iconButtonRect(); + + if (zone == Note::Custom0) + return QRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() + else if (zone == Note::Content) + return linkRect; + else + return QRect(); +} + +QString LauncherContent::zoneTip(int zone) +{ + return (zone == Note::Custom0 ? i18n("Launch this application") : QString()); +} + +void LauncherContent::setCursor(QWidget *widget, int zone) +{ + if (zone == Note::Custom0) + widget->setCursor(Qt::PointingHandCursor); +} + + +KURL LauncherContent::urlToOpen(bool with) +{ + if (KService(fullPath()).exec().isEmpty()) + return KURL(); + + return (with ? KURL() : KURL(fullPath())); // Can open the appliation, but not with another application :-) +} + +QString LauncherContent::messageWhenOpenning(OpenMessage where) +{ + if (KService(fullPath()).exec().isEmpty()) + return i18n("The launcher have no command to run."); + + switch (where) { + case OpenOne: return i18n("Launching application..."); + case OpenSeveral: return i18n("Launching applications..."); + case OpenOneWith: + case OpenSeveralWith: + case OpenOneWithDialog: + case OpenSeveralWithDialog: // TODO: "Open this application with this file as parameter"? + default: return ""; + } +} + +void LauncherContent::setLauncher(const QString &name, const QString &icon, const QString &exec) +{ + m_name = name; + m_icon = icon; + m_exec = exec; + + m_linkDisplay.setLink(name, icon, LinkLook::launcherLook, note()->font()); + contentChanged(m_linkDisplay.minWidth()); +} + +void LauncherContent::exportToHTML(HTMLExporter *exporter, int indent) +{ + QString spaces; + QString fileName = exporter->copyFile(fullPath(), /*createIt=*/true); + exporter->stream << m_linkDisplay.toHtml(exporter, KURL(exporter->dataFolderName + fileName), "").replace("\n", "\n" + spaces.fill(' ', indent + 1)); +} + +/** class ColorContent: + */ + +const int ColorContent::RECT_MARGIN = 2; + +ColorContent::ColorContent(Note *parent, const QColor &color) + : NoteContent(parent) +{ + setColor(color); +} + +int ColorContent::setWidthAndGetHeight(int /*width*/) // We do not need width because we can't word-break, and width is always >= minWidth() +{ + // FIXME: Duplicate from setColor(): + QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name()); + int rectHeight = (textRect.height() + 2)*3/2; + return rectHeight; +} + +void ColorContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) +{ + // FIXME: Duplicate from setColor(): + QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name()); + int rectHeight = (textRect.height() + 2)*3/2; + int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. + + // FIXME: Duplicate from CommonColorSelector::drawColorRect: + // Fill: + painter->fillRect(1, 1, rectWidth - 2, rectHeight - 2, color()); + // Stroke: + QColor stroke = color().dark(125); + painter->setPen(stroke); + painter->drawLine(1, 0, rectWidth - 2, 0); + painter->drawLine(0, 1, 0, rectHeight - 2); + painter->drawLine(1, rectHeight - 1, rectWidth - 2, rectHeight - 1); + painter->drawLine(rectWidth - 1, 1, rectWidth - 1, rectHeight - 2); + // Round corners: + painter->setPen(Tools::mixColor(color(), stroke)); + painter->drawPoint(1, 1); + painter->drawPoint(1, rectHeight - 2); + painter->drawPoint(rectWidth - 2, rectHeight - 2); + painter->drawPoint(rectWidth - 2, 1); + + // Draw the text: + painter->setFont(note()->font()); + painter->setPen(colorGroup.text()); + painter->drawText(rectWidth + RECT_MARGIN, 0, width - rectWidth - RECT_MARGIN, height, Qt::AlignAuto | Qt::AlignVCenter, color().name()); +} + +void ColorContent::saveToNode(QDomDocument &doc, QDomElement &content) +{ + QDomText textNode = doc.createTextNode(color().name()); + content.appendChild(textNode); +} + + +void ColorContent::toolTipInfos(QStringList *keys, QStringList *values) +{ + int hue, saturation, value; + m_color.getHsv(hue, saturation, value); + + keys->append(i18n("RGB Colorspace: Red/Green/Blue", "RGB")); + values->append(i18n("<i>Red</i>: %1, <i>Green</i>: %2, <i>Blue</i>: %3,").arg(QString::number(m_color.red()), QString::number(m_color.green()), QString::number(m_color.blue()))); + + keys->append(i18n("HSV Colorspace: Hue/Saturation/Value", "HSV")); + values->append(i18n("<i>Hue</i>: %1, <i>Saturation</i>: %2, <i>Value</i>: %3,").arg(QString::number(hue), QString::number(saturation), QString::number(value))); + + static QString cssColors[] = { + "aqua", "00ffff", + "black", "000000", + "blue", "0000ff", + "fuchsia", "ff00ff", + "gray", "808080", + "green", "008000", + "lime", "00ff00", + "maroon", "800000", + "navy", "000080", + "olive", "808000", + "purple", "800080", + "red", "ff0000", + "silver", "c0c0c0", + "teal", "008080", + "white", "ffffff", + "yellow", "ffff00" + }; + + static QString cssExtendedColors[] = { + "aliceblue", "f0f8ff", + "antiquewhite", "faebd7", + "aquamarine", "7fffd4", + "azure", "f0ffff", + "beige", "f5f5dc", + "bisque", "ffe4c4", + "blanchedalmond", "ffebcd", + "blueviolet", "8a2be2", + "brown", "a52a2a", + "burlywood", "deb887", + "cadetblue", "5f9ea0", + "chartreuse", "7fff00", + "chocolate", "d2691e", + "coral", "ff7f50", + "cornflowerblue", "6495ed", + "cornsilk", "fff8dc", + "crimson", "dc1436", + "cyan", "00ffff", + "darkblue", "00008b", + "darkcyan", "008b8b", + "darkgoldenrod", "b8860b", + "darkgray", "a9a9a9", + "darkgreen", "006400", + "darkkhaki", "bdb76b", + "darkmagenta", "8b008b", + "darkolivegreen", "556b2f", + "darkorange", "ff8c00", + "darkorchid", "9932cc", + "darkred", "8b0000", + "darksalmon", "e9967a", + "darkseagreen", "8fbc8f", + "darkslateblue", "483d8b", + "darkslategray", "2f4f4f", + "darkturquoise", "00ced1", + "darkviolet", "9400d3", + "deeppink", "ff1493", + "deepskyblue", "00bfff", + "dimgray", "696969", + "dodgerblue", "1e90ff", + "firebrick", "b22222", + "floralwhite", "fffaf0", + "forestgreen", "228b22", + "gainsboro", "dcdcdc", + "ghostwhite", "f8f8ff", + "gold", "ffd700", + "goldenrod", "daa520", + "greenyellow", "adff2f", + "honeydew", "f0fff0", + "hotpink", "ff69b4", + "indianred", "cd5c5c", + "indigo", "4b0082", + "ivory", "fffff0", + "khaki", "f0e68c", + "lavender", "e6e6fa", + "lavenderblush", "fff0f5", + "lawngreen", "7cfc00", + "lemonchiffon", "fffacd", + "lightblue", "add8e6", + "lightcoral", "f08080", + "lightcyan", "e0ffff", + "lightgoldenrodyellow", "fafad2", + "lightgreen", "90ee90", + "lightgrey", "d3d3d3", + "lightpink", "ffb6c1", + "lightsalmon", "ffa07a", + "lightseagreen", "20b2aa", + "lightskyblue", "87cefa", + "lightslategray", "778899", + "lightsteelblue", "b0c4de", + "lightyellow", "ffffe0", + "limegreen", "32cd32", + "linen", "faf0e6", + "magenta", "ff00ff", + "mediumaquamarine", "66cdaa", + "mediumblue", "0000cd", + "mediumorchid", "ba55d3", + "mediumpurple", "9370db", + "mediumseagreen", "3cb371", + "mediumslateblue", "7b68ee", + "mediumspringgreen", "00fa9a", + "mediumturquoise", "48d1cc", + "mediumvioletred", "c71585", + "midnightblue", "191970", + "mintcream", "f5fffa", + "mistyrose", "ffe4e1", + "moccasin", "ffe4b5", + "navajowhite", "ffdead", + "oldlace", "fdf5e6", + "olivedrab", "6b8e23", + "orange", "ffa500", + "orangered", "ff4500", + "orchid", "da70d6", + "palegoldenrod", "eee8aa", + "palegreen", "98fb98", + "paleturquoise", "afeeee", + "palevioletred", "db7093", + "papayawhip", "ffefd5", + "peachpuff", "ffdab9", + "peru", "cd853f", + "pink", "ffc0cb", + "plum", "dda0dd", + "powderblue", "b0e0e6", + "rosybrown", "bc8f8f", + "royalblue", "4169e1", + "saddlebrown", "8b4513", + "salmon", "fa8072", + "sandybrown", "f4a460", + "seagreen", "2e8b57", + "seashell", "fff5ee", + "sienna", "a0522d", + "skyblue", "87ceeb", + "slateblue", "6a5acd", + "slategray", "708090", + "snow", "fffafa", + "springgreen", "00ff7f", + "steelblue", "4682b4", + "tan", "d2b48c", + "thistle", "d8bfd8", + "tomato", "ff6347", + "turquoise", "40e0d0", + "violet", "ee82ee", + "wheat", "f5deb3", + "whitesmoke", "f5f5f5", + "yellowgreen", "9acd32" + }; + + QString colorHex = color().name().mid(1); // Take the hexadecimal name of the color, without the '#'. + + bool cssColorFound = false; + for (int i = 0; i < 2*16; i += 2) { + if (colorHex == cssColors[i+1]) { + keys->append(i18n("CSS Color Name")); + values->append(cssColors[i]); + cssColorFound = true; + break; + } + } + + if (!cssColorFound) + for (int i = 0; i < 2*124; i += 2) { + if (colorHex == cssExtendedColors[i+1]) { + keys->append(i18n("CSS Extended Color Name")); + values->append(cssExtendedColors[i]); + break; + } + } + + keys->append(i18n("Is Web Color")); + values->append(Tools::isWebColor(color()) ? i18n("Yes") : i18n("No")); + +} + +void ColorContent::setColor(const QColor &color) +{ + m_color = color; + + QRect textRect = QFontMetrics(note()->font()).boundingRect(color.name()); + int rectHeight = (textRect.height() + 2)*3/2; + int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. + contentChanged(rectWidth + RECT_MARGIN + textRect.width() + RECT_MARGIN); // The second RECT_MARGIN is because textRect.width() is too short. I done a bug? Can't figure out. +} + +void ColorContent::addAlternateDragObjects(KMultipleDrag *dragObject) +{ + dragObject->addDragObject( new QColorDrag(color()) ); + +// addDragObject(new KColorDrag( note->color(), 0 )); +// addDragObject(new QTextDrag( note->color().name(), 0 )); + +/* // Creata and add the QDragObject: + storedDrag = new QStoredDrag("application/x-color"); + storedDrag->setEncodedData(*array); + dragObject->addDragObject(storedDrag); + delete array;*/ +} + +void ColorContent::exportToHTML(HTMLExporter *exporter, int /*indent*/) +{ + // FIXME: Duplicate from setColor(): TODO: rectSize() + QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name()); + int rectHeight = (textRect.height() + 2)*3/2; + int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. + + QString fileName = /*Tools::fileNameForNewFile(*/QString("color_%1.png").arg(color().name().lower().mid(1))/*, exportData.iconsFolderPath)*/; + QString fullPath = exporter->iconsFolderPath + fileName; + QPixmap colorIcon = KColorCombo2::colorRectPixmap(color(), /*isDefault=*/false, rectWidth, rectHeight); + colorIcon.save(fullPath, "PNG"); + QString iconHtml = QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">") + .arg(exporter->iconsFolderName + fileName, QString::number(colorIcon.width()), QString::number(colorIcon.height())); + + exporter->stream << iconHtml + " " + color().name(); +} + + + +/** class UnknownContent: + */ + +const int UnknownContent::DECORATION_MARGIN = 2; + +UnknownContent::UnknownContent(Note *parent, const QString &fileName) + : NoteContent(parent, fileName) +{ + basket()->addWatchedFile(fullPath()); + loadFromFile(/*lazyLoad=*/false); +} + +int UnknownContent::setWidthAndGetHeight(int width) +{ + width -= 1; + QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, width, 500000, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, m_mimeTypes); + return DECORATION_MARGIN + textRect.height() + DECORATION_MARGIN; +} + +// TODO: Move this function from note.cpp to class Tools: +extern void drawGradient( QPainter *p, const QColor &colorTop, const QColor & colorBottom, + int x, int y, int w, int h, + bool sunken, bool horz, bool flat ); /*const*/ + +void UnknownContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) +{ + width -= 1; + painter->setPen(colorGroup.text()); + + // FIXME: Duplicate from ColorContent::paint() and CommonColorSelector::drawColorRect: + // Fill with gradient: + drawGradient(painter, colorGroup.background(), colorGroup.background().dark(110), 1, 1, width - 2, height - 2, /*sunken=*/false, /*horz=*/true, /*flat=*/false); + // Stroke: + QColor stroke = Tools::mixColor(colorGroup.background(), colorGroup.text()); + painter->setPen(stroke); + painter->drawLine(1, 0, width - 2, 0); + painter->drawLine(0, 1, 0, height - 2); + painter->drawLine(1, height - 1, width - 2, height - 1); + painter->drawLine(width - 1, 1, width - 1, height - 2); + // Round corners: + painter->setPen(Tools::mixColor(colorGroup.background(), stroke)); + painter->drawPoint(1, 1); + painter->drawPoint(1, height - 2); + painter->drawPoint(width - 2, height - 2); + painter->drawPoint(width - 2, 1); + + painter->setPen(colorGroup.text()); + painter->drawText(DECORATION_MARGIN, DECORATION_MARGIN, width - 2*DECORATION_MARGIN, height - 2*DECORATION_MARGIN, + Qt::AlignAuto | Qt::AlignVCenter | Qt::WordBreak, m_mimeTypes); +} + +bool UnknownContent::loadFromFile(bool /*lazyLoad*/) +{ + DEBUG_WIN << "Loading UnknownContent From " + basket()->folderName() + fileName(); + QFile file(fullPath()); + if (file.open(IO_ReadOnly)) { + QDataStream stream(&file); + QString line; + m_mimeTypes = ""; + // Get the MIME-types names: + do { + if (!stream.atEnd()) { + stream >> line; + if (!line.isEmpty()) { + if (m_mimeTypes.isEmpty()) + m_mimeTypes += line; + else + m_mimeTypes += QString("\n") + line; + } + } + } while (!line.isEmpty() && !stream.atEnd()); + file.close(); + } + + QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, /*width=*/1, 500000, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, m_mimeTypes); + contentChanged(DECORATION_MARGIN + textRect.width() + DECORATION_MARGIN + 1); + return true; +} + +void UnknownContent::addAlternateDragObjects(KMultipleDrag *dragObject) +{ + QFile file(fullPath()); + if (file.open(IO_ReadOnly)) { + QDataStream stream(&file); + // Get the MIME types names: + QValueList<QString> mimes; + QString line; + do { + if (!stream.atEnd()) { + stream >> line; + if (!line.isEmpty()) + mimes.append(line); + } + } while (!line.isEmpty() && !stream.atEnd()); + // Add the streams: + Q_UINT64 size; // TODO: It was Q_UINT32 in version 0.5.0 ! + QByteArray *array; + QStoredDrag *storedDrag; + for (uint i = 0; i < mimes.count(); ++i) { + // Get the size: + stream >> size; + // Allocate memory to retreive size bytes and store them: + array = new QByteArray(size); + stream.readRawBytes(array->data(), size); + // Creata and add the QDragObject: + storedDrag = new QStoredDrag(*(mimes.at(i))); + storedDrag->setEncodedData(*array); + dragObject->addDragObject(storedDrag); + delete array; // FIXME: Should we? + } + file.close(); + } +} + +void UnknownContent::exportToHTML(HTMLExporter *exporter, int indent) +{ + QString spaces; + exporter->stream << "<div class=\"unknown\">" << mimeTypes().replace("\n", "\n" + spaces.fill(' ', indent + 1 + 1)) << "</div>"; +} + + + + +void NoteFactory__loadNode(const QDomElement &content, const QString &lowerTypeName, Note *parent, bool lazyLoad) +{ + if (lowerTypeName == "text") new TextContent( parent, content.text(), lazyLoad ); + else if (lowerTypeName == "html") new HtmlContent( parent, content.text(), lazyLoad ); + else if (lowerTypeName == "image") new ImageContent( parent, content.text(), lazyLoad ); + else if (lowerTypeName == "animation") new AnimationContent( parent, content.text(), lazyLoad ); + else if (lowerTypeName == "sound") new SoundContent( parent, content.text() ); + else if (lowerTypeName == "file") new FileContent( parent, content.text() ); + else if (lowerTypeName == "link") { + bool autoTitle = content.attribute("title") == content.text(); + bool autoIcon = content.attribute("icon") == NoteFactory::iconForURL(KURL(content.text())); + autoTitle = XMLWork::trueOrFalse( content.attribute("autoTitle"), autoTitle); + autoIcon = XMLWork::trueOrFalse( content.attribute("autoIcon"), autoIcon ); + new LinkContent( parent, KURL(content.text()), content.attribute("title"), content.attribute("icon"), autoTitle, autoIcon ); + } else if (lowerTypeName == "launcher") new LauncherContent( parent, content.text() ); + else if (lowerTypeName == "color") new ColorContent( parent, QColor(content.text()) ); + else if (lowerTypeName == "unknown") new UnknownContent( parent, content.text() ); +} + +#include "notecontent.moc" |