File indexing completed on 2024-12-22 04:17:50

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2007 The University of Toronto                        *
0004  *                   netterfield@astro.utoronto.ca                         *
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  ***************************************************************************/
0012 
0013 #include "viewitemdialog.h"
0014 
0015 #include "viewitem.h"
0016 #include "filltab.h"
0017 #include "stroketab.h"
0018 #include "layouttab.h"
0019 #include "dimensionstab.h"
0020 #include "dialogpage.h"
0021 #include "viewgridlayout.h"
0022 #include "document.h"
0023 #include "mainwindow.h"
0024 #include "application.h"
0025 
0026 #include "dialogdefaults.h"
0027 
0028 #include "editmultiplewidget.h"
0029 
0030 #include <QPen>
0031 #include <QBrush>
0032 #include <QDebug>
0033 #include <QtGlobal>
0034 
0035 namespace Kst {
0036 
0037 ViewItemDialog::ViewItemDialog(ViewItem *item, QWidget *parent)
0038     : Dialog(parent), _mode(Single), _item(item) {
0039 
0040   setWindowTitle(tr("Edit View Item"));
0041 
0042   // semi-hack: set the width of the list widget to 15 characters, which is enough
0043   // to say "X-Axis Markers" in english.  This is better than setting it to a fixed
0044   // number of pixels, as it scales with font size or screen resolution, but
0045   // it won't necessairly survive translations, or someone adding a option like
0046   // "Do something super important", which has more than 15 characters.
0047   // We have to do it here, before the layout is set, and we don't yet know how
0048   // what is going into the listWidget.
0049   _listWidget->setMinimumWidth(_listWidget->fontMetrics().averageCharWidth()*15);
0050 
0051   QWidget *extension = extensionWidget();
0052 
0053   QVBoxLayout *extensionLayout = new QVBoxLayout(extension);
0054   extensionLayout->setContentsMargins(0, -1, 0, -1);
0055 
0056   _editMultipleWidget = new EditMultipleWidget();
0057   extensionLayout->addWidget(_editMultipleWidget);
0058 
0059   extension->setLayout(extensionLayout);
0060 
0061   _editMultipleBox = topCustomWidget();
0062 
0063   QHBoxLayout *layout = new QHBoxLayout(_editMultipleBox);
0064 
0065   _tagStringLabel = new QLabel(tr("&Name:"), _editMultipleBox);
0066   _tagStringLabel->setObjectName("_tagStringLabel");
0067   _tagString = new QLineEdit(_editMultipleBox);
0068   connect(_tagString, SIGNAL(textChanged(QString)), this, SLOT(modified()));
0069   _tagStringLabel->setBuddy(_tagString);
0070 
0071   _editMultipleButton = new QPushButton(tr("Edit Multiple >>"));
0072   _editMultipleButton->setObjectName("_editMultipleButton");
0073   connect(_editMultipleButton, SIGNAL(clicked()), this, SLOT(slotEditMultiple()));
0074 
0075   layout->addWidget(_tagStringLabel);
0076   layout->addWidget(_tagString);
0077   layout->addWidget(_editMultipleButton);
0078 
0079   _editMultipleBox->setLayout(layout);
0080 
0081   setSupportsMultipleEdit(false);
0082 
0083   if (_item->hasBrush()) {
0084     _fillTab = new FillTab(this);
0085     connect(_fillTab, SIGNAL(apply()), this, SLOT(fillChanged()));
0086   }
0087   if (_item->hasStroke()) {
0088     _strokeTab = new StrokeTab(this);
0089     connect(_strokeTab, SIGNAL(apply()), this, SLOT(strokeChanged()));
0090   }
0091   _layoutTab = new LayoutTab(this);
0092   connect(_layoutTab, SIGNAL(apply()), this, SLOT(layoutChanged()));
0093 
0094   DialogPageTab *page = new DialogPageTab(this);
0095   page->setPageTitle(tr("Appearance"));
0096   if (_item->hasBrush()) {
0097     page->addDialogTab(_fillTab);
0098   }
0099 
0100   if (_item->hasStroke()) {
0101     page->addDialogTab(_strokeTab);
0102   }
0103   page->addDialogTab(_layoutTab);
0104   addDialogPage(page);
0105 
0106   if (!_item->customDimensionsTab()) {
0107     _dimensionsTab = new DimensionsTab(_item, this);
0108     DialogPage *dimensionsPage = new DialogPage(this);
0109     dimensionsPage->setPageTitle(tr("Size/Position"));
0110     dimensionsPage->addDialogTab(_dimensionsTab);
0111     addDialogPage(dimensionsPage);
0112     connect(_dimensionsTab, SIGNAL(apply()), this, SLOT(dimensionsChanged()));
0113   } else {
0114     _dimensionsTab = 0;
0115   }
0116 
0117   QList<DialogPage*> dialogPages = _item->dialogPages();
0118   foreach (DialogPage *dialogPage, dialogPages)
0119     addDialogPage(dialogPage);
0120 
0121   setupFill();
0122   setupStroke();
0123   setupLayout();
0124   setupDimensions();
0125 
0126   selectDialogPage(page);
0127 
0128   if (!_item->customDimensionsTab()) {
0129     connect(_dimensionsTab, SIGNAL(tabModified()), this, SLOT(modified()));
0130   }
0131 
0132   connect(this, SIGNAL(editMultipleMode()), this, SLOT(setMultipleEdit()));
0133   connect(this, SIGNAL(editSingleMode()), this, SLOT(setSingleEdit()));
0134   connect(_item, SIGNAL(relativeSizeUpdated()), this, SLOT(setupDimensions()));
0135   connect(_saveAsDefault, SIGNAL(clicked()), this, SLOT(modified()));
0136 
0137   _saveAsDefault->show();
0138 }
0139 
0140 
0141 ViewItemDialog::~ViewItemDialog() {
0142   disconnect(_item, SIGNAL(relativeSizeUpdated()), this, SLOT(setupDimensions()));
0143   _item->clearEditDialogPtr();
0144 }
0145 
0146 
0147 void ViewItemDialog::setSupportsMultipleEdit(bool enabled) {
0148   _editMultipleBox->setVisible(enabled);
0149 }
0150 
0151 
0152 void ViewItemDialog::slotEditMultiple() {
0153   int currentWidth = width();
0154   int extensionWidth = extensionWidget()->width();
0155   if (extensionWidth<204) extensionWidth = 204; // FIXME: magic number hack...
0156   extensionWidget()->setVisible(!extensionWidget()->isVisible());
0157  _tagString->setEnabled(!extensionWidget()->isVisible());
0158   if (!extensionWidget()->isVisible()) {
0159     setMinimumWidth(currentWidth - extensionWidth);
0160     resize(currentWidth - extensionWidth, height());
0161     _mode = Single;
0162     emit editSingleMode();
0163   } else {
0164     setMinimumWidth(currentWidth + extensionWidth);
0165     resize(currentWidth + extensionWidth, height());
0166     _mode = Multiple;
0167     emit editMultipleMode();
0168   }
0169 }
0170 
0171 
0172 void ViewItemDialog::addMultipleEditOption(QString name, QString descriptionTip, QString shortName) {
0173   _editMultipleWidget->addObject(name, descriptionTip);
0174   _multiNameShortName.insert(name, shortName);
0175 }
0176 
0177 
0178 QList<ViewItem*> ViewItemDialog::selectedMultipleEditObjects() {
0179   QList<ViewItem*> selectedItems;
0180   QList<ViewItem*> allItiems = ViewItem::getItems<ViewItem>();
0181   foreach(const QString &name, _editMultipleWidget->selectedObjects()) {
0182     if (_multiNameShortName.contains(name)) {
0183       QString shortName = _multiNameShortName[name];
0184       foreach (ViewItem *item, allItiems) {
0185         if (item->shortName() == shortName) {
0186           selectedItems.append(item);
0187         }
0188       }
0189     //  selectedItems.append(multiItems[name]);
0190     }
0191   }
0192   return selectedItems;
0193 }
0194 
0195 
0196 void ViewItemDialog::clearMultipleEditOptions() {
0197   _editMultipleWidget->clearObjects();
0198   _multiNameShortName.clear();
0199 }
0200 
0201 
0202 void ViewItemDialog::setupFill() {
0203   Q_ASSERT(_item);
0204   if (_item->hasBrush()) {
0205     QBrush b = _item->brush();
0206     _fillTab->enableSingleEditOptions(true);
0207     _fillTab->initialize(&b);
0208   }
0209 }
0210 
0211 void ViewItemDialog::setupStroke() {
0212   Q_ASSERT(_item);
0213   if (_item->hasStroke()) {
0214     QPen p = _item->storedPen();
0215 
0216     _strokeTab->initialize(&p);
0217   }
0218 }
0219 
0220 void ViewItemDialog::setupLayout() {
0221   Q_ASSERT(_item);
0222   _layoutTab->setHorizontalMargin(_item->layoutMargins().width());
0223   _layoutTab->setVerticalMargin(_item->layoutMargins().height());
0224   _layoutTab->setHorizontalSpacing(_item->layoutSpacing().width());
0225   _layoutTab->setVerticalSpacing(_item->layoutSpacing().height());
0226 }
0227 
0228 
0229 void ViewItemDialog::setupDimensions() {
0230   if (_dimensionsTab) {
0231     _dimensionsTab->enableSingleEditOptions(true);
0232     _dimensionsTab->setupDimensions();
0233   }
0234 }
0235 
0236 
0237 void ViewItemDialog::fillChanged() {
0238   Q_ASSERT(_item);
0239 
0240   if (_item->hasBrush()) {
0241     if (_mode == Multiple) {
0242       foreach(ViewItem* item, selectedMultipleEditObjects()) {
0243         saveFill(item);
0244       }
0245     } else {
0246       saveFill(_item);
0247       if (_saveAsDefault->isChecked()) {
0248         saveDialogDefaultsBrush(_item->defaultsGroupName(), _item->brush());
0249       }
0250     }
0251     kstApp->mainWindow()->document()->setChanged(true);
0252   }
0253 }
0254 
0255 void ViewItemDialog::saveFill(ViewItem *item) {
0256   if (_item->hasBrush()) {
0257     QBrush b = _fillTab->brush(item->brush());
0258     item->setBrush(b);
0259   }
0260 }
0261 
0262 
0263 void ViewItemDialog::strokeChanged() {
0264   Q_ASSERT(_item);
0265   if (_mode == Multiple) {
0266     if (_strokeTab->strokeDirty()) {
0267       foreach(ViewItem* item, selectedMultipleEditObjects()) {
0268         saveStroke(item);
0269       }
0270     }
0271   } else {
0272     saveStroke(_item);
0273     if (_saveAsDefault->isChecked()) {
0274       saveDialogDefaultsPen(_item->defaultsGroupName(), _item->storedPen());
0275     }
0276   }
0277   kstApp->mainWindow()->document()->setChanged(true);
0278 }
0279 
0280 
0281 void ViewItemDialog::saveStroke(ViewItem *item) {
0282   if (_item->hasStroke()) {
0283     item->setItemPen(_strokeTab->pen(item->storedPen()));
0284   }
0285 }
0286 
0287 
0288 void ViewItemDialog::layoutChanged() {
0289   Q_ASSERT(_item);
0290   if (_mode == Multiple) {
0291     foreach(ViewItem* item, selectedMultipleEditObjects()) {
0292       saveLayout(item);
0293     }
0294   } else {
0295     saveLayout(_item);
0296   }
0297   kstApp->mainWindow()->document()->setChanged(true);
0298 }
0299 
0300 
0301 void ViewItemDialog::saveLayout(ViewItem *item) {
0302   Q_ASSERT(_item);
0303   qreal horizontalMargin = _layoutTab->horizontalMarginDirty() ? _layoutTab->horizontalMargin() :item->layoutMargins().width();
0304   qreal verticalMargin = _layoutTab->verticalMarginDirty() ? _layoutTab->verticalMargin() :item->layoutMargins().height();
0305   qreal horizontalSpacing = _layoutTab->horizontalSpacingDirty() ? _layoutTab->horizontalSpacing() :item->layoutSpacing().width();
0306   qreal verticalSpacing = _layoutTab->verticalSpacingDirty() ? _layoutTab->verticalSpacing() :item->layoutSpacing().height();
0307 
0308   item->setLayoutMargins(QSizeF(horizontalMargin, verticalMargin));
0309   item->setLayoutSpacing(QSizeF(horizontalSpacing, verticalSpacing));
0310 }
0311 
0312 
0313 void ViewItemDialog::dimensionsChanged() {
0314   Q_ASSERT(_item);
0315   if (_mode == Multiple) {
0316     foreach(ViewItem* item, selectedMultipleEditObjects()) {
0317       saveDimensions(item);
0318     }
0319   } else {
0320     saveDimensions(_item);
0321   }
0322   if (_saveAsDefault->isChecked()) {
0323     saveDialogDefaultsLockPosToData(_item->defaultsGroupName(), _item->lockPosToData());
0324   }
0325 
0326   kstApp->mainWindow()->document()->setChanged(true);
0327 }
0328 
0329 
0330 void ViewItemDialog::saveDimensions(ViewItem *item) {
0331   Q_ASSERT(item);
0332 
0333   if (editMode() == Multiple) { // saving dimensions not supported for edit multiple mode
0334     return;
0335   }
0336 
0337   qreal rotation = _dimensionsTab->rotationDirty() ? _dimensionsTab->rotation() :item->rotationAngle();
0338 
0339   if (_dimensionsTab->lockPosToData() && item->dataPosLockable()) {
0340     QRectF dr;
0341     dr.setWidth(_dimensionsTab->width());
0342     dr.setHeight(_dimensionsTab->height());
0343     dr.moveCenter(QPointF(_dimensionsTab->x(), _dimensionsTab->y()));
0344 
0345     item->setDataRelativeRect(dr);
0346     item->setLockPosToData(true);
0347     item->applyDataLockedDimensions();
0348 
0349   } else {
0350     QRectF parentRect = item->parentRect();
0351     qreal parentWidth = parentRect.width();
0352     qreal parentHeight = parentRect.height();
0353     qreal parentX = parentRect.x();
0354     qreal parentY = parentRect.y();
0355 
0356     qreal aspectRatio;
0357     if (item->rect().width() > 0) {
0358       aspectRatio = qreal(item->rect().height()) / qreal(item->rect().width());
0359     } else {
0360       aspectRatio = 10000.0;
0361     }
0362 
0363     qreal relativeWidth = _dimensionsTab->widthDirty() ? _dimensionsTab->width() :item->relativeWidth();
0364     qreal relativeHeight = _dimensionsTab->heightDirty() ? _dimensionsTab->height() :item->relativeHeight();
0365     bool fixedAspect = _dimensionsTab->fixedAspectDirty() ? _dimensionsTab->fixedAspect() :item->lockAspectRatio();
0366 
0367     qreal width = relativeWidth * parentWidth;
0368     qreal height;
0369     if (fixedAspect) {
0370       height = width * aspectRatio;
0371       item->setLockAspectRatio(true);
0372     } else {
0373       height = relativeHeight * parentHeight;
0374       item->setLockAspectRatio(false);
0375     }
0376 
0377     double x = _dimensionsTab->x();
0378     double y = _dimensionsTab->y();
0379 
0380     item->setLockPosToData(false);
0381     item->setPos(parentX + x*parentWidth, parentY + y*parentHeight);
0382     item->setViewRect(-width/2, -height/2, width, height);
0383   }
0384 
0385   QTransform transform;
0386   transform.rotate(rotation);
0387 
0388   item->setTransform(transform);
0389   item->updateRelativeSize(true);
0390 }
0391 
0392 
0393 void ViewItemDialog::setSingleEdit() {
0394   setupFill();
0395   setupStroke();
0396   setupLayout();
0397   setupDimensions();
0398   _mode = Single;
0399   _editMultipleButton->setText(tr("Edit Multiple >>"));
0400 }
0401 
0402 
0403 void ViewItemDialog::setMultipleEdit() {
0404   _mode = Multiple;
0405   _dimensionsTab->clearTabValues();
0406   _dimensionsTab->enableSingleEditOptions(false);
0407   _dimensionsTab->setEnabled(false); // FIXME: pretty draconian... maybe we can enable some later.
0408   if (_item->hasBrush()) {
0409     _fillTab->clearTabValues();
0410   }
0411   if (_item->hasStroke()) {
0412     _strokeTab->clearTabValues();
0413   }
0414   _layoutTab->clearTabValues();
0415   _editMultipleButton->setText(tr("<< Edit One"));
0416   setAlwaysAllowApply(true);
0417 }
0418 
0419 }
0420 
0421 // vim: ts=2 sw=2 et