File indexing completed on 2024-05-12 16:39:48
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> 0003 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> 0004 Copyright (C) 2004-2014 Jarosław Staniek <staniek@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "form_p.h" 0023 #include "formIO.h" 0024 0025 #include <KPropertyListData> 0026 0027 #include <KLocalizedString> 0028 0029 #include <QStyleOption> 0030 0031 using namespace KFormDesigner; 0032 0033 DesignModeStyle::DesignModeStyle(const QString &baseStyleName) 0034 : QProxyStyle(baseStyleName) 0035 { 0036 } 0037 0038 void DesignModeStyle::drawControl(ControlElement element, const QStyleOption *option, 0039 QPainter *p, const QWidget *w) const 0040 { 0041 QStyleOption *so = alterOption(element, option); 0042 QProxyStyle::drawControl(element, so ? so : option, p, w); 0043 delete so; 0044 } 0045 0046 //! Used in alterOption() 0047 template <class StyleOptionClass> 0048 static StyleOptionClass *cloneStyleOption(const QStyleOption *option) 0049 { 0050 const StyleOptionClass *o = qstyleoption_cast<const StyleOptionClass*>(option); 0051 return o ? new StyleOptionClass(*o) : new StyleOptionClass(); 0052 } 0053 0054 QStyleOption* DesignModeStyle::alterOption(ControlElement element, const QStyleOption *option) const 0055 { 0056 Q_UNUSED(element) 0057 if (!option) 0058 return 0; 0059 QStyleOption* res = 0; 0060 switch (option->type) { 0061 case QStyleOption::SO_Button: 0062 res = cloneStyleOption<QStyleOptionButton>(option); 0063 break; 0064 case QStyleOption::SO_ComboBox: 0065 res = cloneStyleOption<QStyleOptionComboBox>(option); 0066 break; 0067 case QStyleOption::SO_Complex: 0068 res = cloneStyleOption<QStyleOptionComplex>(option); 0069 break; 0070 case QStyleOption::SO_DockWidget: 0071 res = cloneStyleOption<QStyleOptionDockWidget>(option); 0072 break; 0073 case QStyleOption::SO_FocusRect: 0074 res = cloneStyleOption<QStyleOptionFocusRect>(option); 0075 break; 0076 case QStyleOption::SO_Frame: 0077 res = cloneStyleOption<QStyleOptionFrame>(option); 0078 break; 0079 case QStyleOption::SO_GraphicsItem: 0080 res = cloneStyleOption<QStyleOptionGraphicsItem>(option); 0081 break; 0082 case QStyleOption::SO_GroupBox: 0083 res = cloneStyleOption<QStyleOptionGroupBox>(option); 0084 break; 0085 case QStyleOption::SO_Header: 0086 res = cloneStyleOption<QStyleOptionHeader>(option); 0087 break; 0088 case QStyleOption::SO_MenuItem: 0089 res = cloneStyleOption<QStyleOptionMenuItem>(option); 0090 break; 0091 case QStyleOption::SO_ProgressBar: 0092 res = cloneStyleOption<QStyleOptionProgressBar>(option); 0093 break; 0094 case QStyleOption::SO_RubberBand: 0095 res = cloneStyleOption<QStyleOptionRubberBand>(option); 0096 break; 0097 case QStyleOption::SO_SizeGrip: 0098 res = cloneStyleOption<QStyleOptionSizeGrip>(option); 0099 break; 0100 case QStyleOption::SO_Slider: 0101 res = cloneStyleOption<QStyleOptionSlider>(option); 0102 break; 0103 case QStyleOption::SO_SpinBox: 0104 res = cloneStyleOption<QStyleOptionSpinBox>(option); 0105 break; 0106 case QStyleOption::SO_Tab: 0107 res = cloneStyleOption<QStyleOptionTab>(option); 0108 break; 0109 case QStyleOption::SO_TabBarBase: 0110 res = cloneStyleOption<QStyleOptionTabBarBase>(option); 0111 break; 0112 case QStyleOption::SO_TabWidgetFrame: 0113 res = cloneStyleOption<QStyleOptionTabWidgetFrame>(option); 0114 break; 0115 case QStyleOption::SO_TitleBar: 0116 res = cloneStyleOption<QStyleOptionTitleBar>(option); 0117 break; 0118 case QStyleOption::SO_ToolBar: 0119 res = cloneStyleOption<QStyleOptionToolBar>(option); 0120 break; 0121 case QStyleOption::SO_ToolBox: 0122 res = cloneStyleOption<QStyleOptionToolBox>(option); 0123 break; 0124 case QStyleOption::SO_ToolButton: 0125 res = cloneStyleOption<QStyleOptionToolButton>(option); 0126 break; 0127 case QStyleOption::SO_ViewItem: 0128 res = cloneStyleOption<QStyleOptionViewItem>(option); 0129 break; 0130 default: 0131 return 0; 0132 } 0133 0134 const QStyle::State statesToRemove( QStyle::State_MouseOver | State_HasFocus ); 0135 res->state |= statesToRemove; 0136 res->state ^= statesToRemove; 0137 return res; 0138 } 0139 0140 //-------------- 0141 0142 FormPrivate::FormPrivate(Form *form, WidgetLibrary *_library, Form::Mode _mode, 0143 KActionCollection &col, KFormDesigner::ActionGroup &group) 0144 : mode(_mode) 0145 , state(Form::WidgetSelecting) 0146 , internalCollection(static_cast<QObject *>(nullptr)) 0147 , collection(&col) 0148 , widgetActionGroup(&group) 0149 #ifdef KEXI_PIXMAP_COLLECTIONS_SUPPORT 0150 , pixcollection(nullptr) 0151 #endif 0152 , formWidget(nullptr) 0153 , formatVersion(KFormDesigner::version()) 0154 , originalFormatVersion(KFormDesigner::version()) 0155 #ifdef KFD_SIGSLOTS 0156 , mouseTrackers(nullptr) 0157 , connection(nullptr) 0158 #endif 0159 , library(_library) 0160 , q(form) 0161 { 0162 toplevel = 0; 0163 topTree = 0; 0164 widget = 0; 0165 modified = false; 0166 interactive = true; 0167 autoTabstops = true; 0168 isRedoing = false; 0169 //! @todo get the default from globals... 0170 snapToGrid = true; 0171 gridSize = 10; 0172 #ifdef KFD_SIGSLOTS 0173 connBuffer = new ConnectionBuffer(); 0174 #endif 0175 lastCommand = 0; 0176 lastCommandGroup = 0; 0177 isUndoing = false; 0178 slotPropertyChangedEnabled = true; 0179 slotPropertyChanged_addCommandEnabled = true; 0180 insideAddPropertyCommand = false; 0181 initPropertiesDescription(); 0182 designModeStyle = 0; 0183 idOfPropertyCommand = 0; 0184 selectWidgetEnabled = true; 0185 pixmapsStoredInline = false; 0186 QObject::connect(&propertySet, SIGNAL(propertyChanged(KPropertySet &, KProperty &)), q, 0187 SLOT(slotPropertyChanged(KPropertySet &, KProperty &))); 0188 QObject::connect(&propertySet, SIGNAL(propertyReset(KPropertySet &, KProperty &)), q, 0189 SLOT(slotPropertyReset(KPropertySet &, KProperty &))); 0190 } 0191 0192 FormPrivate::~FormPrivate() 0193 { 0194 delete topTree; 0195 #ifdef KFD_SIGSLOTS 0196 delete connBuffer; 0197 connBuffer = 0; 0198 #endif 0199 } 0200 0201 QString FormPrivate::propertyCaption(const QByteArray &name) 0202 { 0203 return propCaption.value(name); 0204 } 0205 0206 QString FormPrivate::valueCaption(const QByteArray &name) 0207 { 0208 return propValCaption.value(name); 0209 } 0210 0211 void FormPrivate::addPropertyCaption(const QByteArray &property, const QString &caption) 0212 { 0213 if (!propCaption.contains(property)) 0214 propCaption.insert(property, caption); 0215 } 0216 0217 void FormPrivate::addValueCaption(const QByteArray &value, const QString &caption) 0218 { 0219 if (!propValCaption.contains(value)) 0220 propValCaption.insert(value, caption); 0221 } 0222 0223 void FormPrivate::setColorProperty(KProperty& p, 0224 QPalette::ColorRole (QWidget::*roleMethod)() const, 0225 const QVariant& value) 0226 { 0227 bool nullColor = value.isNull() || !value.value<QColor>().isValid(); 0228 foreach(QWidget* widget, selected) { 0229 ObjectTreeItem *titem = q->objectTree()->lookup(widget->objectName()); 0230 QColor color; 0231 if (nullColor && roleMethod == &QWidget::backgroundRole) { 0232 color = widget->parentWidget()->palette().color((widget->*roleMethod)()); 0233 } 0234 else { 0235 color = value.value<QColor>(); 0236 } 0237 if (titem && p.isModified()) 0238 titem->addModifiedProperty(p.name(), color); 0239 QPalette widgetPalette(widget->palette()); 0240 QColor oldColor(widgetPalette.color((widget->*roleMethod)())); 0241 widgetPalette.setColor((widget->*roleMethod)(), color); 0242 widget->setPalette(widgetPalette); 0243 if (!isRedoing && !isUndoing) { 0244 q->addPropertyCommand(widget->objectName().toLatin1(), 0245 oldColor, color, p.name(), Form::DontExecuteCommand); 0246 } 0247 if (roleMethod == &QWidget::backgroundRole) { 0248 widget->setAutoFillBackground(!nullColor); 0249 if (nullColor) { // make background inherited 0250 widget->setBackgroundRole(QPalette::NoRole); 0251 } 0252 } 0253 } 0254 } 0255 0256 void FormPrivate::enableAction(const char *name, bool enable) 0257 { 0258 QAction *a = collection->action(QLatin1String(name)); 0259 if (a) { 0260 a->setEnabled(enable); 0261 } 0262 } 0263 0264 ////////////////////////////////////////// i18n related functions //////// 0265 0266 void FormPrivate::initPropertiesDescription() 0267 { 0268 //! \todo perhaps a few of them shouldn't be translated within KFD mode, 0269 //! to be more Qt Designer friendly? 0270 propCaption["name"] = xi18n("Name"); // for backward compatibility with Qt 3 0271 propCaption["objectName"] = xi18n("Name"); 0272 propCaption["caption"] = xi18n("Caption"); 0273 propCaption["windowTitle"] = xi18n("Window title"); 0274 propCaption["text"] = xi18n("Text"); 0275 propCaption["paletteBackgroundPixmap"] = xi18n("Background Pixmap"); 0276 propCaption["enabled"] = xi18nc("Property: enabled widget", "Enabled"); 0277 propCaption["geometry"] = xi18n("Geometry"); 0278 propCaption["sizePolicy"] = xi18n("Size Policy"); 0279 propCaption["minimumSize"] = xi18n("Minimum Size"); 0280 propCaption["maximumSize"] = xi18n("Maximum Size"); 0281 propCaption["font"] = xi18n("Font"); 0282 propCaption["cursor"] = xi18n("Cursor"); 0283 propCaption["paletteForegroundColor"] = xi18n("Foreground Color"); 0284 propCaption["paletteBackgroundColor"] = xi18n("Background Color"); 0285 propCaption["autoFillBackground"] = xi18n("Fill Background"); 0286 propCaption["focusPolicy"] = xi18n("Focus Policy"); 0287 propCaption["margin"] = xi18n("Margin"); 0288 propCaption["readOnly"] = xi18n("Read Only"); 0289 propCaption["styleSheet"] = xi18n("Style Sheet"); 0290 propCaption["toolTip"] = xi18nc("Widget's Tooltip", "Tooltip"); 0291 propCaption["whatsThis"] = xi18nc("Widget's Whats This", "What's This"); 0292 propCaption["iconSize"] = xi18n("Icon Size"); 0293 0294 //any QFrame 0295 propCaption["frame"] = xi18n("Frame"); 0296 propCaption["lineWidth"] = xi18n("Frame Width"); 0297 propCaption["midLineWidth"] = xi18n("Mid Frame Width"); 0298 propCaption["frameShape"] = xi18n("Frame Shape"); 0299 propCaption["frameShadow"] = xi18n("Frame Shadow"); 0300 //any QScrollBar 0301 propCaption["vScrollBarMode"] = xi18n("Vertical Scrollbar"); 0302 propCaption["hScrollBarMode"] = xi18n("Horizontal Scrollbar"); 0303 0304 propValCaption["NoBackground"] = xi18n("No Background"); 0305 propValCaption["PaletteForeground"] = xi18n("Palette Foreground"); 0306 propValCaption["AutoText"] = xi18nc("Auto (HINT: for AutoText)", "Auto"); 0307 0308 propValCaption["AlignAuto"] = xi18nc("Auto (HINT: for Align)", "Auto"); 0309 propValCaption["AlignBaseline"] = xi18nc("Baseline (HINT: for Align)", "Baseline"); 0310 propValCaption["AlignLeft"] = xi18nc("Left (HINT: for Align)", "Left"); 0311 propValCaption["AlignLeading"] = xi18nc("Left (HINT: for Align)", "Left"); 0312 propValCaption["AlignRight"] = xi18nc("Right (HINT: for Align)", "Right"); 0313 propValCaption["AlignTrailing"] = xi18nc("Right (HINT: for Align)", "Right"); 0314 propValCaption["AlignHCenter"] = xi18nc("Center (HINT: for Align)", "Center"); 0315 propValCaption["AlignJustify"] = xi18nc("Justify (HINT: for Align)", "Justify"); 0316 propValCaption["AlignVCenter"] = xi18nc("Center (HINT: for Align)", "Center"); 0317 propValCaption["AlignTop"] = xi18nc("Top (HINT: for Align)", "Top"); 0318 propValCaption["AlignBottom"] = xi18nc("Bottom (HINT: for Align)", "Bottom"); 0319 0320 propValCaption["NoFrame"] = xi18nc("No Frame (HINT: for Frame Shape)", "No Frame"); 0321 propValCaption["Box"] = xi18nc("Box (HINT: for Frame Shape)", "Box"); 0322 propValCaption["Panel"] = xi18nc("Panel (HINT: for Frame Shape)", "Panel"); 0323 propValCaption["WinPanel"] = xi18nc("Windows Panel (HINT: for Frame Shape)", "Windows Panel"); 0324 propValCaption["HLine"] = xi18nc("Horiz. Line (HINT: for Frame Shape)", "Horiz. Line"); 0325 propValCaption["VLine"] = xi18nc("Vertical Line (HINT: for Frame Shape)", "Vertical Line"); 0326 propValCaption["StyledPanel"] = xi18nc("Styled (HINT: for Frame Shape)", "Styled"); 0327 propValCaption["PopupPanel"] = xi18nc("Popup (HINT: for Frame Shape)", "Popup"); 0328 propValCaption["MenuBarPanel"] = xi18nc("Menu Bar (HINT: for Frame Shape)", "Menu Bar"); 0329 propValCaption["ToolBarPanel"] = xi18nc("Toolbar (HINT: for Frame Shape)", "Toolbar"); 0330 propValCaption["LineEditPanel"] = xi18nc("Text Box (HINT: for Frame Shape)", "Text Box"); 0331 propValCaption["TabWidgetPanel"] = xi18nc("Tab Widget (HINT: for Frame Shape)", "Tab Widget"); 0332 propValCaption["GroupBoxPanel"] = xi18nc("Group Box (HINT: for Frame Shape)", "Group Box"); 0333 0334 propValCaption["Plain"] = xi18nc("Plain (HINT: for Frame Shadow)", "Plain"); 0335 propValCaption["Raised"] = xi18nc("Raised (HINT: for Frame Shadow)", "Raised"); 0336 propValCaption["Sunken"] = xi18nc("Sunken (HINT: for Frame Shadow)", "Sunken"); 0337 propValCaption["MShadow"] = xi18nc("for Frame Shadow", "Internal"); 0338 0339 propValCaption["NoFocus"] = xi18nc("No Focus (HINT: for Focus)", "No Focus"); 0340 propValCaption["TabFocus"] = xi18nc("Tab (HINT: for Focus)", "Tab"); 0341 propValCaption["ClickFocus"] = xi18nc("Click (HINT: for Focus)", "Click"); 0342 propValCaption["StrongFocus"] = xi18nc("Tab/Click (HINT: for Focus)", "Tab/Click"); 0343 propValCaption["WheelFocus"] = xi18nc("Tab/Click/MouseWheel (HINT: for Focus)", "Tab/Click/Mouse Wheel"); 0344 0345 propValCaption["Auto"] = xi18n("Auto"); 0346 propValCaption["AlwaysOff"] = xi18n("Always Off"); 0347 propValCaption["AlwaysOn"] = xi18n("Always On"); 0348 0349 //orientation 0350 propValCaption["Horizontal"] = xi18n("Horizontal"); 0351 propValCaption["Vertical"] = xi18n("Vertical"); 0352 0353 //layout direction 0354 propValCaption["LeftToRight"] = xi18n("Left to Right"); 0355 propValCaption["RightToLeft"] = xi18n("Right to Left"); 0356 } 0357 0358 KPropertyListData* FormPrivate::createValueList(WidgetInfo *winfo, const QStringList &list) 0359 { 0360 QStringList names; 0361 foreach (const QString& name, list) { 0362 QString n(propValCaption.value(name.toLatin1())); 0363 if (n.isEmpty()) { //try within factory and (maybe) parent factory 0364 if (winfo) { 0365 n = q->library()->propertyDescForValue(winfo, name.toLatin1()); 0366 } 0367 if (n.isEmpty()) { 0368 names.append(name); //untranslated 0369 } 0370 else { 0371 names.append(n); 0372 } 0373 } else { 0374 names.append(n); 0375 } 0376 } 0377 return new KPropertyListData(list, names); 0378 }