diff --git a/src/domain/UBGraphicsItemZLevelUndoCommand.cpp b/src/domain/UBGraphicsItemZLevelUndoCommand.cpp index 85704afc..db8f8b3f 100644 --- a/src/domain/UBGraphicsItemZLevelUndoCommand.cpp +++ b/src/domain/UBGraphicsItemZLevelUndoCommand.cpp @@ -59,7 +59,7 @@ void UBGraphicsItemZLevelUndoCommand::undo(){ if(mDest == UBZLayerController::down || mDest == UBZLayerController::bottom){ // Move up QList::iterator downIt = mItems.end(); - for(downIt; downIt >= mItems.begin(); downIt--){ + for(; downIt >= mItems.begin(); downIt--){ for(int i=0; ichangeZLevelTo(*downIt, UBZLayerController::up); } diff --git a/src/domain/UBGraphicsTextItemDelegate.cpp b/src/domain/UBGraphicsTextItemDelegate.cpp index d3b6e5b0..3c22d6d9 100644 --- a/src/domain/UBGraphicsTextItemDelegate.cpp +++ b/src/domain/UBGraphicsTextItemDelegate.cpp @@ -45,13 +45,64 @@ const int UBGraphicsTextItemDelegate::sMinPixelSize = 8; const int UBGraphicsTextItemDelegate::sMinPointSize = 8; + +AlignTextButton::AlignTextButton(const QString &fileName, QGraphicsItem *pDelegated, QGraphicsItem *parent, Qt::WindowFrameSection section) + : DelegateButton(fileName, pDelegated, parent, section) + , lft(new QSvgRenderer(QString(":/images/plus.svg"))) + , cntr(new QSvgRenderer(QString(":/images/pause.svg"))) + , rght(new QSvgRenderer(QString(":/images/minus.svg"))) + , mxd(new QSvgRenderer(QString(":/images/reload.svg"))) +{ + setKind(k_left); +} + +AlignTextButton::~AlignTextButton() +{ + if (lft) delete lft; + if (cntr) delete cntr; + if (rght) delete rght; + if (mxd) delete mxd; +} + +void AlignTextButton::setKind(int pKind) +{ + if (mHideMixed && pKind == k_mixed) { + qDebug() << "Mixed button is hidden, can't process it"; + return; + } + mKind = pKind; + QSvgRenderer *rndrer = rndFromKind(pKind); + Q_ASSERT(rndrer); + setSharedRenderer(rndrer); +} + +void AlignTextButton::setNextKind() +{ + int mxKind = MAX_KIND; + if (mHideMixed) { + mxKind--; + } + setKind(mKind == mxKind ? 0 : ++mKind); +} + +int AlignTextButton::nextKind() const +{ + int mxKind = MAX_KIND; + if (mHideMixed) { + mxKind--; + } + int result = mKind; + return mKind == mxKind ? 0 : ++result; +} + UBGraphicsTextItemDelegate::UBGraphicsTextItemDelegate(UBGraphicsTextItem* pDelegated, QObject *) : UBGraphicsItemDelegate(pDelegated,0, GF_COMMON | GF_REVOLVABLE | GF_TOOLBAR_USED) + , mFontButton(0) + , mColorButton(0) + , mDecreaseSizeButton(0) + , mIncreaseSizeButton(0) + , mAlignButton(0) , mLastFontPixelSize(-1) - , mAlignLeftButton(0) - , mAlignCenterButton(0) - , mAlignRightButton(0) - , mAlighMixed(0) , delta(5) { delegated()->setData(UBGraphicsItemData::ItemEditable, QVariant(true)); @@ -70,6 +121,9 @@ UBGraphicsTextItemDelegate::UBGraphicsTextItemDelegate(UBGraphicsTextItem* pDele delegated()->adjustSize(); delegated()->contentsChanged(); + connect(delegated()->document(), SIGNAL(cursorPositionChanged(QTextCursor)), this, SLOT(onCursorPositionChanged(QTextCursor))); + connect(delegated()->document(), SIGNAL(modificationChanged(bool)), this, SLOT(onModificationChanged(bool))); + // NOOP } @@ -107,24 +161,35 @@ void UBGraphicsTextItemDelegate::buildButtons() { UBGraphicsItemDelegate::buildButtons(); - mFontButton = new DelegateButton(":/images/font.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); - mColorButton = new DelegateButton(":/images/color.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); - mDecreaseSizeButton = new DelegateButton(":/images/minus.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); - mIncreaseSizeButton = new DelegateButton(":/images/plus.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); + if (!mFontButton) { + mFontButton = new DelegateButton(":/images/font.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); + connect(mFontButton, SIGNAL(clicked(bool)), this, SLOT(pickFont())); + } + if (!mColorButton) { + mColorButton = new DelegateButton(":/images/color.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); + connect(mColorButton, SIGNAL(clicked(bool)), this, SLOT(pickColor())); + } - //Alignment buttons family - mAlignLeftButton = new DelegateButton(":/images/plus.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); - mAlignCenterButton = new DelegateButton(":/images/pause.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); - mAlignRightButton = new DelegateButton(":/images/minus.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); - mAlighMixed = new DelegateButton(":/images/reload.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); + if (!mDecreaseSizeButton) { + mDecreaseSizeButton = new DelegateButton(":/images/minus.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); + connect(mDecreaseSizeButton, SIGNAL(clicked(bool)), this, SLOT(decreaseSize())); + } + + if (!mIncreaseSizeButton) { + mIncreaseSizeButton = new DelegateButton(":/images/plus.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); + connect(mIncreaseSizeButton, SIGNAL(clicked(bool)), this, SLOT(increaseSize())); + } + + // Alignment button + if (!mAlignButton) { + mAlignButton = new AlignTextButton(":/images/plus.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); + connect(mAlignButton, SIGNAL(clicked()), this, SLOT(alignButtonProcess())); + } - connect(mFontButton, SIGNAL(clicked(bool)), this, SLOT(pickFont())); - connect(mColorButton, SIGNAL(clicked(bool)), this, SLOT(pickColor())); - connect(mDecreaseSizeButton, SIGNAL(clicked(bool)), this, SLOT(decreaseSize())); - connect(mIncreaseSizeButton, SIGNAL(clicked(bool)), this, SLOT(increaseSize())); QList itemsOnToolBar; - itemsOnToolBar << mFontButton << mColorButton << mDecreaseSizeButton << mIncreaseSizeButton << mFontButton; + itemsOnToolBar << mFontButton << mColorButton << mDecreaseSizeButton << mIncreaseSizeButton; + itemsOnToolBar << mAlignButton; mToolBarItem->setItemsOnToolBar(itemsOnToolBar); mToolBarItem->setShifting(true); mToolBarItem->setVisibleOnBoard(true); @@ -259,6 +324,58 @@ void UBGraphicsTextItemDelegate::increaseSize() ChangeTextSize(delta, changeSize); } +void UBGraphicsTextItemDelegate::alignButtonProcess() +{ + qDebug() << "alignButtonProcess() clicked"; + QObject *sndr = sender(); + + if (sndr == mAlignButton) { + qDebug() << "Align button"; + AlignTextButton *asAlText = static_cast(mAlignButton); + if (asAlText->nextKind() == AlignTextButton::k_mixed) { + restoreTextCursorFormats(); + } + asAlText->setNextKind(); + + QTextCursor cur = delegated()->textCursor(); + QTextBlockFormat fmt = cur.blockFormat(); + switch (asAlText->kind()) { + case AlignTextButton::k_left: + fmt.setAlignment(Qt::AlignLeft); + break; + case AlignTextButton::k_center: + fmt.setAlignment(Qt::AlignCenter); + break; + case AlignTextButton::k_right: + fmt.setAlignment(Qt::AlignRight); + break; + case AlignTextButton::k_mixed: + break; + } + + delegated()->setTextCursor(cur); + cur.setBlockFormat(fmt); + } + + qDebug() << "sender process" << sndr; +} + +void UBGraphicsTextItemDelegate::onCursorPositionChanged(const QTextCursor &cursor) +{ + qDebug() << "cursor position changed"; + qDebug() << "-----------------------"; + qDebug() << "we have a selection!" << cursor.selectionStart(); + qDebug() << "-----------------------"; + updateAlighButtonState(); +} + +void UBGraphicsTextItemDelegate::onModificationChanged(bool ch) +{ + Q_UNUSED(ch); + qDebug() << "modification changed"; + updateAlighButtonState(); +} + UBGraphicsTextItem* UBGraphicsTextItemDelegate::delegated() { return static_cast(mDelegated); @@ -344,6 +461,47 @@ void UBGraphicsTextItemDelegate::positionHandles() } } +bool UBGraphicsTextItemDelegate::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + mSelectionData.mButtonIsPressed = true; + qDebug() << "Reporting selection of the cursor (mouse press)" << delegated()->textCursor().selection().isEmpty(); + qDebug() << QString("Anchor: %1\nposition: %2 (mouse press)").arg(delegated()->textCursor().anchor()).arg(delegated()->textCursor().position()); + + if (!UBGraphicsItemDelegate::mousePressEvent(event)) { + return false; + } + + return true; +} + +bool UBGraphicsTextItemDelegate::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (mSelectionData.mButtonIsPressed) { + qDebug() << "Reporting selection of the cursor (mouse move)" << delegated()->textCursor().selection().isEmpty(); + qDebug() << QString("Anchor: %1\nposition: %2 (mouse mouse move)").arg(delegated()->textCursor().anchor()).arg(delegated()->textCursor().position()); + } + + if (!UBGraphicsItemDelegate::mouseMoveEvent(event)) { + return false; + } + + return true; +} + +bool UBGraphicsTextItemDelegate::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + mSelectionData.mButtonIsPressed = false; + qDebug() << "Reporting selection of the cursor (mouse release)" << delegated()->textCursor().selection().isEmpty(); + qDebug() << QString("Anchor: %1\nposition: %2 (mouse mouse release)").arg(delegated()->textCursor().anchor()).arg(delegated()->textCursor().position()); + updateAlighButtonState(); + + if (!UBGraphicsItemDelegate::mouseReleaseEvent(event)) { + return false; + } + + return true; +} + void UBGraphicsTextItemDelegate::ChangeTextSize(qreal factor, textChangeMode changeMode) { if (scaleSize == changeMode) @@ -352,8 +510,8 @@ void UBGraphicsTextItemDelegate::ChangeTextSize(qreal factor, textChangeMode cha return; } else - if (0 == factor) - return; + if (0 == factor) + return; UBGraphicsTextItem *item = dynamic_cast(delegated()); @@ -445,6 +603,77 @@ void UBGraphicsTextItemDelegate::ChangeTextSize(qreal factor, textChangeMode cha delegated()->setTextCursor(cursor); } +void UBGraphicsTextItemDelegate::updateAlighButtonState() +{ + if (!mAlignButton) { + return; + } + + AlignTextButton *asAlBtn = static_cast(mAlignButton); + + if (!oneBlockSelection()) { + asAlBtn->setMixedButtonVisible(true); + asAlBtn->setKind(AlignTextButton::k_mixed); + saveTextCursorFormats(); + return; + } + + asAlBtn->setMixedButtonVisible(false); + switch (static_cast(delegated()->textCursor().blockFormat().alignment())) { + case Qt::AlignCenter : + asAlBtn->setKind(AlignTextButton::k_center); + break; + case Qt::AlignRight : + asAlBtn->setKind(AlignTextButton::k_right); + break; + default: + asAlBtn->setKind(AlignTextButton::k_left); + break; + } +} + +bool UBGraphicsTextItemDelegate::oneBlockSelection() +{ + const QTextCursor cursor = delegated()->textCursor(); + int pos = cursor.position(); + int anchor = cursor.anchor(); + + // no selection + if (pos == anchor) { + return true; + } + + //selecton within one text block + QTextBlock blck = cursor.block(); + if (blck.contains(pos) && blck.contains(anchor)) { + return true; + } + + //otherwise + return false; +} + +void UBGraphicsTextItemDelegate::saveTextCursorFormats() +{ + mSelectionData.anchor = delegated()->textCursor().anchor(); + mSelectionData.position = delegated()->textCursor().position(); + mSelectionData.html = delegated()->document()->toHtml(); +} + +void UBGraphicsTextItemDelegate::restoreTextCursorFormats() +{ + delegated()->document()->setHtml(mSelectionData.html); + + int min = qMin(mSelectionData.position, mSelectionData.anchor); + int max = qMax(mSelectionData.position, mSelectionData.anchor); + int steps = max - min; + + QTextCursor tcrsr = delegated()->textCursor(); + tcrsr.setPosition(mSelectionData.position); + tcrsr.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor, steps); + delegated()->setTextCursor(tcrsr); +} + void UBGraphicsTextItemDelegate::scaleTextSize(qreal multiplyer) { ChangeTextSize(multiplyer, scaleSize); diff --git a/src/domain/UBGraphicsTextItemDelegate.h b/src/domain/UBGraphicsTextItemDelegate.h index 7143f7eb..a6b4c5b1 100644 --- a/src/domain/UBGraphicsTextItemDelegate.h +++ b/src/domain/UBGraphicsTextItemDelegate.h @@ -37,6 +37,64 @@ class UBGraphicsTextItem; +class AlignTextButton : public DelegateButton +{ + Q_OBJECT + +public: + static const int MAX_KIND = 3; + enum kind_t{ + k_left = 0 + , k_center + , k_right + , k_mixed + }; + + AlignTextButton(const QString & fileName, QGraphicsItem* pDelegated, QGraphicsItem * parent = 0, Qt::WindowFrameSection section = Qt::TopLeftSection); + virtual ~AlignTextButton(); + + void setKind(int pKind); + int kind() {return mKind;} + + void setNextKind(); + int nextKind() const; + + void setMixedButtonVisible(bool v = true) {mHideMixed = !v;} + bool isMixedButtonVisible() {return !mHideMixed;} + +private: + + QSvgRenderer *rndFromKind(int pknd) + { + switch (pknd) { + case k_left: + return lft; + break; + case k_center: + return cntr; + break; + case k_right: + return rght; + break; + case k_mixed: + return mxd; + break; + } + + return 0; + } + + QSvgRenderer *curRnd() {return rndFromKind(mKind);} + + QPointer lft; + QPointer cntr; + QPointer rght; + QPointer mxd; + + int mKind; + bool mHideMixed; +}; + class UBGraphicsTextItemDelegate : public UBGraphicsItemDelegate { Q_OBJECT @@ -67,8 +125,11 @@ class UBGraphicsTextItemDelegate : public UBGraphicsItemDelegate virtual void positionHandles(); - private: + virtual bool mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual bool mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual bool mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + private: UBGraphicsTextItem* delegated(); DelegateButton* mFontButton; @@ -76,10 +137,7 @@ class UBGraphicsTextItemDelegate : public UBGraphicsItemDelegate DelegateButton* mDecreaseSizeButton; DelegateButton* mIncreaseSizeButton; - DelegateButton* mAlignLeftButton; - DelegateButton* mAlignCenterButton; - DelegateButton* mAlignRightButton; - DelegateButton* mAlighMixed; + DelegateButton* mAlignButton; int mLastFontPixelSize; @@ -89,9 +147,26 @@ class UBGraphicsTextItemDelegate : public UBGraphicsItemDelegate private: void customize(QFontDialog &fontDialog); void ChangeTextSize(qreal factor, textChangeMode changeMode); + void updateAlighButtonState(); + bool oneBlockSelection(); + void saveTextCursorFormats(); + void restoreTextCursorFormats(); + QFont createDefaultFont(); QAction *mEditableAction; + struct selectionData_t { + selectionData_t() + : mButtonIsPressed(false) + {} + bool mButtonIsPressed; + int position; + int anchor; + QString html; + QTextDocumentFragment selection; + QList fmts; + + } mSelectionData; private slots: @@ -101,9 +176,12 @@ class UBGraphicsTextItemDelegate : public UBGraphicsItemDelegate void decreaseSize(); void increaseSize(); + void alignButtonProcess(); + void onCursorPositionChanged(const QTextCursor& cursor); + void onModificationChanged(bool ch); + private: const int delta; - }; #endif /* UBGRAPHICSTEXTITEMDELEGATE_H_ */