1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the Qt Designer of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 ** included in the packaging of this file. Please review the following 22 ** information to ensure the GNU General Public License requirements will 23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 ** 25 ** $QT_END_LICENSE$ 26 ** 27 ****************************************************************************/ 28 29 #ifndef FORMWINDOW_H 30 #define FORMWINDOW_H 31 32 #include "formeditor_global.h" 33 #include <formwindowbase_p.h> 34 35 // Qt 36 #include <QtWidgets/qundostack.h> 37 #include <QtCore/qhash.h> 38 #include <QtCore/qlist.h> 39 #include <QtCore/qmap.h> 40 #include <QtCore/qset.h> 41 #include <QtCore/qpointer.h> 42 43 QT_BEGIN_NAMESPACE 44 45 class QDesignerDnDItemInterface; 46 class QDesignerTaskMenuExtension; 47 class DomConnections; 48 class DomUI; 49 50 class QWidget; 51 class QAction; 52 class QLabel; 53 class QTimer; 54 class QAction; 55 class QMenu; 56 class QRubberBand; 57 58 namespace qdesigner_internal { 59 60 class FormEditor; 61 class FormWindowCursor; 62 class WidgetEditorTool; 63 class FormWindowWidgetStack; 64 class FormWindowManager; 65 class FormWindowDnDItem; 66 class SetPropertyCommand; 67 68 class QT_FORMEDITOR_EXPORT FormWindow: public FormWindowBase 69 { 70 Q_OBJECT 71 72 public: 73 enum HandleOperation 74 { 75 NoHandleOperation, 76 ResizeHandleOperation, 77 ChangeLayoutSpanHandleOperation 78 }; 79 80 explicit FormWindow(FormEditor *core, QWidget *parent = nullptr, Qt::WindowFlags flags = {}); 81 ~FormWindow() override; 82 83 QDesignerFormEditorInterface *core() const override; 84 85 QDesignerFormWindowCursorInterface *cursor() const override; 86 87 // Overwritten: FormWindowBase 88 QWidget *formContainer() const override; 89 90 int toolCount() const override; 91 int currentTool() const override; 92 void setCurrentTool(int index) override; 93 QDesignerFormWindowToolInterface *tool(int index) const override; 94 void registerTool(QDesignerFormWindowToolInterface *tool) override; 95 96 QString author() const override; 97 void setAuthor(const QString &author) override; 98 99 QString comment() const override; 100 void setComment(const QString &comment) override; 101 102 void layoutDefault(int *margin, int *spacing) override; 103 void setLayoutDefault(int margin, int spacing) override; 104 105 void layoutFunction(QString *margin, QString *spacing) override; 106 void setLayoutFunction(const QString &margin, const QString &spacing) override; 107 108 QString pixmapFunction() const override; 109 void setPixmapFunction(const QString &pixmapFunction) override; 110 111 QString exportMacro() const override; 112 void setExportMacro(const QString &exportMacro) override; 113 114 QStringList includeHints() const override; 115 void setIncludeHints(const QStringList &includeHints) override; 116 117 QString fileName() const override; 118 void setFileName(const QString &fileName) override; 119 120 QString contents() const override; 121 bool setContents(QIODevice *dev, QString *errorMessage = nullptr) override; 122 bool setContents(const QString &) override; 123 124 QDir absoluteDir() const override; 125 126 void simplifySelection(QWidgetList *sel) const override; 127 128 void ensureUniqueObjectName(QObject *object) override; 129 130 QWidget *mainContainer() const override; 131 void setMainContainer(QWidget *mainContainer) override; 132 bool isMainContainer(const QWidget *w) const; 133 134 QWidget *currentWidget() const; 135 136 bool hasInsertedChildren(QWidget *w) const; 137 138 QWidgetList selectedWidgets() const; 139 void clearSelection(bool changePropertyDisplay = true) override; 140 bool isWidgetSelected(QWidget *w) const; 141 void selectWidget(QWidget *w, bool select = true) override; 142 143 void selectWidgets(); 144 void repaintSelection(); 145 void updateSelection(QWidget *w); 146 void updateChildSelections(QWidget *w); 147 void raiseChildSelections(QWidget *w); 148 void raiseSelection(QWidget *w); 149 150 inline const QWidgetList& widgets() const { return m_widgets; } 151 inline int widgetCount() const { return m_widgets.count(); } 152 inline QWidget *widgetAt(int index) const { return m_widgets.at(index); } 153 154 QWidgetList widgets(QWidget *widget) const; 155 156 QWidget *createWidget(DomUI *ui, const QRect &rect, QWidget *target); 157 158 bool isManaged(QWidget *w) const override; 159 160 void manageWidget(QWidget *w) override; 161 void unmanageWidget(QWidget *w) override; 162 163 QUndoStack *commandHistory() const override; 164 void beginCommand(const QString &description) override; 165 void endCommand() override; 166 167 bool blockSelectionChanged(bool blocked) override; 168 void emitSelectionChanged() override; 169 170 bool unify(QObject *w, QString &s, bool changeIt); 171 172 bool isDirty() const override; 173 void setDirty(bool dirty) override; 174 175 static FormWindow *findFormWindow(QWidget *w); 176 177 virtual QWidget *containerAt(const QPoint &pos); 178 QWidget *widgetAt(const QPoint &pos) override; 179 void highlightWidget(QWidget *w, const QPoint &pos, HighlightMode mode = Highlight) override; 180 181 void updateOrderIndicators(); 182 183 bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event); 184 185 QStringList resourceFiles() const override; 186 void addResourceFile(const QString &path) override; 187 void removeResourceFile(const QString &path) override; 188 189 void resizeWidget(QWidget *widget, const QRect &geometry); 190 191 bool dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &global_mouse_pos); 192 bool dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target, 193 const QPoint &global_mouse_pos) override; 194 195 QWidget *findContainer(QWidget *w, bool excludeLayout) const override; 196 // for WidgetSelection only. 197 QWidget *designerWidget(QWidget *w) const; 198 199 // Initialize and return a popup menu for a managed widget 200 QMenu *initializePopupMenu(QWidget *managedWidget) override; 201 202 #if QT_CONFIG(clipboard) 203 void paste(PasteMode pasteMode) override; 204 #endif 205 QEditorFormBuilder *createFormBuilder() override; 206 207 bool eventFilter(QObject *watched, QEvent *event) override; 208 209 HandleOperation handleOperation() const { return m_handleOperation; } 210 void setHandleOperation(HandleOperation o) { m_handleOperation = o; } 211 212 signals: 213 void contextMenuRequested(QMenu *menu, QWidget *widget); 214 215 public slots: 216 void deleteWidgets(); 217 void raiseWidgets(); 218 void lowerWidgets(); 219 #if QT_CONFIG(clipboard) 220 void copy(); 221 void cut(); 222 void paste(); 223 #endif 224 void selectAll(); 225 226 void createLayout(int type, QWidget *container = nullptr); 227 void morphLayout(QWidget *container, int newType); 228 void breakLayout(QWidget *w); 229 230 void editContents(); 231 232 protected: 233 virtual QMenu *createPopupMenu(QWidget *w); 234 void resizeEvent(QResizeEvent *e) override; 235 236 void insertWidget(QWidget *w, const QRect &rect, QWidget *target, bool already_in_form = false); 237 238 private slots: 239 void selectionChangedTimerDone(); 240 void checkSelection(); 241 void checkSelectionNow(); 242 void slotSelectWidget(QAction *); 243 void slotCleanChanged(bool); 244 245 private: 246 enum MouseState { 247 NoMouseState, 248 // Double click received 249 MouseDoubleClicked, 250 // Drawing selection rubber band rectangle 251 MouseDrawRubber, 252 // Started a move operation 253 MouseMoveDrag, 254 // Click on a widget whose parent is selected. Defer selection to release 255 MouseDeferredSelection 256 }; 257 MouseState m_mouseState; 258 QPointer<QWidget> m_lastClickedWidget; 259 260 void init(); 261 void initializeCoreTools(); 262 263 int getValue(const QRect &rect, int key, bool size) const; 264 int calcValue(int val, bool forward, bool snap, int snapOffset) const; 265 void handleClickSelection(QWidget *managedWidget, unsigned mouseFlags); 266 267 bool frameNeeded(QWidget *w) const; 268 269 enum RectType { Insert, Rubber }; 270 271 void startRectDraw(const QPoint &global, QWidget *, RectType t); 272 void continueRectDraw(const QPoint &global, QWidget *, RectType t); 273 void endRectDraw(); 274 275 QWidget *containerAt(const QPoint &pos, QWidget *notParentOf); 276 277 void checkPreviewGeometry(QRect &r); 278 279 bool handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e); 280 bool handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e); 281 bool handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e); 282 bool handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e); 283 bool handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e); 284 bool handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e); 285 bool handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e); 286 287 bool isCentralWidget(QWidget *w) const; 288 289 bool setCurrentWidget(QWidget *currentWidget); 290 bool trySelectWidget(QWidget *w, bool select); 291 292 void dragWidgetWithinForm(QWidget *widget, const QRect &targetGeometry, QWidget *targetContainer); 293 294 void setCursorToAll(const QCursor &c, QWidget *start); 295 296 QPoint mapToForm(const QWidget *w, const QPoint &pos) const; 297 bool canBeBuddy(QWidget *w) const; 298 299 QWidget *findTargetContainer(QWidget *widget) const; 300 301 void clearMainContainer(); 302 303 static int widgetDepth(const QWidget *w); 304 static bool isChildOf(const QWidget *c, const QWidget *p); 305 306 void editWidgets() override; 307 308 void updateWidgets(); 309 310 void handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers); 311 312 void layoutSelection(int type); 313 void layoutContainer(QWidget *w, int type); 314 315 private: 316 QWidget *innerContainer(QWidget *outerContainer) const; 317 QWidget *containerForPaste() const; 318 QAction *createSelectAncestorSubMenu(QWidget *w); 319 void selectSingleWidget(QWidget *w); 320 321 FormEditor *m_core; 322 FormWindowCursor *m_cursor; 323 QWidget *m_mainContainer = nullptr; 324 QWidget *m_currentWidget = nullptr; 325 326 bool m_blockSelectionChanged = false; 327 328 QPoint m_rectAnchor; 329 QRect m_currRect; 330 331 QWidgetList m_widgets; 332 QSet<QWidget*> m_insertedWidgets; 333 334 class Selection; 335 Selection *m_selection; 336 337 QPoint m_startPos; 338 339 QUndoStack m_undoStack; 340 341 QString m_fileName; 342 343 using PaletteAndFill = QPair<QPalette ,bool>; 344 using WidgetPaletteMap = QMap<QWidget*, PaletteAndFill>; 345 WidgetPaletteMap m_palettesBeforeHighlight; 346 347 QRubberBand *m_rubberBand = nullptr; 348 349 QTimer *m_selectionChangedTimer = nullptr; 350 QTimer *m_checkSelectionTimer = nullptr; 351 QTimer *m_geometryChangedTimer = nullptr; 352 353 FormWindowWidgetStack *m_widgetStack; 354 WidgetEditorTool *m_widgetEditor = nullptr; 355 356 QStringList m_resourceFiles; 357 358 QString m_comment; 359 QString m_author; 360 QString m_pixmapFunction; 361 int m_defaultMargin, m_defaultSpacing; 362 QString m_marginFunction, m_spacingFunction; 363 QString m_exportMacro; 364 QStringList m_includeHints; 365 366 QPoint m_contextMenuPosition; 367 HandleOperation m_handleOperation = NoHandleOperation; 368 369 private: 370 friend class WidgetEditorTool; 371 }; 372 373 } // namespace qdesigner_internal 374 375 QT_END_NAMESPACE 376 377 #endif // FORMWINDOW_H 378