/*************************************************************************** * * * 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 * ***************************************************************************/ // own header #include "notewidget.h" //qt includes #include #include #include #include // kde includes #include #include // 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 TQTextEdit(view); m_pEditor->setFrameStyle(TQFrame::NoFrame | TQFrame::Plain); m_pEditor->setHScrollBarMode(TQScrollView::AlwaysOff); m_pEditor->setVScrollBarMode(TQScrollView::AlwaysOff); m_pEditor->setTextFormat(TQt::RichText); m_pEditor->setShown(true); setEditorGeometry(); connect(m_pView, TQT_SIGNAL(contentsMoving(int, int)), this, TQT_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; } TQString 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(TQFont 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 TQRect 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(); } TQString NoteWidget::getDoc() const { #if defined (NOTEWIDGET_EMBED_EDITOR) return m_pEditor->text(); #else return m_Text; #endif } void NoteWidget::setDoc(const TQString &newText) { #if defined (NOTEWIDGET_EMBED_EDITOR) m_pEditor->setText(newText); #else m_Text = newText; #endif } void NoteWidget::draw(TQPainter & p, int offsetX, int offsetY) { int margin = 10; int w = width()-1; int h= height()-1; TQPointArray 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() ) { TQBrush 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); } TQSize NoteWidget::calculateSize() { return TQSize(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(TQPainter * 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( TQt::black ); TQFont font = UMLWidget::getFont(); p->setFont( font ); const TQFontMetrics &fm = getFontMetrics(FT_NORMAL); const int fontHeight = fm.lineSpacing(); TQString text = getDoc(); if( text.length() == 0 ) return; TQString word = ""; TQString fullLine = ""; TQString 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; TQChar returnChar('\n'); TQChar 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, TQt::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, TQt::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, TQt::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( TQDomDocument & qDoc, TQDomElement & qElement ) { TQDomElement 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( TQDomElement & qElement ) { if( !UMLWidget::loadFromXMI( qElement ) ) return false; setZ( 20 ); //make sure always on top. setDoc( qElement.attribute("text", "") ); TQString diagramlink = qElement.attribute("diagramlink", ""); if (!diagramlink.isEmpty()) m_DiagramLink = STR2ID(diagramlink); return true; } #include "notewidget.moc"