Rev 24657 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
12295 | fschmid | 1 | /* |
2 | For general Scribus (>=1.3.2) copyright and licensing information please refer |
||
3 | to the COPYING file provided with the program. Following this notice may exist |
||
4 | a copyright and/or license notice that predates the release of Scribus 1.3.2 |
||
5 | for which a new license (GPL+exception) is in place. |
||
6 | */ |
||
7 | /*************************************************************************** |
||
8 | sctreewidget.cpp - description |
||
9 | ------------------- |
||
10 | begin : Wed Jun 18 2008 |
||
11 | copyright : (C) 2008 by Franz Schmid |
||
12 | email : Franz.Schmid@altmuehlnet.de |
||
13 | ***************************************************************************/ |
||
14 | |||
15 | /*************************************************************************** |
||
16 | * * |
||
17 | * This program is free software; you can redistribute it and/or modify * |
||
18 | * it under the terms of the GNU General Public License as published by * |
||
19 | * the Free Software Foundation; either version 2 of the License, or * |
||
20 | * (at your option) any later version. * |
||
21 | * * |
||
22 | ***************************************************************************/ |
||
23 | |||
24 | #include <QAbstractItemModel> |
||
25 | #include <QStyle> |
||
26 | #include <QPainter> |
||
27 | #include <QHeaderView> |
||
12296 | fschmid | 28 | #include <QLayout> |
17383 | fschmid | 29 | #include <QShortcutEvent> |
12295 | fschmid | 30 | |
13650 | cbradney | 31 | #include "sctreewidget.h" |
12295 | fschmid | 32 | |
33 | ScTreeWidgetDelegate::ScTreeWidgetDelegate(QTreeWidget *view, QWidget *parent) : QItemDelegate(parent), m_view(view) |
||
34 | { |
||
35 | } |
||
36 | |||
37 | void ScTreeWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const |
||
38 | { |
||
39 | const QAbstractItemModel *model = index.model(); |
||
40 | Q_ASSERT(model); |
||
24658 | jghali | 41 | |
42 | if (model->parent(index).isValid()) |
||
12295 | fschmid | 43 | { |
24658 | jghali | 44 | QItemDelegate::paint(painter, option, index); |
45 | return; |
||
46 | } |
||
47 | |||
48 | // This is a top-level item. |
||
49 | QStyleOptionButton buttonOption; |
||
50 | buttonOption.state = option.state; |
||
18204 | fschmid | 51 | #if defined(Q_OS_MAC) || defined(Q_OS_WIN) |
24658 | jghali | 52 | buttonOption.state |= QStyle::State_Raised; |
12295 | fschmid | 53 | #endif |
24658 | jghali | 54 | buttonOption.state &= ~QStyle::State_HasFocus; |
55 | buttonOption.rect = option.rect; |
||
56 | buttonOption.palette = option.palette; |
||
57 | m_view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, m_view); |
||
24657 | jghali | 58 | |
24658 | jghali | 59 | // Draw arrow |
60 | static const int i = 9; // ### hardcoded in qcommonstyle.cpp |
||
61 | QRect r = option.rect; |
||
62 | QPalette::ColorGroup arrowColorGroup = (option.state & QStyle::State_Enabled) ? QPalette::Active : QPalette::Disabled; |
||
63 | QColor arrowColor = option.palette.color(arrowColorGroup, QPalette::ButtonText); |
||
64 | painter->save(); |
||
65 | painter->setBrush(arrowColor); |
||
66 | painter->setPen(Qt::NoPen); |
||
67 | QRect rect = QRect(r.left() + 6, r.top() + 6, r.height() - 12, r.height() - 12); |
||
68 | QPolygon pa(3); |
||
69 | if (m_view->isExpanded(index)) |
||
70 | { |
||
71 | pa.setPoint(0, rect.left(), rect.top()); |
||
72 | pa.setPoint(1, rect.right(), rect.top()); |
||
73 | pa.setPoint(2, rect.center().x(), rect.bottom()); |
||
12295 | fschmid | 74 | } |
75 | else |
||
24658 | jghali | 76 | { |
77 | pa.setPoint(0, rect.left(), rect.top()); |
||
78 | pa.setPoint(1, rect.left(), rect.bottom()); |
||
79 | pa.setPoint(2, rect.right(), rect.center().y()); |
||
80 | } |
||
81 | painter->setRenderHint(QPainter::Antialiasing, true); |
||
82 | painter->drawPolygon(pa); |
||
83 | painter->restore(); |
||
84 | |||
85 | // Draw text |
||
86 | QRect textrect = QRect(r.left() + i * 2, r.top(), r.width() - ((5 * i) / 2), r.height()); |
||
87 | QString text = option.fontMetrics.elidedText(model->data(index, Qt::DisplayRole).toString(), Qt::ElideMiddle, textrect.width(), Qt::TextShowMnemonic); |
||
88 | m_view->style()->drawItemText(painter, textrect, Qt::AlignCenter | Qt::TextShowMnemonic, option.palette, (option.state & QStyle::State_Enabled), text, QPalette::Text); |
||
12295 | fschmid | 89 | } |
90 | |||
91 | QSize ScTreeWidgetDelegate::sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const |
||
92 | { |
||
17383 | fschmid | 93 | QSize sz = QItemDelegate::sizeHint(opt, index) + QSize(2, 6); |
12295 | fschmid | 94 | return sz; |
95 | } |
||
96 | |||
97 | ScTreeWidget::ScTreeWidget(QWidget* pa) : QTreeWidget(pa) |
||
98 | { |
||
21095 | jghali | 99 | // #12204: Opening/Closing Properties palette tabs moves the view to the first document |
100 | // When a tab looses focus, this cause problems has Qt has to fallback to another widget |
||
101 | // for setting new focus, and this may be an arbitrary document window |
||
102 | // setFocusPolicy(Qt::NoFocus); |
||
12295 | fschmid | 103 | setColumnCount(1); |
104 | setItemDelegate(new ScTreeWidgetDelegate(this, this)); |
||
105 | setRootIsDecorated(false); |
||
106 | setIndentation(0); |
||
107 | header()->hide(); |
||
18194 | fschmid | 108 | header()->setSectionResizeMode(QHeaderView::Stretch); |
12295 | fschmid | 109 | viewport()->setBackgroundRole(QPalette::Window); |
17389 | fschmid | 110 | setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); |
23925 | jghali | 111 | |
12308 | fschmid | 112 | connect(this, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(handleMousePress(QTreeWidgetItem*))); |
12295 | fschmid | 113 | } |
114 | |||
17383 | fschmid | 115 | bool ScTreeWidget::event(QEvent *e) |
116 | { |
||
117 | if (e->type() == QEvent::Shortcut) |
||
118 | { |
||
119 | QShortcutEvent *se = static_cast<QShortcutEvent *>(e); |
||
22521 | craig | 120 | if (se != nullptr) |
17383 | fschmid | 121 | { |
122 | int k = se->shortcutId(); |
||
123 | QTreeWidgetItem *item1 = keySList.value(k); |
||
124 | handleMousePress(item1); |
||
125 | return true; |
||
126 | } |
||
127 | } |
||
128 | return QTreeWidget::event(e); |
||
129 | } |
||
130 | |||
22635 | craig | 131 | QTreeWidgetItem* ScTreeWidget::addWidget(const QString& title, QWidget* widget) |
12295 | fschmid | 132 | { |
133 | QTreeWidgetItem *item1 = new QTreeWidgetItem(this); |
||
134 | item1->setText(0, title); |
||
135 | item1->setFlags(Qt::ItemIsEnabled); |
||
136 | QTreeWidgetItem *item2 = new QTreeWidgetItem(item1); |
||
137 | item2->setFlags(Qt::ItemIsEnabled); |
||
12296 | fschmid | 138 | // hack to work around a bug in Qt-4.3.4 |
21575 | craig | 139 | // if (widget->layout()) |
140 | // { |
||
141 | // widget->layout()->activate(); |
||
142 | // widget->setMinimumSize(widget->layout()->minimumSize()); |
||
143 | // item2->setSizeHint(0, widget->layout()->minimumSize()); |
||
144 | // } |
||
12296 | fschmid | 145 | // end hack |
12295 | fschmid | 146 | setItemWidget(item2, 0, widget); |
17383 | fschmid | 147 | QKeySequence newMnemonic = QKeySequence::mnemonic(title); |
148 | // grabShortcut(newMnemonic); |
||
149 | keySList.insert(grabShortcut(newMnemonic), item1); |
||
12295 | fschmid | 150 | return item1; |
151 | } |
||
152 | |||
17383 | fschmid | 153 | void ScTreeWidget::setToolBoxMode(bool enable) |
154 | { |
||
23925 | jghali | 155 | m_toolboxMode = enable; |
17383 | fschmid | 156 | } |
157 | |||
22635 | craig | 158 | int ScTreeWidget::addItem(QWidget* widget, const QString& title) |
17383 | fschmid | 159 | { |
160 | QTreeWidgetItem *top = addWidget(title, widget); |
||
161 | return indexOfTopLevelItem(top); |
||
162 | } |
||
163 | |||
164 | QWidget* ScTreeWidget::widget(int index) |
||
165 | { |
||
166 | if ((index < 0) || (index >= topLevelItemCount())) |
||
22521 | craig | 167 | return nullptr; |
17383 | fschmid | 168 | QTreeWidgetItem *top = topLevelItem(index); |
169 | if (top->childCount() == 0) |
||
22521 | craig | 170 | return nullptr; |
17383 | fschmid | 171 | QTreeWidgetItem *child = top->child(0); |
172 | return itemWidget(child, 0); |
||
173 | } |
||
174 | |||
175 | void ScTreeWidget::setItemEnabled(int index, bool enable) |
||
176 | { |
||
177 | if ((index < 0) || (index >= topLevelItemCount())) |
||
178 | return; |
||
179 | if (enable) |
||
180 | topLevelItem(index)->setFlags(Qt::ItemIsEnabled); |
||
181 | else |
||
22652 | craig | 182 | topLevelItem(index)->setFlags(Qt::NoItemFlags); |
17387 | fschmid | 183 | QTreeWidgetItem *child = topLevelItem(index)->child(0); |
22521 | craig | 184 | if (child != nullptr) |
17387 | fschmid | 185 | itemWidget(child, 0)->setEnabled(enable); |
17383 | fschmid | 186 | } |
187 | |||
188 | bool ScTreeWidget::isItemEnabled(int index) |
||
189 | { |
||
190 | if ((index < 0) || (index >= topLevelItemCount())) |
||
191 | return false; |
||
192 | return !topLevelItem(index)->isDisabled(); |
||
193 | } |
||
194 | |||
195 | void ScTreeWidget::setCurrentIndex(int index) |
||
196 | { |
||
197 | if ((index < 0) || (index >= topLevelItemCount())) |
||
198 | return; |
||
199 | int tops = topLevelItemCount(); |
||
200 | for (int t = 0; t < tops; t++) |
||
201 | { |
||
21093 | jghali | 202 | topLevelItem(t)->setExpanded(false); |
17383 | fschmid | 203 | } |
204 | QTreeWidgetItem *top = topLevelItem(index); |
||
205 | setCurrentItem(top); |
||
21093 | jghali | 206 | top->setExpanded(true); |
17383 | fschmid | 207 | int wide = 0; |
208 | if (top->childCount() != 0) |
||
209 | { |
||
210 | QTreeWidgetItem *child = top->child(0); |
||
22601 | craig | 211 | if (child != nullptr) |
17383 | fschmid | 212 | wide = itemWidget(child, 0)->minimumSizeHint().width()+5; |
213 | } |
||
214 | if (wide != 0) |
||
215 | setColumnWidth(0, wide); |
||
216 | else |
||
217 | resizeColumnToContents(0); |
||
218 | } |
||
219 | |||
220 | int ScTreeWidget::currentIndex() |
||
221 | { |
||
222 | int index = -1; |
||
223 | QTreeWidgetItem* item = currentItem(); |
||
22601 | craig | 224 | if (item->parent() == nullptr) |
17383 | fschmid | 225 | index = indexOfTopLevelItem(item); |
226 | else |
||
227 | index = indexOfTopLevelItem(item->parent()); |
||
228 | return index; |
||
229 | } |
||
230 | |||
22601 | craig | 231 | void ScTreeWidget::setItemText(int index, const QString& text) |
17383 | fschmid | 232 | { |
233 | if ((index < 0) || (index >= topLevelItemCount())) |
||
234 | return; |
||
235 | topLevelItem(index)->setText(0, text); |
||
236 | } |
||
237 | |||
12295 | fschmid | 238 | void ScTreeWidget::handleMousePress(QTreeWidgetItem *item) |
239 | { |
||
22601 | craig | 240 | if (item == nullptr) |
12295 | fschmid | 241 | return; |
22601 | craig | 242 | if (item->parent() == nullptr) |
12295 | fschmid | 243 | { |
17383 | fschmid | 244 | if (item->isDisabled()) |
245 | { |
||
21093 | jghali | 246 | item->setExpanded(false); |
17383 | fschmid | 247 | return; |
248 | } |
||
249 | int wide = 0; |
||
12295 | fschmid | 250 | int tops = topLevelItemCount(); |
23925 | jghali | 251 | if (m_toolboxMode) |
12295 | fschmid | 252 | { |
17383 | fschmid | 253 | for (int t = 0; t < tops; t++) |
12295 | fschmid | 254 | { |
21093 | jghali | 255 | topLevelItem(t)->setExpanded(false); |
17383 | fschmid | 256 | } |
257 | setCurrentItem(item); |
||
21093 | jghali | 258 | item->setExpanded(true); |
17383 | fschmid | 259 | if (item->childCount() != 0) |
260 | { |
||
261 | QTreeWidgetItem *child = item->child(0); |
||
22601 | craig | 262 | if (child != nullptr) |
17383 | fschmid | 263 | wide = itemWidget(child, 0)->minimumSizeHint().width()+5; |
264 | } |
||
265 | if (wide != 0) |
||
266 | setColumnWidth(0, wide); |
||
267 | else |
||
268 | resizeColumnToContents(0); |
||
269 | } |
||
270 | else |
||
271 | { |
||
21093 | jghali | 272 | item->setExpanded(!item->isExpanded()); |
17383 | fschmid | 273 | for (int t = 0; t < tops; t++) |
274 | { |
||
275 | QTreeWidgetItem *top = topLevelItem(t); |
||
21093 | jghali | 276 | if (top->isExpanded()) |
12295 | fschmid | 277 | { |
17383 | fschmid | 278 | if (top->childCount() != 0) |
279 | { |
||
280 | QTreeWidgetItem *child = top->child(0); |
||
22601 | craig | 281 | if (child != nullptr) |
17383 | fschmid | 282 | wide = qMax(wide, itemWidget(child, 0)->minimumSizeHint().width()+5); |
283 | } |
||
12295 | fschmid | 284 | } |
285 | } |
||
286 | } |
||
287 | if (wide != 0) |
||
288 | setColumnWidth(0, wide); |
||
289 | else |
||
290 | resizeColumnToContents(0); |
||
17936 | craig | 291 | emit currentChanged2(indexOfTopLevelItem(item)); |
12295 | fschmid | 292 | } |
293 | } |