ctkFittedTextBrowser.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. All rights reserved.
  5. Distributed under a BSD License. See LICENSE.txt file.
  6. This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the above copyright notice for more information.
  9. =========================================================================*/
  10. // Qt includes
  11. #include <QDebug>
  12. #include <QTextBlock>
  13. #include <QAbstractTextDocumentLayout>
  14. // CTK includes
  15. #include "ctkFittedTextBrowser.h"
  16. //-----------------------------------------------------------------------------
  17. ctkFittedTextBrowser::ctkFittedTextBrowser(QWidget* _parent)
  18. : QTextBrowser(_parent)
  19. {
  20. this->connect(this, SIGNAL(textChanged()), SLOT(heightForWidthMayHaveChanged()));
  21. }
  22. //-----------------------------------------------------------------------------
  23. ctkFittedTextBrowser::~ctkFittedTextBrowser()
  24. {
  25. }
  26. //-----------------------------------------------------------------------------
  27. void ctkFittedTextBrowser::heightForWidthMayHaveChanged()
  28. {
  29. this->updateGeometry();
  30. }
  31. //-----------------------------------------------------------------------------
  32. int ctkFittedTextBrowser::heightForWidth(int _width) const
  33. {
  34. QTextDocument* doc = this->document();
  35. qreal savedWidth = doc->textWidth();
  36. // Fudge factor. This is the difference between the frame and the
  37. // viewport.
  38. int fudge = 2 * this->frameWidth();
  39. // Do the calculation assuming no scrollbars
  40. doc->setTextWidth(_width - fudge);
  41. int noScrollbarHeight =
  42. doc->documentLayout()->documentSize().height() + fudge;
  43. // (If noScrollbarHeight is greater than the maximum height we'll be
  44. // allowed, then there will be scrollbars, and the actual required
  45. // height will be even higher. But since in this case we've already
  46. // hit the maximum height, it doesn't matter that we underestimate.)
  47. // Get minimum height (even if string is empty): one line of text
  48. int _minimumHeight = QFontMetrics(doc->defaultFont()).lineSpacing() + fudge;
  49. int ret = qMax(noScrollbarHeight, _minimumHeight);
  50. doc->setTextWidth(savedWidth);
  51. return ret;
  52. }
  53. //-----------------------------------------------------------------------------
  54. QSize ctkFittedTextBrowser::minimumSizeHint() const {
  55. QSize s(this->size().width(), 0);
  56. if (s.width() == 0)
  57. {
  58. //s.setWidth(400); // arbitrary value
  59. return QTextBrowser::minimumSizeHint();
  60. }
  61. s.setHeight(this->heightForWidth(s.width()));
  62. return s;
  63. }
  64. //-----------------------------------------------------------------------------
  65. QSize ctkFittedTextBrowser::sizeHint() const {
  66. return this->minimumSizeHint();
  67. }
  68. //-----------------------------------------------------------------------------
  69. void ctkFittedTextBrowser::resizeEvent(QResizeEvent* e)
  70. {
  71. this->QTextBrowser::resizeEvent(e);
  72. if (e->size().height() != this->heightForWidth(e->size().width()))
  73. {
  74. this->heightForWidthMayHaveChanged();
  75. }
  76. }