summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/notewidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'umbrello/umbrello/notewidget.cpp')
-rw-r--r--umbrello/umbrello/notewidget.cpp316
1 files changed, 316 insertions, 0 deletions
diff --git a/umbrello/umbrello/notewidget.cpp b/umbrello/umbrello/notewidget.cpp
new file mode 100644
index 00000000..0cc7d079
--- /dev/null
+++ b/umbrello/umbrello/notewidget.cpp
@@ -0,0 +1,316 @@
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ * copyright (C) 2002-2006 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+// own header
+#include "notewidget.h"
+//qt includes
+#include <qpointarray.h>
+#include <qpainter.h>
+#include <qtextedit.h>
+#include <qframe.h>
+// kde includes
+#include <kdebug.h>
+#include <kcolordialog.h>
+// app includes
+#include "notewidgetcontroller.h"
+#include "dialogs/notedialog.h"
+#include "clipboard/umldrag.h"
+#include "umldoc.h"
+#include "umlview.h"
+#include "uml.h"
+#include "listpopupmenu.h"
+
+#define NOTEMARGIN 10
+
+NoteWidget::NoteWidget(UMLView * view, Uml::IDType id)
+ : UMLWidget(view, id, new NoteWidgetController(this)) {
+ init();
+ setSize(100,80);
+ setZ( 20 ); //make sure always on top.
+#ifdef NOTEWIDGET_EMBED_EDITOR
+ // NB: This code is currently deactivated because
+ // Zoom does not yet work with the embedded text editor.
+ m_pEditor = new QTextEdit(view);
+ m_pEditor->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
+ m_pEditor->setHScrollBarMode(QScrollView::AlwaysOff);
+ m_pEditor->setVScrollBarMode(QScrollView::AlwaysOff);
+ m_pEditor->setTextFormat(Qt::RichText);
+ m_pEditor->setShown(true);
+ setEditorGeometry();
+ connect(m_pView, SIGNAL(contentsMoving(int, int)),
+ this, SLOT(slotViewScrolled(int, int)));
+#endif
+}
+
+void NoteWidget::init() {
+ UMLWidget::setBaseType(Uml::wt_Note);
+ m_DiagramLink = Uml::id_None;
+}
+
+NoteWidget::~NoteWidget() {
+#ifdef NOTEWIDGET_EMBED_EDITOR
+ delete m_pEditor;
+#endif
+}
+
+void NoteWidget::setDiagramLink(Uml::IDType viewID) {
+ UMLDoc *umldoc = UMLApp::app()->getDocument();
+ UMLView *view = umldoc->findView(viewID);
+ if (view == NULL) {
+ kError() << "NoteWidget::setDiagramLink(" << ID2STR(viewID)
+ << "): no view found for this ID." << endl;
+ return;
+ }
+ QString linkText("Diagram: " + view->getName());
+#if defined (NOTEWIDGET_EMBED_EDITOR)
+ m_pEditor->setUnderline(true);
+ m_pEditor->insert(linkText);
+ m_pEditor->setUnderline(false);
+#else
+ setDoc(linkText);
+ update();
+#endif
+ m_DiagramLink = viewID;
+}
+
+Uml::IDType NoteWidget::getDiagramLink() const {
+ return m_DiagramLink;
+}
+
+void NoteWidget::slotViewScrolled(int x, int y) {
+ setEditorGeometry(x, y);
+}
+
+void NoteWidget::setFont(QFont font) {
+ UMLWidget::setFont(font);
+#ifdef NOTEWIDGET_EMBED_EDITOR
+ m_pEditor->setFont(font);
+#endif
+}
+
+void NoteWidget::setEditorGeometry(int dx /*=0*/, int dy /*=0*/) {
+#if defined (NOTEWIDGET_EMBED_EDITOR)
+ const QRect editorGeometry( UMLWidget::getX() - dx + 6,
+ UMLWidget::getY() - dy + 10,
+ UMLWidget::getWidth() - 16,
+ UMLWidget::getHeight() - 16);
+ m_pEditor->setGeometry( editorGeometry );
+ drawText();
+#else
+ dx=0; dy=0; // avoid "unused arg" warnings
+#endif
+}
+
+void NoteWidget::setX( int x ) {
+ UMLWidget::setX(x);
+ setEditorGeometry();
+}
+
+void NoteWidget::setY( int y ) {
+ UMLWidget::setY(y);
+ setEditorGeometry();
+}
+
+QString NoteWidget::getDoc() const {
+#if defined (NOTEWIDGET_EMBED_EDITOR)
+ return m_pEditor->text();
+#else
+ return m_Text;
+#endif
+}
+
+void NoteWidget::setDoc(const QString &newText) {
+#if defined (NOTEWIDGET_EMBED_EDITOR)
+ m_pEditor->setText(newText);
+#else
+ m_Text = newText;
+#endif
+}
+
+void NoteWidget::draw(QPainter & p, int offsetX, int offsetY) {
+ int margin = 10;
+ int w = width()-1;
+
+ int h= height()-1;
+ QPointArray poly(6);
+ poly.setPoint(0, offsetX, offsetY);
+ poly.setPoint(1, offsetX, offsetY + h);
+ poly.setPoint(2, offsetX + w, offsetY + h);
+ poly.setPoint(3, offsetX + w, offsetY + margin);
+ poly.setPoint(4, offsetX + w - margin, offsetY);
+ poly.setPoint(5, offsetX, offsetY);
+ UMLWidget::setPen(p);
+ if ( UMLWidget::getUseFillColour() ) {
+ QBrush brush( UMLWidget::getFillColour() );
+ p.setBrush(brush);
+ p.drawPolygon(poly);
+#if defined (NOTEWIDGET_EMBED_EDITOR)
+ m_pEditor->setPaper(brush);
+#endif
+ } else
+ p.drawPolyline(poly);
+ p.drawLine(offsetX + w - margin, offsetY, offsetX + w - margin, offsetY + margin);
+ p.drawLine(offsetX + w - margin, offsetY + margin, offsetX + w, offsetY + margin);
+ if(m_bSelected) {
+ drawSelected(&p, offsetX, offsetY);
+ }
+
+ drawText(&p, offsetX, offsetY);
+}
+
+QSize NoteWidget::calculateSize() {
+ return QSize(50, 50);
+}
+
+void NoteWidget::slotMenuSelection(int sel) {
+ NoteDialog * dlg = 0;
+ UMLDoc *doc = UMLApp::app()->getDocument();
+ switch(sel) {
+ ///OBSOLETE - remove ListPopupMenu::mt_Link_Docs
+ // case ListPopupMenu::mt_Link_Docs:
+ // m_pView->updateNoteWidgets();
+ // doc -> setModified(true);
+ // break;
+
+ case ListPopupMenu::mt_Rename:
+ m_pView -> updateDocumentation( false );
+ dlg = new NoteDialog( m_pView, this );
+ if( dlg -> exec() ) {
+ m_pView -> showDocumentation( this, true );
+ doc -> setModified(true);
+ update();
+ }
+ delete dlg;
+ break;
+
+ default:
+ UMLWidget::slotMenuSelection(sel);
+ break;
+ }
+}
+
+void NoteWidget::drawText(QPainter * p /*=NULL*/, int offsetX /*=0*/, int offsetY /*=0*/) {
+#if defined (NOTEWIDGET_EMBED_EDITOR)
+ m_pEditor->setText( getDoc() );
+ m_pEditor->setShown(true);
+ m_pEditor->repaint();
+#else
+ if (p == NULL)
+ return;
+ /*
+ Implement word wrap for text as follows:
+ wrap at width on whole words.
+ if word is wider than width then clip word
+ if reach height exit and don't print anymore
+ start new line on \n character
+ */
+ p->setPen( Qt::black );
+ QFont font = UMLWidget::getFont();
+ p->setFont( font );
+ const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+ const int fontHeight = fm.lineSpacing();
+ QString text = getDoc();
+ if( text.length() == 0 )
+ return;
+ QString word = "";
+ QString fullLine = "";
+ QString testCombineLine = "";
+ const int margin = fm.width( "W" );
+ int textY = fontHeight / 2;
+ int textX = margin;
+ const int width = this -> width() - margin * 2;
+ const int height = this -> height() - fontHeight;
+ QChar returnChar('\n');
+ QChar c;
+ for (uint i = 0; i <= text.length(); i++) {
+ if (i < text.length()) {
+ c = text[i];
+ } else {
+ // all chars of text have been handled already ->
+ // perform this last run to spool current content of "word"
+ c = returnChar;
+ }
+ if (c == returnChar || c.isSpace()) {
+ // new word delimiter found -> its time to decide on word wrap
+ testCombineLine = fullLine + ' ' + word;
+ int textWidth = fm.width( testCombineLine );
+ if (textX + textWidth > width) {
+ // combination of "fullLine" and "word" doesn't fit into one line ->
+ // print "fullLine" in current line, update write position to next line
+ // and decide then on following actions
+ p->drawText(offsetX + textX, offsetY + textY,
+ textWidth, fontHeight, Qt::AlignLeft, fullLine );
+ fullLine = word;
+ word = "";
+ // update write position
+ textX = margin;
+ textY += fontHeight;
+ if (textY > height)
+ return;
+ // in case of c==newline ->
+ // print "word" and set write position one additional line lower
+ if (c == returnChar) {
+ // print "word" - which is now "fullLine" and set to next line
+ p->drawText(offsetX + textX, offsetY + textY,
+ textWidth, fontHeight, Qt::AlignLeft, fullLine);
+ fullLine = "";
+ textX = margin;
+ textY += fontHeight;
+ if( textY > height ) return;
+ }
+ }
+ else if ( c == returnChar ) {
+ // newline found and combination of "fullLine" and "word" fits
+ // in one line
+ p->drawText(offsetX + textX, offsetY + textY,
+ textWidth, fontHeight, Qt::AlignLeft, testCombineLine);
+ fullLine = word = "";
+ textX = margin;
+ textY += fontHeight;
+ if (textY > height)
+ return;
+ } else {
+ // word delimiter found, and combination of "fullLine", space and "word" fits into one line
+ fullLine = testCombineLine;
+ word = "";
+ }
+ } else {
+ // no word delimiter found --> add current char to "word"
+ if (c != '\0')
+ word += c;
+ }
+ }//end for
+#endif
+}
+
+void NoteWidget::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) {
+ QDomElement noteElement = qDoc.createElement( "notewidget" );
+ UMLWidget::saveToXMI( qDoc, noteElement );
+ noteElement.setAttribute( "text", getDoc() );
+ if (m_DiagramLink != Uml::id_None)
+ noteElement.setAttribute( "diagramlink", ID2STR(m_DiagramLink) );
+ qElement.appendChild( noteElement );
+}
+
+bool NoteWidget::loadFromXMI( QDomElement & qElement ) {
+ if( !UMLWidget::loadFromXMI( qElement ) )
+ return false;
+ setZ( 20 ); //make sure always on top.
+ setDoc( qElement.attribute("text", "") );
+ QString diagramlink = qElement.attribute("diagramlink", "");
+ if (!diagramlink.isEmpty())
+ m_DiagramLink = STR2ID(diagramlink);
+ return true;
+}
+
+
+#include "notewidget.moc"
+