1 #include "layoutwidget.h"
4 #include <taskmanager/taskmanager.h>
5 #include <taskmanager/abstractgroupableitem.h>
6 #include <taskmanager/groupmanager.h>
10 #include <QGraphicsScene>
11 #include <QGraphicsGridLayout>
16 #include "windowtaskitem.h"
17 #include "taskgroupitem.h"
20 //GroupItem Constructor
21 LayoutWidget::LayoutWidget(TaskGroupItem
*parent
, Tasks
*applet
)
34 foreach(AbstractTaskItem
*item
, m_groupItem
->memberList()) {
39 LayoutWidget::~LayoutWidget()
45 void LayoutWidget::init()
48 //calculatePreferredRowSize();
52 void LayoutWidget::constraintsChanged(Plasma::Constraints constraints
)
57 if (constraints
& Plasma::SizeConstraint
) {
62 void LayoutWidget::addTaskItem(AbstractTaskItem
* item
)
66 kDebug() << "invalid item";
69 if (m_itemPositions
.contains(item
)) {
70 kDebug() << "already in this layout";
73 if (item
->abstractItem()) {
74 if (item
->abstractItem()->isGroupItem()) {
75 connect(static_cast<TaskGroupItem
*>(item
), SIGNAL(changed()), this, SLOT(update())); //update on expanding group
78 if (m_groupItem
->scene() && !item
->scene()) {
79 //kDebug() << "layout widget got scene"<<m_groupItem->scene()<< "add item to scene" <<item->scene();
80 m_groupItem
->scene()->addItem(item
);
81 //kDebug() << "itemScene" << item->scene();
84 if (!insert(m_groupItem
->indexOf(item
), item
)) {
85 kDebug() << "error on insert";
92 void LayoutWidget::removeTaskItem(AbstractTaskItem
* item
)
100 if (m_groupItem
->scene()) {
101 //kDebug() << "got scene";
102 m_groupItem
->scene()->removeItem(item
);
104 kDebug() << "No Scene available";
106 //kDebug() << "done";
109 bool LayoutWidget::insert(int index
, AbstractTaskItem
* item
)
111 //kDebug() << item->text() << index;
117 for (listIndex
= 0; listIndex
< m_itemPositions
.size(); listIndex
++) {
118 if (index
<= m_groupItem
->indexOf(m_itemPositions
.at(listIndex
))) {
123 m_itemPositions
.insert(listIndex
, item
);
129 bool LayoutWidget::remove(AbstractTaskItem
* item
)
132 kDebug() << "null Item";
135 m_itemPositions
.removeAll(item
);
140 void LayoutWidget::update()
147 /** size including expanded groups*/
148 int LayoutWidget::size()
152 foreach (AbstractTaskItem
*item
, m_groupItem
->memberList()) {
153 if (!item
->abstractItem()) { //this item is a startup task
154 kDebug() << "Error, invalid item in groupMembers";
158 if (item
->abstractItem()->isGroupItem()) {
159 TaskGroupItem
*group
= static_cast<TaskGroupItem
*>(item
);
160 if (!group
->collapsed()) {
161 LayoutWidget
*layout
= dynamic_cast<LayoutWidget
*>(group
->layoutWidget());
163 kDebug() << "Error group has no layout";
166 groupSize
+= layout
->size();// increase number of items since expanded groups occupy several spaces
173 //kDebug() << "group size" << groupSize;
177 //return maximum colums set by the user unless the setting is to high and the items would get unusable
178 int LayoutWidget::maximumRows()
181 if (m_itemPositions
.isEmpty()) {
189 // in this case rows are columns, columns are rows...
190 //TODO basicPreferredSize isn't the optimal source here because it changes because of margins probably
191 QSizeF itemSize
= m_itemPositions
.first()->basicPreferredSize();
192 if (m_applet
->formFactor() == Plasma::Vertical
) {
193 maxRows
= qMin(qMax(1, int(m_groupItem
->geometry().width() / itemSize
.width())), m_maxRows
);
195 maxRows
= qMin(qMax(1, int(m_groupItem
->geometry().height() / itemSize
.height())), m_maxRows
);
197 //kDebug() << "maximum rows: " << maxRows << m_maxRows << m_groupItem->geometry().height() << itemSize.height();
201 //returns a reasonable amount of columns
202 int LayoutWidget::preferredColumns()
207 if (m_itemPositions
.isEmpty()) {
211 //TODO basicPreferredSize isn't the optimal source here because it changes because of margins probably
212 QSizeF itemSize
= m_itemPositions
.first()->basicPreferredSize();
213 //kDebug() << itemSize.width() << m_groupItem->geometry().width();
214 if (m_applet
->formFactor() == Plasma::Vertical
) {
215 m_rowSize
= qMax(1, int(m_groupItem
->geometry().height() / itemSize
.height()));
217 m_rowSize
= qMax(1, int(m_groupItem
->geometry().width() / itemSize
.width()));
220 //kDebug() << "preferred columns: " << qMax(1, qMin(m_rowSize, size()));
221 return qMax(1, qMin(m_rowSize
, size()));
224 QPair
<int, int> LayoutWidget::gridLayoutSize()
226 int groupSize
= size();
228 int columns
= preferredColumns();
229 int maxRows
= maximumRows();
231 //check for adjustments on columns because there isnt room enough yet for all of the items
232 while (ceil(static_cast<float>(groupSize
)/static_cast<float>(columns
)) > maxRows
) {
233 columns
++; // more rows needed than allowed so we add some columns instead
235 //kDebug() << "groupWidth" << columns << maxRows << m_maxRows;
240 rows
= ceil(static_cast<float>(groupSize
) / static_cast<float>(columns
)); //actually needed rows
243 return QPair
<int,int> (columns
, rows
);
246 void LayoutWidget::createLayout()
248 m_layout
= new QGraphicsGridLayout(m_groupItem
);
249 m_layout
->setContentsMargins(0,0,0,0);
250 m_layout
->setSizePolicy(QSizePolicy(QSizePolicy::Expanding
,QSizePolicy::Expanding
));
251 m_layout
->setMaximumSize(INT_MAX
,INT_MAX
);
254 void LayoutWidget::layoutItems()
258 QPair
<int,int> grid
= gridLayoutSize();
259 int columns
= grid
.first
;
260 int rows
= grid
.second
;
262 //kDebug() << "Laying out with" << columns << rows;
263 //kDebug() << "geometry" << m_groupItem->geometry();
264 int rowHeight
= qMax(1, int(m_groupItem
->geometry().height() / rows
));
265 //kDebug() << "rowHeight" << rowHeight;
266 int columnWidth
= qMax(1, int(m_groupItem
->geometry().size().width() / columns
));
267 //kDebug() << "column width set to " << columnWidth;
269 QSizeF maximumCellSize
;
270 if (!m_itemPositions
.isEmpty()) {
271 maximumCellSize
= m_itemPositions
.first()->basicPreferredSize() * 1.8;
274 createLayout(); //its a shame that we have to create a new layout every time but the QGraphicsGridLayout is just to buggy yet
276 if (m_applet
->formFactor() == Plasma::Vertical
) {
277 m_layout
->setHorizontalSpacing(0);
278 m_layout
->setVerticalSpacing(2);
280 m_layout
->setHorizontalSpacing(2);
281 m_layout
->setVerticalSpacing(0);
284 //go through all items of this layoutwidget and populate the layout with items
285 int numberOfItems
= 0;
286 foreach (AbstractTaskItem
*item
, m_itemPositions
) {
290 if (m_applet
->formFactor() == Plasma::Vertical
) {
291 row
= numberOfItems
% columns
;
292 col
= numberOfItems
/ columns
;
294 row
= numberOfItems
/ columns
;
295 col
= numberOfItems
% columns
;
299 if (m_applet
->formFactor() == Plasma::Vertical
) {
300 row
= numberOfItems
/ rows
;
301 col
= numberOfItems
% rows
;
303 row
= numberOfItems
% rows
;
304 col
= numberOfItems
/ rows
;
309 m_layout
->setColumnPreferredWidth(col
, columnWidth
);//Somehow this line is absolutely crucial
310 m_layout
->setRowPreferredHeight(row
, rowHeight
);//Somehow this line is absolutely crucial
312 if (maximumCellSize
.isValid()) {
313 if (m_applet
->formFactor() == Plasma::Vertical
) {
314 m_layout
->setRowMaximumHeight(row
, maximumCellSize
.height());
316 m_layout
->setColumnMaximumWidth(col
, maximumCellSize
.width());
320 if (item
->abstractItem() && item
->abstractItem()->isGroupItem()) {
321 TaskGroupItem
*group
= static_cast<TaskGroupItem
*>(item
);
322 if (group
->collapsed()) {
323 group
->unsplitGroup();
324 m_layout
->addItem(item
, row
, col
, 1, 1);
326 LayoutWidget
*layout
= group
->layoutWidget();
328 kDebug() << "group has no valid layout";
331 int groupRowWidth
= layout
->numberOfColumns();
333 if ((columns
-col
) < groupRowWidth
) {//we need to split the group
334 int splitIndex
= columns
- col
;//number of items in group that are on this row
335 TaskGroupItem
*splitChild
= group
->splitGroup(splitIndex
);
336 m_layout
->addItem(item
, row
, col
, 1, splitIndex
); //Add the normal item
337 //kDebug() << "add normal item: split index = column span " << splitIndex;
339 m_layout
->addItem(splitChild
, row
+ 1, 0, 1, groupRowWidth
- splitIndex
);//also add the second part of the group if there is one
341 //kDebug() << "add split item: column span " << groupRowWidth - splitIndex;
343 group
->unsplitGroup();
344 m_layout
->addItem(item
, row
, col
, 1, groupRowWidth
); //Add the normal item
345 //kDebug() << "add unsplit expanded item over columns " << groupRowWidth;
348 numberOfItems
+= groupRowWidth
- 1;
351 m_layout
->addItem(item
, row
, col
, 1, 1);
354 //kDebug() << "addItem at: " << row << col;
358 updatePreferredSize();
359 m_groupItem
->setLayout(m_layout
);
363 void LayoutWidget::updatePreferredSize()
365 //kDebug() << "column count: " << m_layout->columnCount();
367 if (m_layout
->count() > 0) {
368 AbstractTaskItem
*item
= dynamic_cast<AbstractTaskItem
*>(m_layout
->itemAt(0));
370 m_layout
->setPreferredSize(item
->basicPreferredSize().width()*m_layout
->columnCount(), item
->basicPreferredSize().height()*m_layout
->rowCount());
371 //Empty taskbar, arbitrary small value
373 kDebug() << "Empty layout!!!!!!!!!!!!!!!!!!";
374 if (m_applet
->formFactor() == Plasma::Vertical
) {
375 m_layout
->setPreferredSize(/*m_layout->preferredSize().width()*/10, 10); //since we recreate the layout we don't have the previous values
377 m_layout
->setPreferredSize(10, /*m_layout->preferredSize().height()*/10);
380 //kDebug() << "preferred size: " << m_layout->preferredSize();
381 emit
sizeHintChanged(Qt::PreferredSize
);
384 void LayoutWidget::setMaximumRows(int rows
)
389 void LayoutWidget::setForceRows(bool forceRows
)
391 m_forceRows
= forceRows
;
394 int LayoutWidget::insertionIndexAt(const QPointF
&pos
)
396 int insertIndex
= -1;
397 int row
= numberOfRows();
398 int col
= numberOfColumns();
400 //if pos is (-1,-1) insert at the end of the panel
401 if (pos
.toPoint() == QPoint(-1, -1)) {
405 QRectF siblingGeometry
;
408 for (int i
= 0; i
< numberOfRows(); i
++) {
409 if (m_applet
->formFactor() == Plasma::Vertical
) {
410 siblingGeometry
= m_layout
->itemAt(0, i
)->geometry();//set geometry of single item
411 if (pos
.x() <= siblingGeometry
.right()) {
416 siblingGeometry
= m_layout
->itemAt(i
, 0)->geometry();//set geometry of single item
417 if (pos
.y() <= siblingGeometry
.bottom()) {
424 for (int i
= 0; i
< numberOfColumns(); i
++) {
425 if (m_applet
->formFactor() == Plasma::Vertical
) {
426 siblingGeometry
= m_layout
->itemAt(i
, 0)->geometry();//set geometry of single item
427 qreal vertMiddle
= (siblingGeometry
.top() + siblingGeometry
.bottom()) / 2.0;
428 if (pos
.y() < vertMiddle
) {
434 siblingGeometry
= m_layout
->itemAt(0, i
)->geometry();//set geometry of single item
435 qreal horizMiddle
= (siblingGeometry
.left() + siblingGeometry
.right()) / 2.0;
436 //kDebug() << "pos middle " << pos.x() << horizMiddle;
437 if (pos
.x() < horizMiddle
) {
445 //kDebug() << row << col;
448 insertIndex
= row
* numberOfColumns() + col
;
450 insertIndex
= col
* numberOfRows() + row
;
453 if (insertIndex
> m_layout
->count()) {
455 //kDebug() << "correction";
458 //kDebug() << "insert Index" << insertIndex;
462 int LayoutWidget::numberOfRows()
464 if (m_applet
->formFactor() == Plasma::Vertical
) {
465 return m_layout
->columnCount();
467 return m_layout
->rowCount();
471 int LayoutWidget::numberOfColumns()
473 if (m_applet
->formFactor() == Plasma::Vertical
) {
474 return m_layout
->rowCount();
476 return m_layout
->columnCount();
481 #include "layoutwidget.moc"