annotate view/PaneStack.cpp @ 1269:f2894944c6b8

Make the overlays at either end translucent, so they don't completely crop out any underlying text or necessary info (e.g. selection extents)
author Chris Cannam
date Thu, 19 Apr 2018 14:35:59 +0100
parents a34a2a25907c
children d79e21855aef
rev   line source
Chris@127 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@127 2
Chris@127 3 /*
Chris@127 4 Sonic Visualiser
Chris@127 5 An audio file viewer and annotation editor.
Chris@127 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@127 8
Chris@127 9 This program is free software; you can redistribute it and/or
Chris@127 10 modify it under the terms of the GNU General Public License as
Chris@127 11 published by the Free Software Foundation; either version 2 of the
Chris@127 12 License, or (at your option) any later version. See the file
Chris@127 13 COPYING included with this distribution for more information.
Chris@127 14 */
Chris@127 15
Chris@127 16 #include "PaneStack.h"
Chris@127 17
Chris@128 18 #include "Pane.h"
Chris@127 19 #include "widgets/PropertyStack.h"
Chris@323 20 #include "widgets/IconLoader.h"
Chris@500 21 #include "widgets/ClickableLabel.h"
Chris@128 22 #include "layer/Layer.h"
Chris@128 23 #include "ViewManager.h"
Chris@867 24 #include "AlignmentView.h"
Chris@127 25
Chris@127 26 #include <QApplication>
Chris@127 27 #include <QHBoxLayout>
Chris@323 28 #include <QVBoxLayout>
Chris@127 29 #include <QPainter>
Chris@127 30 #include <QPalette>
Chris@127 31 #include <QLabel>
Chris@323 32 #include <QPushButton>
Chris@127 33 #include <QSplitter>
Chris@127 34 #include <QStackedWidget>
Chris@127 35
Chris@127 36 #include <iostream>
Chris@127 37
Chris@247 38 //#define DEBUG_PANE_STACK 1
Chris@247 39
Chris@127 40 PaneStack::PaneStack(QWidget *parent, ViewManager *viewManager) :
Chris@127 41 QFrame(parent),
Chris@127 42 m_currentPane(0),
Chris@712 43 m_showAccessories(true),
Chris@867 44 m_showAlignmentViews(false),
Chris@127 45 m_splitter(new QSplitter),
Chris@127 46 m_propertyStackStack(new QStackedWidget),
Chris@127 47 m_viewManager(viewManager),
Chris@615 48 m_propertyStackMinWidth(100),
Chris@127 49 m_layoutStyle(PropertyStackPerPaneLayout)
Chris@127 50 {
Chris@127 51 QHBoxLayout *layout = new QHBoxLayout;
Chris@127 52 layout->setMargin(0);
Chris@127 53 layout->setSpacing(0);
Chris@127 54
Chris@127 55 m_splitter->setOrientation(Qt::Vertical);
Chris@127 56 m_splitter->setOpaqueResize(false);
Chris@127 57
Chris@127 58 layout->addWidget(m_splitter);
Chris@127 59 layout->setStretchFactor(m_splitter, 1);
Chris@127 60 layout->addWidget(m_propertyStackStack);
Chris@127 61 m_propertyStackStack->hide();
Chris@127 62
Chris@127 63 setLayout(layout);
Chris@127 64 }
Chris@127 65
Chris@712 66 void
Chris@712 67 PaneStack::setShowPaneAccessories(bool show)
Chris@712 68 {
Chris@712 69 m_showAccessories = show;
Chris@712 70 }
Chris@712 71
Chris@867 72 void
Chris@867 73 PaneStack::setShowAlignmentViews(bool show)
Chris@867 74 {
Chris@867 75 m_showAlignmentViews = show;
Chris@867 76 foreach (const PaneRec &r, m_panes) {
Chris@867 77 r.alignmentView->setVisible(m_showAlignmentViews);
Chris@867 78 }
Chris@867 79 }
Chris@867 80
Chris@127 81 Pane *
Chris@127 82 PaneStack::addPane(bool suppressPropertyBox)
Chris@127 83 {
Chris@539 84 return insertPane(getPaneCount(), suppressPropertyBox);
Chris@539 85 }
Chris@539 86
Chris@539 87 Pane *
Chris@539 88 PaneStack::insertPane(int index, bool suppressPropertyBox)
Chris@539 89 {
Chris@127 90 QFrame *frame = new QFrame;
Chris@495 91
Chris@495 92 QGridLayout *layout = new QGridLayout;
Chris@127 93 layout->setMargin(0);
Chris@127 94 layout->setSpacing(2);
Chris@127 95
Chris@323 96 QPushButton *xButton = new QPushButton(frame);
Chris@323 97 xButton->setIcon(IconLoader().load("cross"));
Chris@323 98 xButton->setFixedSize(QSize(16, 16));
Chris@497 99 xButton->setFlat(true);
Chris@712 100 xButton->setVisible(m_showAccessories);
Chris@495 101 layout->addWidget(xButton, 0, 0);
Chris@323 102 connect(xButton, SIGNAL(clicked()), this, SLOT(paneDeleteButtonClicked()));
Chris@323 103
Chris@500 104 ClickableLabel *currentIndicator = new ClickableLabel(frame);
Chris@500 105 connect(currentIndicator, SIGNAL(clicked()), this, SLOT(indicatorClicked()));
Chris@495 106 layout->addWidget(currentIndicator, 1, 0);
Chris@495 107 layout->setRowStretch(1, 20);
Chris@497 108 currentIndicator->setMinimumWidth(8);
Chris@127 109 currentIndicator->setScaledContents(true);
Chris@712 110 currentIndicator->setVisible(m_showAccessories);
Chris@127 111
Chris@908 112 sv_frame_t initialCentreFrame = -1;
Chris@855 113 if (!m_panes.empty()) {
Chris@855 114 initialCentreFrame = m_panes[0].pane->getCentreFrame();
Chris@516 115 }
Chris@516 116
Chris@127 117 Pane *pane = new Pane(frame);
Chris@516 118 if (initialCentreFrame >= 0) {
Chris@516 119 pane->setViewManager(m_viewManager, initialCentreFrame);
Chris@516 120 } else {
Chris@516 121 pane->setViewManager(m_viewManager);
Chris@516 122 }
Chris@495 123 layout->addWidget(pane, 0, 1, 2, 1);
Chris@495 124 layout->setColumnStretch(1, 20);
Chris@127 125
Chris@867 126 AlignmentView *av = new AlignmentView(frame);
Chris@867 127 av->setFixedHeight(40);//!!!
Chris@867 128 av->setVisible(m_showAlignmentViews);
Chris@867 129 av->setViewManager(m_viewManager);
Chris@867 130 layout->addWidget(av, 2, 1);
Chris@867 131
Chris@127 132 QWidget *properties = 0;
Chris@127 133 if (suppressPropertyBox) {
Chris@1266 134 properties = new QFrame();
Chris@127 135 } else {
Chris@1266 136 properties = new PropertyStack(frame, pane);
Chris@1266 137 connect(properties, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
Chris@1266 138 this, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
Chris@190 139 connect(properties, SIGNAL(viewSelected(View *)),
Chris@190 140 this, SLOT(viewSelected(View *)));
Chris@189 141 connect(properties, SIGNAL(contextHelpChanged(const QString &)),
Chris@189 142 this, SIGNAL(contextHelpChanged(const QString &)));
Chris@127 143 }
Chris@127 144 if (m_layoutStyle == PropertyStackPerPaneLayout) {
Chris@495 145 layout->addWidget(properties, 0, 2, 2, 1);
Chris@127 146 } else {
Chris@127 147 properties->setParent(m_propertyStackStack);
Chris@127 148 m_propertyStackStack->addWidget(properties);
Chris@127 149 }
Chris@606 150 layout->setColumnStretch(2, 0);
Chris@127 151
Chris@127 152 PaneRec rec;
Chris@127 153 rec.pane = pane;
Chris@127 154 rec.propertyStack = properties;
Chris@605 155 rec.xButton = xButton;
Chris@127 156 rec.currentIndicator = currentIndicator;
Chris@127 157 rec.frame = frame;
Chris@127 158 rec.layout = layout;
Chris@867 159 rec.alignmentView = av;
Chris@127 160 m_panes.push_back(rec);
Chris@127 161
Chris@127 162 frame->setLayout(layout);
Chris@539 163 m_splitter->insertWidget(index, frame);
Chris@127 164
Chris@127 165 connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
Chris@1266 166 this, SLOT(propertyContainerAdded(PropertyContainer *)));
Chris@127 167 connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
Chris@1266 168 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
Chris@127 169 connect(pane, SIGNAL(paneInteractedWith()),
Chris@1266 170 this, SLOT(paneInteractedWith()));
Chris@127 171 connect(pane, SIGNAL(rightButtonMenuRequested(QPoint)),
Chris@127 172 this, SLOT(rightButtonMenuRequested(QPoint)));
Chris@312 173 connect(pane, SIGNAL(dropAccepted(QStringList)),
Chris@312 174 this, SLOT(paneDropAccepted(QStringList)));
Chris@312 175 connect(pane, SIGNAL(dropAccepted(QString)),
Chris@312 176 this, SLOT(paneDropAccepted(QString)));
Chris@908 177 connect(pane, SIGNAL(doubleClickSelectInvoked(sv_frame_t)),
Chris@908 178 this, SIGNAL(doubleClickSelectInvoked(sv_frame_t)));
Chris@127 179
Chris@271 180 emit paneAdded(pane);
Chris@271 181 emit paneAdded();
Chris@271 182
Chris@127 183 if (!m_currentPane) {
Chris@1266 184 setCurrentPane(pane);
Chris@127 185 }
Chris@127 186
Chris@605 187 showOrHidePaneAccessories();
Chris@867 188 relinkAlignmentViews();
Chris@605 189
Chris@127 190 return pane;
Chris@127 191 }
Chris@127 192
Chris@127 193 void
Chris@867 194 PaneStack::relinkAlignmentViews()
Chris@867 195 {
Chris@867 196 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@867 197 m_panes[i].alignmentView->setViewAbove(m_panes[i].pane);
Chris@867 198 if (i + 1 < (int)m_panes.size()) {
Chris@867 199 m_panes[i].alignmentView->setViewBelow(m_panes[i+1].pane);
Chris@867 200 } else {
Chris@867 201 m_panes[i].alignmentView->setViewBelow(0);
Chris@867 202 }
Chris@867 203 }
Chris@867 204 }
Chris@867 205
Chris@867 206 void
Chris@867 207 PaneStack::unlinkAlignmentViews()
Chris@867 208 {
Chris@867 209 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@867 210 m_panes[i].alignmentView->setViewAbove(0);
Chris@867 211 m_panes[i].alignmentView->setViewBelow(0);
Chris@867 212 }
Chris@867 213 }
Chris@867 214
Chris@867 215 void
Chris@235 216 PaneStack::setPropertyStackMinWidth(int mw)
Chris@235 217 {
Chris@235 218 for (std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@235 219 i != m_panes.end(); ++i) {
Chris@235 220 i->propertyStack->setMinimumWidth(mw);
Chris@235 221 }
Chris@235 222 m_propertyStackMinWidth = mw;
Chris@235 223 }
Chris@235 224
Chris@235 225 void
Chris@127 226 PaneStack::setLayoutStyle(LayoutStyle style)
Chris@127 227 {
Chris@127 228 if (style == m_layoutStyle) return;
Chris@127 229 m_layoutStyle = style;
Chris@127 230
Chris@127 231 std::vector<PaneRec>::iterator i;
Chris@127 232
Chris@127 233 switch (style) {
Chris@127 234
Chris@179 235 case NoPropertyStacks:
Chris@127 236 case SinglePropertyStackLayout:
Chris@127 237
Chris@127 238 for (i = m_panes.begin(); i != m_panes.end(); ++i) {
Chris@127 239 i->layout->removeWidget(i->propertyStack);
Chris@127 240 i->propertyStack->setParent(m_propertyStackStack);
Chris@127 241 m_propertyStackStack->addWidget(i->propertyStack);
Chris@127 242 }
Chris@179 243 m_propertyStackStack->setVisible(style != NoPropertyStacks);
Chris@127 244 break;
Chris@127 245
Chris@127 246 case PropertyStackPerPaneLayout:
Chris@127 247
Chris@127 248 for (i = m_panes.begin(); i != m_panes.end(); ++i) {
Chris@127 249 m_propertyStackStack->removeWidget(i->propertyStack);
Chris@127 250 i->propertyStack->setParent(i->frame);
Chris@495 251 i->layout->addWidget(i->propertyStack, 0, 2, 2, 1);
Chris@127 252 i->propertyStack->show();
Chris@127 253 }
Chris@127 254 m_propertyStackStack->hide();
Chris@127 255 break;
Chris@127 256 }
Chris@127 257 }
Chris@127 258
Chris@127 259 Pane *
Chris@127 260 PaneStack::getPane(int n)
Chris@127 261 {
Chris@806 262 if (n < (int)m_panes.size()) {
Chris@277 263 return m_panes[n].pane;
Chris@277 264 } else {
Chris@277 265 return 0;
Chris@277 266 }
Chris@277 267 }
Chris@277 268
Chris@277 269 int
Chris@277 270 PaneStack::getPaneIndex(Pane *pane)
Chris@277 271 {
Chris@277 272 for (int i = 0; i < getPaneCount(); ++i) {
Chris@277 273 if (pane == getPane(i)) {
Chris@277 274 return i;
Chris@277 275 }
Chris@277 276 }
Chris@277 277 return -1;
Chris@127 278 }
Chris@127 279
Chris@127 280 Pane *
Chris@127 281 PaneStack::getHiddenPane(int n)
Chris@127 282 {
Chris@127 283 return m_hiddenPanes[n].pane;
Chris@127 284 }
Chris@127 285
Chris@127 286 void
Chris@127 287 PaneStack::deletePane(Pane *pane)
Chris@127 288 {
Chris@729 289 cerr << "PaneStack::deletePane(" << pane << ")" << endl;
Chris@729 290
Chris@127 291 std::vector<PaneRec>::iterator i;
Chris@127 292 bool found = false;
Chris@127 293
Chris@729 294 QWidget *stack = 0;
Chris@729 295
Chris@127 296 for (i = m_panes.begin(); i != m_panes.end(); ++i) {
Chris@1266 297 if (i->pane == pane) {
Chris@729 298 stack = i->propertyStack;
Chris@1266 299 m_panes.erase(i);
Chris@1266 300 found = true;
Chris@1266 301 break;
Chris@1266 302 }
Chris@127 303 }
Chris@127 304
Chris@127 305 if (!found) {
Chris@127 306
Chris@1266 307 for (i = m_hiddenPanes.begin(); i != m_hiddenPanes.end(); ++i) {
Chris@1266 308 if (i->pane == pane) {
Chris@729 309 stack = i->propertyStack;
Chris@1266 310 m_hiddenPanes.erase(i);
Chris@1266 311 found = true;
Chris@1266 312 break;
Chris@1266 313 }
Chris@1266 314 }
Chris@127 315
Chris@1266 316 if (!found) {
Chris@1266 317 cerr << "WARNING: PaneStack::deletePane(" << pane << "): Pane not found in visible or hidden panes, not deleting" << endl;
Chris@1266 318 return;
Chris@1266 319 }
Chris@127 320 }
Chris@127 321
Chris@271 322 emit paneAboutToBeDeleted(pane);
Chris@867 323 unlinkAlignmentViews();
Chris@271 324
Chris@729 325 cerr << "PaneStack::deletePane: about to delete parent " << pane->parent() << " of pane " << pane << endl;
Chris@729 326
Chris@729 327 // The property stack associated with the parent was initially
Chris@729 328 // created with the same parent as it, so it would be deleted when
Chris@729 329 // we delete the pane's parent in a moment -- but it may have been
Chris@729 330 // reparented depending on the layout. We'd better delete it
Chris@729 331 // separately first. (This fixes a crash on opening a new layer
Chris@729 332 // with a new unit type in it, when a long-defunct property box
Chris@729 333 // could be signalled from the unit database to tell it that a new
Chris@729 334 // unit had appeared.)
Chris@729 335 delete stack;
Chris@729 336
Chris@127 337 delete pane->parent();
Chris@127 338
Chris@127 339 if (m_currentPane == pane) {
Chris@1266 340 if (m_panes.size() > 0) {
Chris@127 341 setCurrentPane(m_panes[0].pane);
Chris@1266 342 } else {
Chris@1266 343 setCurrentPane(0);
Chris@1266 344 }
Chris@127 345 }
Chris@271 346
Chris@605 347 showOrHidePaneAccessories();
Chris@867 348 relinkAlignmentViews();
Chris@605 349
Chris@271 350 emit paneDeleted();
Chris@127 351 }
Chris@127 352
Chris@605 353 void
Chris@605 354 PaneStack::showOrHidePaneAccessories()
Chris@605 355 {
Chris@682 356 cerr << "PaneStack::showOrHidePaneAccessories: count == " << getPaneCount() << endl;
Chris@605 357
Chris@605 358 bool multi = (getPaneCount() > 1);
Chris@605 359 for (std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@605 360 i != m_panes.end(); ++i) {
Chris@712 361 i->xButton->setVisible(multi && m_showAccessories);
Chris@712 362 i->currentIndicator->setVisible(multi && m_showAccessories);
Chris@605 363 }
Chris@605 364 }
Chris@605 365
Chris@127 366 int
Chris@127 367 PaneStack::getPaneCount() const
Chris@127 368 {
Chris@908 369 return int(m_panes.size());
Chris@127 370 }
Chris@127 371
Chris@127 372 int
Chris@127 373 PaneStack::getHiddenPaneCount() const
Chris@127 374 {
Chris@908 375 return int(m_hiddenPanes.size());
Chris@127 376 }
Chris@127 377
Chris@127 378 void
Chris@127 379 PaneStack::hidePane(Pane *pane)
Chris@127 380 {
Chris@127 381 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 382
Chris@127 383 while (i != m_panes.end()) {
Chris@1266 384 if (i->pane == pane) {
Chris@127 385
Chris@1266 386 m_hiddenPanes.push_back(*i);
Chris@1266 387 m_panes.erase(i);
Chris@127 388
Chris@1266 389 QWidget *pw = dynamic_cast<QWidget *>(pane->parent());
Chris@1266 390 if (pw) pw->hide();
Chris@127 391
Chris@1266 392 if (m_currentPane == pane) {
Chris@1266 393 if (m_panes.size() > 0) {
Chris@1266 394 setCurrentPane(m_panes[0].pane);
Chris@1266 395 } else {
Chris@1266 396 setCurrentPane(0);
Chris@1266 397 }
Chris@1266 398 }
Chris@1266 399
Chris@605 400 showOrHidePaneAccessories();
Chris@605 401 emit paneHidden(pane);
Chris@605 402 emit paneHidden();
Chris@1266 403 return;
Chris@1266 404 }
Chris@1266 405 ++i;
Chris@127 406 }
Chris@127 407
Chris@867 408 relinkAlignmentViews();
Chris@867 409
Chris@682 410 cerr << "WARNING: PaneStack::hidePane(" << pane << "): Pane not found in visible panes" << endl;
Chris@127 411 }
Chris@127 412
Chris@127 413 void
Chris@127 414 PaneStack::showPane(Pane *pane)
Chris@127 415 {
Chris@127 416 std::vector<PaneRec>::iterator i = m_hiddenPanes.begin();
Chris@127 417
Chris@127 418 while (i != m_hiddenPanes.end()) {
Chris@1266 419 if (i->pane == pane) {
Chris@1266 420 m_panes.push_back(*i);
Chris@1266 421 m_hiddenPanes.erase(i);
Chris@1266 422 QWidget *pw = dynamic_cast<QWidget *>(pane->parent());
Chris@1266 423 if (pw) pw->show();
Chris@127 424
Chris@1266 425 //!!! update current pane
Chris@127 426
Chris@605 427 showOrHidePaneAccessories();
Chris@605 428
Chris@1266 429 return;
Chris@1266 430 }
Chris@1266 431 ++i;
Chris@127 432 }
Chris@127 433
Chris@867 434 relinkAlignmentViews();
Chris@867 435
Chris@682 436 cerr << "WARNING: PaneStack::showPane(" << pane << "): Pane not found in hidden panes" << endl;
Chris@127 437 }
Chris@127 438
Chris@127 439 void
Chris@127 440 PaneStack::setCurrentPane(Pane *pane) // may be null
Chris@127 441 {
Chris@127 442 if (m_currentPane == pane) return;
Chris@127 443
Chris@127 444 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 445
Chris@127 446 // We used to do this by setting the foreground and background
Chris@127 447 // role, but it seems the background role is ignored and the
Chris@127 448 // background drawn transparent in Qt 4.1 -- I can't quite see why
Chris@127 449
Chris@127 450 QPixmap selectedMap(1, 1);
Chris@127 451 selectedMap.fill(QApplication::palette().color(QPalette::Foreground));
Chris@127 452
Chris@127 453 QPixmap unselectedMap(1, 1);
Chris@127 454 unselectedMap.fill(QApplication::palette().color(QPalette::Background));
Chris@127 455
Chris@127 456 bool found = false;
Chris@127 457
Chris@127 458 while (i != m_panes.end()) {
Chris@1266 459 if (i->pane == pane) {
Chris@1266 460 i->currentIndicator->setPixmap(selectedMap);
Chris@179 461 if (m_layoutStyle != PropertyStackPerPaneLayout) {
Chris@127 462 m_propertyStackStack->setCurrentWidget(i->propertyStack);
Chris@127 463 }
Chris@1266 464 found = true;
Chris@1266 465 } else {
Chris@1266 466 i->currentIndicator->setPixmap(unselectedMap);
Chris@1266 467 }
Chris@1266 468 ++i;
Chris@127 469 }
Chris@127 470
Chris@127 471 if (found || pane == 0) {
Chris@1266 472 m_currentPane = pane;
Chris@1266 473 emit currentPaneChanged(m_currentPane);
Chris@127 474 } else {
Chris@1266 475 cerr << "WARNING: PaneStack::setCurrentPane(" << pane << "): pane is not a visible pane in this stack" << endl;
Chris@127 476 }
Chris@127 477 }
Chris@127 478
Chris@127 479 void
Chris@127 480 PaneStack::setCurrentLayer(Pane *pane, Layer *layer) // may be null
Chris@127 481 {
Chris@127 482 setCurrentPane(pane);
Chris@127 483
Chris@127 484 if (m_currentPane) {
Chris@127 485
Chris@1266 486 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 487
Chris@1266 488 while (i != m_panes.end()) {
Chris@127 489
Chris@1266 490 if (i->pane == pane) {
Chris@1266 491 PropertyStack *stack = dynamic_cast<PropertyStack *>
Chris@1266 492 (i->propertyStack);
Chris@1266 493 if (stack) {
Chris@1266 494 if (stack->containsContainer(layer)) {
Chris@1266 495 stack->setCurrentIndex(stack->getContainerIndex(layer));
Chris@1266 496 emit currentLayerChanged(pane, layer);
Chris@1266 497 } else {
Chris@1266 498 stack->setCurrentIndex
Chris@1266 499 (stack->getContainerIndex
Chris@1266 500 (pane->getPropertyContainer(0)));
Chris@1266 501 emit currentLayerChanged(pane, 0);
Chris@1266 502 }
Chris@1266 503 }
Chris@1266 504 break;
Chris@1266 505 }
Chris@1266 506 ++i;
Chris@1266 507 }
Chris@127 508 }
Chris@127 509 }
Chris@127 510
Chris@127 511 Pane *
Chris@127 512 PaneStack::getCurrentPane()
Chris@127 513 {
Chris@127 514 return m_currentPane;
Chris@127 515 }
Chris@127 516
Chris@127 517 void
Chris@127 518 PaneStack::propertyContainerAdded(PropertyContainer *)
Chris@127 519 {
Chris@127 520 sizePropertyStacks();
Chris@127 521 }
Chris@127 522
Chris@127 523 void
Chris@127 524 PaneStack::propertyContainerRemoved(PropertyContainer *)
Chris@127 525 {
Chris@127 526 sizePropertyStacks();
Chris@127 527 }
Chris@127 528
Chris@127 529 void
Chris@127 530 PaneStack::propertyContainerSelected(View *client, PropertyContainer *pc)
Chris@127 531 {
Chris@127 532 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 533
Chris@127 534 while (i != m_panes.end()) {
Chris@1266 535 PropertyStack *stack = dynamic_cast<PropertyStack *>(i->propertyStack);
Chris@1266 536 if (stack &&
Chris@1266 537 stack->getClient() == client &&
Chris@1266 538 stack->containsContainer(pc)) {
Chris@1266 539 setCurrentPane(i->pane);
Chris@1266 540 break;
Chris@1266 541 }
Chris@1266 542 ++i;
Chris@127 543 }
Chris@127 544
Chris@127 545 Layer *layer = dynamic_cast<Layer *>(pc);
Chris@127 546 if (layer) emit currentLayerChanged(m_currentPane, layer);
Chris@127 547 else emit currentLayerChanged(m_currentPane, 0);
Chris@127 548 }
Chris@127 549
Chris@127 550 void
Chris@190 551 PaneStack::viewSelected(View *v)
Chris@190 552 {
Chris@190 553 Pane *p = dynamic_cast<Pane *>(v);
Chris@190 554 if (p) setCurrentPane(p);
Chris@190 555 }
Chris@190 556
Chris@190 557 void
Chris@127 558 PaneStack::paneInteractedWith()
Chris@127 559 {
Chris@127 560 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@127 561 if (!pane) return;
Chris@127 562 setCurrentPane(pane);
Chris@127 563 }
Chris@127 564
Chris@127 565 void
Chris@127 566 PaneStack::rightButtonMenuRequested(QPoint position)
Chris@127 567 {
Chris@127 568 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@127 569 if (!pane) return;
Chris@127 570 emit rightButtonMenuRequested(pane, position);
Chris@127 571 }
Chris@127 572
Chris@127 573 void
Chris@127 574 PaneStack::sizePropertyStacks()
Chris@127 575 {
Chris@127 576 int maxMinWidth = 0;
Chris@127 577
Chris@235 578 if (m_propertyStackMinWidth > 0) maxMinWidth = m_propertyStackMinWidth;
Chris@235 579
Chris@806 580 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 581 if (!m_panes[i].propertyStack) continue;
Chris@247 582 #ifdef DEBUG_PANE_STACK
Chris@1266 583 SVDEBUG << "PaneStack::sizePropertyStacks: " << i << ": min "
Chris@1266 584 << m_panes[i].propertyStack->minimumSizeHint().width() << ", hint "
Chris@243 585 << m_panes[i].propertyStack->sizeHint().width() << ", current "
Chris@1266 586 << m_panes[i].propertyStack->width() << endl;
Chris@247 587 #endif
Chris@127 588
Chris@1266 589 if (m_panes[i].propertyStack->sizeHint().width() > maxMinWidth) {
Chris@1266 590 maxMinWidth = m_panes[i].propertyStack->sizeHint().width();
Chris@1266 591 }
Chris@127 592 }
Chris@127 593
Chris@247 594 #ifdef DEBUG_PANE_STACK
Chris@587 595 SVDEBUG << "PaneStack::sizePropertyStacks: max min width " << maxMinWidth << endl;
Chris@247 596 #endif
Chris@127 597
Chris@127 598 int setWidth = maxMinWidth;
Chris@127 599
Chris@127 600 m_propertyStackStack->setMaximumWidth(setWidth + 10);
Chris@127 601
Chris@806 602 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 603 if (!m_panes[i].propertyStack) continue;
Chris@1266 604 m_panes[i].propertyStack->setMinimumWidth(setWidth);
Chris@127 605 }
Chris@180 606
Chris@363 607 emit propertyStacksResized(setWidth);
Chris@180 608 emit propertyStacksResized();
Chris@127 609 }
Chris@127 610
Chris@312 611 void
Chris@312 612 PaneStack::paneDropAccepted(QStringList uriList)
Chris@312 613 {
Chris@312 614 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@312 615 emit dropAccepted(pane, uriList);
Chris@312 616 }
Chris@312 617
Chris@312 618 void
Chris@312 619 PaneStack::paneDropAccepted(QString text)
Chris@312 620 {
Chris@312 621 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@312 622 emit dropAccepted(pane, text);
Chris@312 623 }
Chris@127 624
Chris@320 625 void
Chris@323 626 PaneStack::paneDeleteButtonClicked()
Chris@323 627 {
Chris@323 628 QObject *s = sender();
Chris@806 629 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 630 if (m_panes[i].xButton == s) {
Chris@605 631 emit paneDeleteButtonClicked(m_panes[i].pane);
Chris@323 632 }
Chris@323 633 }
Chris@323 634 }
Chris@323 635
Chris@323 636 void
Chris@500 637 PaneStack::indicatorClicked()
Chris@500 638 {
Chris@500 639 QObject *s = sender();
Chris@500 640
Chris@806 641 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 642 if (m_panes[i].currentIndicator == s) {
Chris@500 643 setCurrentPane(m_panes[i].pane);
Chris@500 644 return;
Chris@500 645 }
Chris@500 646 }
Chris@500 647 }
Chris@500 648
Chris@500 649 void
Chris@320 650 PaneStack::sizePanesEqually()
Chris@320 651 {
Chris@320 652 QList<int> sizes = m_splitter->sizes();
Chris@320 653 if (sizes.empty()) return;
Chris@320 654
Chris@320 655 int count = sizes.size();
Chris@320 656
Chris@687 657 int fixed = 0, variable = 0, total = 0;
Chris@687 658 int varicount = 0;
Chris@687 659
Chris@320 660 for (int i = 0; i < count; ++i) {
Chris@320 661 total += sizes[i];
Chris@320 662 }
Chris@320 663
Chris@687 664 variable = total;
Chris@687 665
Chris@687 666 for (int i = 0; i < count; ++i) {
Chris@687 667 int minh = m_panes[i].pane->minimumSize().height();
Chris@687 668 if (minh == m_panes[i].pane->maximumSize().height()) {
Chris@687 669 fixed += minh;
Chris@687 670 variable -= minh;
Chris@687 671 } else {
Chris@687 672 varicount++;
Chris@687 673 }
Chris@687 674 }
Chris@687 675
Chris@320 676 if (total == 0) return;
Chris@320 677
Chris@320 678 sizes.clear();
Chris@320 679
Chris@687 680 int each = (varicount > 0 ? (variable / varicount) : 0);
Chris@320 681 int remaining = total;
Chris@320 682
Chris@320 683 for (int i = 0; i < count; ++i) {
Chris@320 684 if (i == count - 1) {
Chris@320 685 sizes.push_back(remaining);
Chris@320 686 } else {
Chris@687 687 int minh = m_panes[i].pane->minimumSize().height();
Chris@687 688 if (minh == m_panes[i].pane->maximumSize().height()) {
Chris@687 689 sizes.push_back(minh);
Chris@687 690 remaining -= minh;
Chris@687 691 } else {
Chris@687 692 sizes.push_back(each);
Chris@687 693 remaining -= each;
Chris@687 694 }
Chris@320 695 }
Chris@320 696 }
Chris@320 697
Chris@320 698 /*
Chris@682 699 cerr << "sizes: ";
Chris@320 700 for (int i = 0; i < sizes.size(); ++i) {
Chris@682 701 cerr << sizes[i] << " ";
Chris@320 702 }
Chris@682 703 cerr << endl;
Chris@320 704 */
Chris@320 705
Chris@320 706 m_splitter->setSizes(sizes);
Chris@320 707 }
Chris@320 708