annotate view/PaneStack.cpp @ 1431:af824022bffd single-point

Begin fixing the various snap operations. Also remove SnapNearest, which is never used and seems to consume more lines of code than the rest!
author Chris Cannam
date Wed, 20 Mar 2019 14:59:34 +0000
parents c8a6fd3f9dff
children 8e6a24110996
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@1408 42 m_currentPane(nullptr),
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@1408 132 QWidget *properties = nullptr;
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@1408 201 m_panes[i].alignmentView->setViewBelow(nullptr);
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@1408 210 m_panes[i].alignmentView->setViewAbove(nullptr);
Chris@1408 211 m_panes[i].alignmentView->setViewBelow(nullptr);
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@1408 265 return nullptr;
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@1362 289 #ifdef DEBUG_PANE_STACK
Chris@1362 290 SVCERR << "PaneStack::deletePane(" << pane << ")" << endl;
Chris@1362 291 #endif
Chris@729 292
Chris@127 293 std::vector<PaneRec>::iterator i;
Chris@127 294 bool found = false;
Chris@127 295
Chris@1408 296 QWidget *stack = nullptr;
Chris@729 297
Chris@127 298 for (i = m_panes.begin(); i != m_panes.end(); ++i) {
Chris@1266 299 if (i->pane == pane) {
Chris@729 300 stack = i->propertyStack;
Chris@1266 301 m_panes.erase(i);
Chris@1266 302 found = true;
Chris@1266 303 break;
Chris@1266 304 }
Chris@127 305 }
Chris@127 306
Chris@127 307 if (!found) {
Chris@127 308
Chris@1266 309 for (i = m_hiddenPanes.begin(); i != m_hiddenPanes.end(); ++i) {
Chris@1266 310 if (i->pane == pane) {
Chris@729 311 stack = i->propertyStack;
Chris@1266 312 m_hiddenPanes.erase(i);
Chris@1266 313 found = true;
Chris@1266 314 break;
Chris@1266 315 }
Chris@1266 316 }
Chris@127 317
Chris@1266 318 if (!found) {
Chris@1266 319 cerr << "WARNING: PaneStack::deletePane(" << pane << "): Pane not found in visible or hidden panes, not deleting" << endl;
Chris@1266 320 return;
Chris@1266 321 }
Chris@127 322 }
Chris@127 323
Chris@271 324 emit paneAboutToBeDeleted(pane);
Chris@867 325 unlinkAlignmentViews();
Chris@271 326
Chris@1362 327 #ifdef DEBUG_PANE_STACK
Chris@1362 328 SVCERR << "PaneStack::deletePane: about to delete parent " << pane->parent() << " of pane " << pane << endl;
Chris@1362 329 #endif
Chris@729 330
Chris@729 331 // The property stack associated with the parent was initially
Chris@729 332 // created with the same parent as it, so it would be deleted when
Chris@729 333 // we delete the pane's parent in a moment -- but it may have been
Chris@729 334 // reparented depending on the layout. We'd better delete it
Chris@729 335 // separately first. (This fixes a crash on opening a new layer
Chris@729 336 // with a new unit type in it, when a long-defunct property box
Chris@729 337 // could be signalled from the unit database to tell it that a new
Chris@729 338 // unit had appeared.)
Chris@729 339 delete stack;
Chris@729 340
Chris@127 341 delete pane->parent();
Chris@127 342
Chris@127 343 if (m_currentPane == pane) {
Chris@1266 344 if (m_panes.size() > 0) {
Chris@127 345 setCurrentPane(m_panes[0].pane);
Chris@1266 346 } else {
Chris@1408 347 setCurrentPane(nullptr);
Chris@1266 348 }
Chris@127 349 }
Chris@271 350
Chris@605 351 showOrHidePaneAccessories();
Chris@867 352 relinkAlignmentViews();
Chris@605 353
Chris@271 354 emit paneDeleted();
Chris@127 355 }
Chris@127 356
Chris@605 357 void
Chris@605 358 PaneStack::showOrHidePaneAccessories()
Chris@605 359 {
Chris@1362 360 #ifdef DEBUG_PANE_STACK
Chris@1362 361 SVCERR << "PaneStack::showOrHidePaneAccessories: count == " << getPaneCount() << endl;
Chris@1362 362 #endif
Chris@605 363
Chris@605 364 bool multi = (getPaneCount() > 1);
Chris@605 365 for (std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@605 366 i != m_panes.end(); ++i) {
Chris@712 367 i->xButton->setVisible(multi && m_showAccessories);
Chris@712 368 i->currentIndicator->setVisible(multi && m_showAccessories);
Chris@605 369 }
Chris@605 370 }
Chris@605 371
Chris@127 372 int
Chris@127 373 PaneStack::getPaneCount() const
Chris@127 374 {
Chris@908 375 return int(m_panes.size());
Chris@127 376 }
Chris@127 377
Chris@127 378 int
Chris@127 379 PaneStack::getHiddenPaneCount() const
Chris@127 380 {
Chris@908 381 return int(m_hiddenPanes.size());
Chris@127 382 }
Chris@127 383
Chris@127 384 void
Chris@127 385 PaneStack::hidePane(Pane *pane)
Chris@127 386 {
Chris@127 387 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 388
Chris@127 389 while (i != m_panes.end()) {
Chris@1266 390 if (i->pane == pane) {
Chris@127 391
Chris@1266 392 m_hiddenPanes.push_back(*i);
Chris@1266 393 m_panes.erase(i);
Chris@127 394
Chris@1266 395 QWidget *pw = dynamic_cast<QWidget *>(pane->parent());
Chris@1266 396 if (pw) pw->hide();
Chris@127 397
Chris@1266 398 if (m_currentPane == pane) {
Chris@1266 399 if (m_panes.size() > 0) {
Chris@1266 400 setCurrentPane(m_panes[0].pane);
Chris@1266 401 } else {
Chris@1408 402 setCurrentPane(nullptr);
Chris@1266 403 }
Chris@1266 404 }
Chris@1266 405
Chris@605 406 showOrHidePaneAccessories();
Chris@605 407 emit paneHidden(pane);
Chris@605 408 emit paneHidden();
Chris@1266 409 return;
Chris@1266 410 }
Chris@1266 411 ++i;
Chris@127 412 }
Chris@127 413
Chris@867 414 relinkAlignmentViews();
Chris@867 415
Chris@1362 416 SVCERR << "WARNING: PaneStack::hidePane(" << pane << "): Pane not found in visible panes" << endl;
Chris@127 417 }
Chris@127 418
Chris@127 419 void
Chris@127 420 PaneStack::showPane(Pane *pane)
Chris@127 421 {
Chris@127 422 std::vector<PaneRec>::iterator i = m_hiddenPanes.begin();
Chris@127 423
Chris@127 424 while (i != m_hiddenPanes.end()) {
Chris@1266 425 if (i->pane == pane) {
Chris@1266 426 m_panes.push_back(*i);
Chris@1266 427 m_hiddenPanes.erase(i);
Chris@1266 428 QWidget *pw = dynamic_cast<QWidget *>(pane->parent());
Chris@1266 429 if (pw) pw->show();
Chris@127 430
Chris@1266 431 //!!! update current pane
Chris@127 432
Chris@605 433 showOrHidePaneAccessories();
Chris@605 434
Chris@1266 435 return;
Chris@1266 436 }
Chris@1266 437 ++i;
Chris@127 438 }
Chris@127 439
Chris@867 440 relinkAlignmentViews();
Chris@867 441
Chris@1362 442 SVCERR << "WARNING: PaneStack::showPane(" << pane << "): Pane not found in hidden panes" << endl;
Chris@127 443 }
Chris@127 444
Chris@127 445 void
Chris@127 446 PaneStack::setCurrentPane(Pane *pane) // may be null
Chris@127 447 {
Chris@127 448 if (m_currentPane == pane) return;
Chris@127 449
Chris@127 450 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 451
Chris@127 452 // We used to do this by setting the foreground and background
Chris@127 453 // role, but it seems the background role is ignored and the
Chris@127 454 // background drawn transparent in Qt 4.1 -- I can't quite see why
Chris@127 455
Chris@127 456 QPixmap selectedMap(1, 1);
Chris@127 457 selectedMap.fill(QApplication::palette().color(QPalette::Foreground));
Chris@127 458
Chris@127 459 QPixmap unselectedMap(1, 1);
Chris@127 460 unselectedMap.fill(QApplication::palette().color(QPalette::Background));
Chris@127 461
Chris@127 462 bool found = false;
Chris@127 463
Chris@127 464 while (i != m_panes.end()) {
Chris@1266 465 if (i->pane == pane) {
Chris@1266 466 i->currentIndicator->setPixmap(selectedMap);
Chris@179 467 if (m_layoutStyle != PropertyStackPerPaneLayout) {
Chris@127 468 m_propertyStackStack->setCurrentWidget(i->propertyStack);
Chris@127 469 }
Chris@1266 470 found = true;
Chris@1266 471 } else {
Chris@1266 472 i->currentIndicator->setPixmap(unselectedMap);
Chris@1266 473 }
Chris@1266 474 ++i;
Chris@127 475 }
Chris@127 476
Chris@1408 477 if (found || pane == nullptr) {
Chris@1266 478 m_currentPane = pane;
Chris@1266 479 emit currentPaneChanged(m_currentPane);
Chris@127 480 } else {
Chris@1362 481 SVCERR << "WARNING: PaneStack::setCurrentPane(" << pane << "): pane is not a visible pane in this stack" << endl;
Chris@127 482 }
Chris@127 483 }
Chris@127 484
Chris@127 485 void
Chris@127 486 PaneStack::setCurrentLayer(Pane *pane, Layer *layer) // may be null
Chris@127 487 {
Chris@127 488 setCurrentPane(pane);
Chris@127 489
Chris@127 490 if (m_currentPane) {
Chris@127 491
Chris@1266 492 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 493
Chris@1266 494 while (i != m_panes.end()) {
Chris@127 495
Chris@1266 496 if (i->pane == pane) {
Chris@1266 497 PropertyStack *stack = dynamic_cast<PropertyStack *>
Chris@1266 498 (i->propertyStack);
Chris@1266 499 if (stack) {
Chris@1266 500 if (stack->containsContainer(layer)) {
Chris@1266 501 stack->setCurrentIndex(stack->getContainerIndex(layer));
Chris@1266 502 emit currentLayerChanged(pane, layer);
Chris@1266 503 } else {
Chris@1266 504 stack->setCurrentIndex
Chris@1266 505 (stack->getContainerIndex
Chris@1266 506 (pane->getPropertyContainer(0)));
Chris@1408 507 emit currentLayerChanged(pane, nullptr);
Chris@1266 508 }
Chris@1266 509 }
Chris@1266 510 break;
Chris@1266 511 }
Chris@1266 512 ++i;
Chris@1266 513 }
Chris@127 514 }
Chris@127 515 }
Chris@127 516
Chris@127 517 Pane *
Chris@127 518 PaneStack::getCurrentPane()
Chris@127 519 {
Chris@127 520 return m_currentPane;
Chris@127 521 }
Chris@127 522
Chris@127 523 void
Chris@127 524 PaneStack::propertyContainerAdded(PropertyContainer *)
Chris@127 525 {
Chris@127 526 sizePropertyStacks();
Chris@127 527 }
Chris@127 528
Chris@127 529 void
Chris@127 530 PaneStack::propertyContainerRemoved(PropertyContainer *)
Chris@127 531 {
Chris@127 532 sizePropertyStacks();
Chris@127 533 }
Chris@127 534
Chris@127 535 void
Chris@127 536 PaneStack::propertyContainerSelected(View *client, PropertyContainer *pc)
Chris@127 537 {
Chris@127 538 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 539
Chris@127 540 while (i != m_panes.end()) {
Chris@1266 541 PropertyStack *stack = dynamic_cast<PropertyStack *>(i->propertyStack);
Chris@1266 542 if (stack &&
Chris@1266 543 stack->getClient() == client &&
Chris@1266 544 stack->containsContainer(pc)) {
Chris@1266 545 setCurrentPane(i->pane);
Chris@1266 546 break;
Chris@1266 547 }
Chris@1266 548 ++i;
Chris@127 549 }
Chris@127 550
Chris@127 551 Layer *layer = dynamic_cast<Layer *>(pc);
Chris@127 552 if (layer) emit currentLayerChanged(m_currentPane, layer);
Chris@1408 553 else emit currentLayerChanged(m_currentPane, nullptr);
Chris@127 554 }
Chris@127 555
Chris@127 556 void
Chris@190 557 PaneStack::viewSelected(View *v)
Chris@190 558 {
Chris@190 559 Pane *p = dynamic_cast<Pane *>(v);
Chris@190 560 if (p) setCurrentPane(p);
Chris@190 561 }
Chris@190 562
Chris@190 563 void
Chris@127 564 PaneStack::paneInteractedWith()
Chris@127 565 {
Chris@127 566 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@127 567 if (!pane) return;
Chris@127 568 setCurrentPane(pane);
Chris@127 569 }
Chris@127 570
Chris@127 571 void
Chris@127 572 PaneStack::rightButtonMenuRequested(QPoint position)
Chris@127 573 {
Chris@127 574 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@127 575 if (!pane) return;
Chris@127 576 emit rightButtonMenuRequested(pane, position);
Chris@127 577 }
Chris@127 578
Chris@127 579 void
Chris@127 580 PaneStack::sizePropertyStacks()
Chris@127 581 {
Chris@127 582 int maxMinWidth = 0;
Chris@127 583
Chris@235 584 if (m_propertyStackMinWidth > 0) maxMinWidth = m_propertyStackMinWidth;
Chris@235 585
Chris@806 586 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 587 if (!m_panes[i].propertyStack) continue;
Chris@247 588 #ifdef DEBUG_PANE_STACK
Chris@1266 589 SVDEBUG << "PaneStack::sizePropertyStacks: " << i << ": min "
Chris@1266 590 << m_panes[i].propertyStack->minimumSizeHint().width() << ", hint "
Chris@243 591 << m_panes[i].propertyStack->sizeHint().width() << ", current "
Chris@1266 592 << m_panes[i].propertyStack->width() << endl;
Chris@247 593 #endif
Chris@127 594
Chris@1266 595 if (m_panes[i].propertyStack->sizeHint().width() > maxMinWidth) {
Chris@1266 596 maxMinWidth = m_panes[i].propertyStack->sizeHint().width();
Chris@1266 597 }
Chris@127 598 }
Chris@127 599
Chris@247 600 #ifdef DEBUG_PANE_STACK
Chris@587 601 SVDEBUG << "PaneStack::sizePropertyStacks: max min width " << maxMinWidth << endl;
Chris@247 602 #endif
Chris@127 603
Chris@127 604 int setWidth = maxMinWidth;
Chris@127 605
Chris@127 606 m_propertyStackStack->setMaximumWidth(setWidth + 10);
Chris@127 607
Chris@806 608 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 609 if (!m_panes[i].propertyStack) continue;
Chris@1266 610 m_panes[i].propertyStack->setMinimumWidth(setWidth);
Chris@127 611 }
Chris@180 612
Chris@363 613 emit propertyStacksResized(setWidth);
Chris@180 614 emit propertyStacksResized();
Chris@127 615 }
Chris@127 616
Chris@312 617 void
Chris@312 618 PaneStack::paneDropAccepted(QStringList uriList)
Chris@312 619 {
Chris@312 620 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@312 621 emit dropAccepted(pane, uriList);
Chris@312 622 }
Chris@312 623
Chris@312 624 void
Chris@312 625 PaneStack::paneDropAccepted(QString text)
Chris@312 626 {
Chris@312 627 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@312 628 emit dropAccepted(pane, text);
Chris@312 629 }
Chris@127 630
Chris@320 631 void
Chris@323 632 PaneStack::paneDeleteButtonClicked()
Chris@323 633 {
Chris@323 634 QObject *s = sender();
Chris@806 635 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 636 if (m_panes[i].xButton == s) {
Chris@605 637 emit paneDeleteButtonClicked(m_panes[i].pane);
Chris@323 638 }
Chris@323 639 }
Chris@323 640 }
Chris@323 641
Chris@323 642 void
Chris@500 643 PaneStack::indicatorClicked()
Chris@500 644 {
Chris@500 645 QObject *s = sender();
Chris@500 646
Chris@806 647 for (int i = 0; i < (int)m_panes.size(); ++i) {
Chris@1266 648 if (m_panes[i].currentIndicator == s) {
Chris@500 649 setCurrentPane(m_panes[i].pane);
Chris@500 650 return;
Chris@500 651 }
Chris@500 652 }
Chris@500 653 }
Chris@500 654
Chris@500 655 void
Chris@320 656 PaneStack::sizePanesEqually()
Chris@320 657 {
Chris@320 658 QList<int> sizes = m_splitter->sizes();
Chris@320 659 if (sizes.empty()) return;
Chris@320 660
Chris@320 661 int count = sizes.size();
Chris@320 662
Chris@687 663 int fixed = 0, variable = 0, total = 0;
Chris@687 664 int varicount = 0;
Chris@687 665
Chris@320 666 for (int i = 0; i < count; ++i) {
Chris@320 667 total += sizes[i];
Chris@320 668 }
Chris@320 669
Chris@687 670 variable = total;
Chris@687 671
Chris@687 672 for (int i = 0; i < count; ++i) {
Chris@687 673 int minh = m_panes[i].pane->minimumSize().height();
Chris@687 674 if (minh == m_panes[i].pane->maximumSize().height()) {
Chris@687 675 fixed += minh;
Chris@687 676 variable -= minh;
Chris@687 677 } else {
Chris@687 678 varicount++;
Chris@687 679 }
Chris@687 680 }
Chris@687 681
Chris@320 682 if (total == 0) return;
Chris@320 683
Chris@320 684 sizes.clear();
Chris@320 685
Chris@687 686 int each = (varicount > 0 ? (variable / varicount) : 0);
Chris@320 687 int remaining = total;
Chris@320 688
Chris@320 689 for (int i = 0; i < count; ++i) {
Chris@320 690 if (i == count - 1) {
Chris@320 691 sizes.push_back(remaining);
Chris@320 692 } else {
Chris@687 693 int minh = m_panes[i].pane->minimumSize().height();
Chris@687 694 if (minh == m_panes[i].pane->maximumSize().height()) {
Chris@687 695 sizes.push_back(minh);
Chris@687 696 remaining -= minh;
Chris@687 697 } else {
Chris@687 698 sizes.push_back(each);
Chris@687 699 remaining -= each;
Chris@687 700 }
Chris@320 701 }
Chris@320 702 }
Chris@320 703
Chris@320 704 /*
Chris@682 705 cerr << "sizes: ";
Chris@320 706 for (int i = 0; i < sizes.size(); ++i) {
Chris@682 707 cerr << sizes[i] << " ";
Chris@320 708 }
Chris@682 709 cerr << endl;
Chris@320 710 */
Chris@320 711
Chris@320 712 m_splitter->setSizes(sizes);
Chris@320 713 }
Chris@320 714