File indexing completed on 2024-05-05 04:49:29

0001 /****************************************************************************************
0002  * Copyright (c) 2009 Thomas Luebking <thomas.luebking@web.de>                          *
0003  * Copyright (c) 2012 Ralf Engels <ralf-engels@gmx.de>                                  *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #ifndef TOKENDROPTARGET_H
0019 #define TOKENDROPTARGET_H
0020 
0021 #include <QWidget>
0022 
0023 class QBoxLayout;
0024 class QHBoxLayout;
0025 class QDropEvent;
0026 class Token;
0027 class TokenFactory;
0028 
0029 /** A widget that accepts dragging Tokens into it.
0030     Used in several dialogs within Amarok e.g. the FilenameLayoutWidget and the
0031     LayoutEditWidget.
0032 
0033     The DropTarget can have one or more rows, limited by the rowLimit.
0034 */
0035 class TokenDropTarget : public QWidget
0036 {
0037     Q_OBJECT
0038 public:
0039     explicit TokenDropTarget( QWidget *parent = nullptr );
0040     ~TokenDropTarget() override;
0041 
0042     QSize sizeHint() const override;
0043     QSize minimumSizeHint() const override;
0044 
0045     /** Removes all tokens from the drop target. */
0046     void clear();
0047 
0048     /** Returns the total number of all tokens contained in this drop traget. */
0049     int count() const;
0050 
0051     /** Returns the row and column position of the \p token. */
0052     QPoint index( Token* token ) const;
0053 
0054     /** Returns the row of the given \p Token or -1 if not found. */
0055     int row ( Token* ) const;
0056 
0057     /** Returns the number of rows that this layout has. */
0058     uint rows() const { return m_rows; }
0059 
0060     /** Returns the maximum allowed number of rows.
0061         A number of 0 means that the row count is not limited at all.
0062     */
0063     uint rowLimit() const { return m_rowLimit; }
0064     void setRowLimit( uint r );
0065 
0066     /** Set a custom factory that creates tokens.
0067         The default factory is the one that creates normal tokens.
0068         LayoutEditWidget set's this for the factory that creates StyledTokens.
0069 
0070         The factory will be deleted by the TokenDropTarget.
0071     */
0072     void setCustomTokenFactory( TokenFactory * factory );
0073 
0074     void setVerticalStretch( bool value );
0075 
0076     /** Returns all the tokens from the specified row.
0077         If row == -1 returns all tokens. */
0078     QList< Token *> tokensAtRow( int row = -1 );
0079 
0080 public Q_SLOTS:
0081     /** Insert the token at the given row and col position.
0082         The token will be reparented for the TokenDropTarget.
0083     */
0084     void insertToken( Token*, int row, int col );
0085     void appendToken( Token *token ) { insertToken( token, -1, -1 ); } // -1 -> append to last row
0086 
0087     void deleteEmptyRows();
0088 Q_SIGNALS:
0089     void changed();
0090 
0091     /** Emitted if a new token got the focus. */
0092     void tokenSelected( Token* );
0093 
0094 protected:
0095     void dragEnterEvent( QDragEnterEvent *event ) override;
0096     void dropEvent( QDropEvent *event ) override;
0097 
0098     /** Draws a "drop here" text if empty */
0099     void paintEvent(QPaintEvent *) override;
0100 
0101     /** Return the enclosing box layout and the row and column position of the widget \p w.  */
0102     QBoxLayout *rowBox( QWidget *w, QPoint *idx = nullptr ) const;
0103 
0104     /** Return the box layout at the position \p pt. */
0105     QBoxLayout *rowBox( const QPoint &pt ) const;
0106 
0107 private:
0108     QHBoxLayout *appendRow();
0109 
0110     /** Returns the token at the given global position */
0111     Token* tokenAt( const QPoint &pos ) const;
0112 
0113     void drop( Token*, const QPoint &pos = QPoint(0,0) );
0114 
0115 private:
0116     /** Maximum number of allowed rows.
0117         If 0 the number is unlimited. */
0118     uint m_rowLimit;
0119 
0120     /** contains the number of real rows
0121         (using the layout is not very practical in that since it seems that the layout
0122         adds at least one empty entry by itself if it's empty) */
0123     uint m_rows;
0124 
0125     /** True if stretch are inserted at the ends of every row. */
0126     bool m_horizontalStretch;
0127 
0128     /** True if a stretch is inserted as a last row.
0129         For now we always have a vertical stretch if the m_rowLimit > 1 */
0130     bool m_verticalStretch;
0131 
0132     TokenFactory *m_tokenFactory;
0133 };
0134 
0135 #endif