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