Skip to content

Commit d62d444

Browse files
committedJun 2, 2017
Moved support classes into own private header
1 parent 7082649 commit d62d444

File tree

6 files changed

+747
-940
lines changed

6 files changed

+747
-940
lines changed
 

‎python/gui/qgsbrowserdockwidget.sip

Lines changed: 2 additions & 289 deletions
Original file line numberDiff line numberDiff line change
@@ -9,165 +9,19 @@
99

1010

1111

12-
class QgsBrowserPropertiesWrapLabel : QTextEdit
13-
{
14-
%Docstring
15-
Hack to show wrapped text without spaces
16-
.. versionadded:: 2.10
17-
%End
18-
19-
%TypeHeaderCode
20-
#include "qgsbrowserdockwidget.h"
21-
%End
22-
public:
23-
24-
QgsBrowserPropertiesWrapLabel( const QString &text, QWidget *parent = 0 );
25-
%Docstring
26-
Constructor for QgsBrowserPropertiesWrapLabel
27-
\param text label text
28-
\param parent parent widget
29-
%End
30-
31-
};
32-
33-
class QgsBrowserPropertiesWidget : QWidget
34-
{
35-
%Docstring
36-
The QgsBrowserPropertiesWidget base class
37-
.. versionadded:: 2.10
38-
%End
39-
40-
%TypeHeaderCode
41-
#include "qgsbrowserdockwidget.h"
42-
%End
43-
public:
44-
45-
explicit QgsBrowserPropertiesWidget( QWidget *parent = 0 );
46-
%Docstring
47-
Constructor for QgsBrowserPropertiesWidget
48-
\param parent parent widget
49-
%End
50-
static QgsBrowserPropertiesWidget *createWidget( QgsDataItem *item, QWidget *parent = 0 ) /Factory/;
51-
%Docstring
52-
Factory method to create a new browser widget
53-
:rtype: QgsBrowserPropertiesWidget
54-
%End
55-
virtual void setItem( QgsDataItem *item );
56-
%Docstring
57-
Stub
58-
%End
59-
virtual void setWidget( QWidget *widget );
60-
%Docstring
61-
Set content widget, usually item paramWidget. Takes ownership.
62-
%End
63-
64-
virtual void setCondensedMode( bool condensedMode );
65-
%Docstring
66-
Sets whether the properties widget should display in condensed mode, ie, for display in a dock
67-
widget rather than it's own separate dialog.
68-
\param condensedMode set to true to enable condensed mode
69-
.. versionadded:: 2.10
70-
%End
71-
};
72-
73-
class QgsBrowserLayerProperties : QgsBrowserPropertiesWidget
74-
{
75-
%Docstring
76-
The QgsBrowserLayerProperties class
77-
.. versionadded:: 2.10
78-
%End
79-
80-
%TypeHeaderCode
81-
#include "qgsbrowserdockwidget.h"
82-
%End
83-
public:
84-
85-
explicit QgsBrowserLayerProperties( QWidget *parent = 0 );
86-
%Docstring
87-
Constructor for QgsBrowserLayerProperties
88-
\param parent parent widget
89-
%End
90-
virtual void setItem( QgsDataItem *item );
91-
92-
%Docstring
93-
Set item
94-
%End
95-
96-
virtual void setCondensedMode( bool condensedMode );
97-
%Docstring
98-
Sets whether the properties widget should display in condensed mode, ie, for display in a dock
99-
widget rather than it's own separate dialog.
100-
\param condensedMode set to true to enable condensed mode
101-
.. versionadded:: 2.10
102-
%End
103-
104-
};
105-
106-
class QgsBrowserDirectoryProperties : QgsBrowserPropertiesWidget
107-
{
108-
%Docstring
109-
The QgsBrowserDirectoryProperties class
110-
.. versionadded:: 2.10
111-
%End
112-
113-
%TypeHeaderCode
114-
#include "qgsbrowserdockwidget.h"
115-
%End
116-
public:
117-
118-
explicit QgsBrowserDirectoryProperties( QWidget *parent = 0 );
119-
%Docstring
120-
Constructor for QgsBrowserDirectoryProperties
121-
\param parent parent widget
122-
%End
123-
124-
virtual void setItem( QgsDataItem *item );
125-
126-
%Docstring
127-
Create widget from the given item and add it
128-
%End
129-
};
130-
131-
class QgsBrowserPropertiesDialog : QDialog
132-
{
133-
%Docstring
134-
The QgsBrowserPropertiesDialog class
135-
.. versionadded:: 2.10
136-
%End
137-
138-
%TypeHeaderCode
139-
#include "qgsbrowserdockwidget.h"
140-
%End
141-
public:
142-
143-
QgsBrowserPropertiesDialog( const QString &settingsSection, QWidget *parent = 0 );
144-
%Docstring
145-
Constructor for QgsBrowserPropertiesDialog
146-
\param settingsSection prefix for settings (from the object name)
147-
\param parent parent widget
148-
%End
149-
~QgsBrowserPropertiesDialog();
150-
151-
void setItem( QgsDataItem *item );
152-
%Docstring
153-
Create dialog from the given item and add it
154-
%End
155-
156-
};
157-
15812
class QgsBrowserDockWidget : QgsDockWidget
15913
{
16014
%Docstring
16115
The QgsBrowserDockWidget class
162-
.. versionadded:: 2.10
16+
.. versionadded:: 3.0
16317
%End
16418

16519
%TypeHeaderCode
16620
#include "qgsbrowserdockwidget.h"
16721
%End
16822
public:
16923

170-
explicit QgsBrowserDockWidget( const QString &name, QWidget *parent = 0 );
24+
explicit QgsBrowserDockWidget( const QString &name, QWidget *parent /TransferThis/ = 0 );
17125
%Docstring
17226
Constructor for QgsBrowserDockWidget
17327
\param name name of the widget
@@ -232,7 +86,6 @@ Apply filter to the model
23286
Update project home directory
23387
%End
23488

235-
23689
void addSelectedLayers();
23790
%Docstring
23891
Add selected layers to the project
@@ -270,154 +123,14 @@ Emitted when drop uri list needs to be handled
270123
%End
271124

272125
protected:
273-
void refreshModel( const QModelIndex &index );
274-
%Docstring
275-
Refresh the model
276-
%End
277126
virtual void showEvent( QShowEvent *event );
278127

279128
%Docstring
280129
Show event override
281130
%End
282-
void addLayer( QgsLayerItem *layerItem );
283-
%Docstring
284-
Add a layer
285-
%End
286-
void clearPropertiesWidget();
287-
%Docstring
288-
Clear the properties widget
289-
%End
290-
void setPropertiesWidget();
291-
%Docstring
292-
Set the properties widget
293-
%End
294-
295-
int selectedItemsCount();
296-
%Docstring
297-
Count selected items
298-
:rtype: int
299-
%End
300-
QString settingsSection();
301-
%Docstring
302-
Settings prefix (the object name)
303-
:rtype: str
304-
%End
305-
306-
307-
};
308-
309-
310-
class QgsDockBrowserTreeView : QgsBrowserTreeView
311-
{
312-
%Docstring
313-
Utility class for correct drag&drop handling.
314-
315-
We want to allow user to drag layers to qgis window. At the same time we do not
316-
accept drops of the items on our view - but if we ignore the drag enter action
317-
then qgis application consumes the drag events and it is possible to drop the
318-
items on the tree view although the drop is actually managed by qgis app.
319-
.. versionadded:: 2.10
320-
%End
321-
322-
%TypeHeaderCode
323-
#include "qgsbrowserdockwidget.h"
324-
%End
325-
public:
326-
327-
explicit QgsDockBrowserTreeView( QWidget *parent );
328-
%Docstring
329-
Constructor for QgsDockBrowserTreeView
330-
\param parent parent widget
331-
%End
332-
virtual void dragEnterEvent( QDragEnterEvent *e );
333-
334-
%Docstring
335-
Overrides drag enter event
336-
%End
337-
virtual void dragMoveEvent( QDragMoveEvent *e );
338-
339-
%Docstring
340-
Overrides drag move event
341-
%End
342-
virtual void dropEvent( QDropEvent *e );
343131

344-
%Docstring
345-
Overrides drag stop event
346-
%End
347132
};
348133

349-
class QgsBrowserTreeFilterProxyModel : QSortFilterProxyModel
350-
{
351-
%Docstring
352-
Utility class for filtering browser items
353-
.. versionadded:: 2.10
354-
%End
355-
356-
%TypeHeaderCode
357-
#include "qgsbrowserdockwidget.h"
358-
%End
359-
public:
360-
361-
explicit QgsBrowserTreeFilterProxyModel( QObject *parent );
362-
%Docstring
363-
Constructor for QgsBrowserTreeFilterProxyModel
364-
@param parent parent widget
365-
%End
366-
void setBrowserModel( QgsBrowserModel *model );
367-
%Docstring
368-
Set the browser model
369-
%End
370-
void setFilterSyntax( const QString &syntax );
371-
%Docstring
372-
Set the filter syntax
373-
%End
374-
void setFilter( const QString &filter );
375-
%Docstring
376-
Set the filter
377-
%End
378-
void setCaseSensitive( bool caseSensitive );
379-
%Docstring
380-
Set case sensitivity
381-
%End
382-
void updateFilter();
383-
%Docstring
384-
Update filter
385-
%End
386-
387-
protected:
388-
389-
390-
bool filterAcceptsString( const QString &value ) const;
391-
%Docstring
392-
Filter accepts string
393-
:rtype: bool
394-
%End
395-
396-
virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const;
397-
398-
%Docstring
399-
It would be better to apply the filer only to expanded (visible) items, but using mapFromSource() + view here was causing strange errors
400-
:rtype: bool
401-
%End
402-
403-
bool filterAcceptsAncestor( const QModelIndex &sourceIndex ) const;
404-
%Docstring
405-
Returns true if at least one ancestor is accepted by filter
406-
:rtype: bool
407-
%End
408-
409-
bool filterAcceptsDescendant( const QModelIndex &sourceIndex ) const;
410-
%Docstring
411-
Returns true if at least one descendant s accepted by filter
412-
:rtype: bool
413-
%End
414-
415-
bool filterAcceptsItem( const QModelIndex &sourceIndex ) const;
416-
%Docstring
417-
Filter accepts item name
418-
:rtype: bool
419-
%End
420-
};
421134

422135

423136
/************************************************************************

‎src/gui/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ SET(QGIS_GUI_SRCS
174174
qgsblendmodecombobox.cpp
175175
qgsbrowsertreeview.cpp
176176
qgsbrowserdockwidget.cpp
177+
qgsbrowserdockwidget_p.cpp
177178
qgsbusyindicatordialog.cpp
178179
qgscharacterselectordialog.cpp
179180
qgscheckablecombobox.cpp
@@ -363,6 +364,7 @@ SET(QGIS_GUI_MOC_HDRS
363364
qgsdial.h
364365
qgsdialog.h
365366
qgsdockwidget.h
367+
qgsbrowserdockwidget_p.h
366368
qgsbrowserdockwidget.h
367369
qgsencodingfiledialog.h
368370
qgserrordialog.h
@@ -651,6 +653,7 @@ SET(QGIS_GUI_HDRS
651653
qgstablewidgetitem.h
652654
qgsuserinputdockwidget.h
653655
qgsbrowserdockwidget.h
656+
qgsbrowserdockwidget_p.h
654657
qgsvertexmarker.h
655658
qgsfiledownloader.h
656659

‎src/gui/qgsbrowserdockwidget.cpp

Lines changed: 1 addition & 437 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* *
1414
***************************************************************************/
1515
#include "qgsbrowserdockwidget.h"
16+
#include "qgsbrowserdockwidget_p.h"
1617

1718
#include <QAbstractTextDocumentLayout>
1819
#include <QHeaderView>
@@ -37,228 +38,6 @@
3738

3839
#include <QDragEnterEvent>
3940

40-
QgsBrowserPropertiesWrapLabel::QgsBrowserPropertiesWrapLabel( const QString &text, QWidget *parent )
41-
: QTextEdit( text, parent )
42-
{
43-
setReadOnly( true );
44-
setFrameStyle( QFrame::NoFrame );
45-
setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
46-
QPalette pal = palette();
47-
pal.setColor( QPalette::Base, Qt::transparent );
48-
setPalette( pal );
49-
setLineWrapMode( QTextEdit::WidgetWidth );
50-
setWordWrapMode( QTextOption::WrapAnywhere );
51-
connect( qobject_cast<QAbstractTextDocumentLayout *>( document()->documentLayout() ), &QAbstractTextDocumentLayout::documentSizeChanged,
52-
this, &QgsBrowserPropertiesWrapLabel::adjustHeight );
53-
setMaximumHeight( 20 );
54-
}
55-
56-
void QgsBrowserPropertiesWrapLabel::adjustHeight( QSizeF size )
57-
{
58-
int height = size.height() + 2 * frameWidth();
59-
setMinimumHeight( height );
60-
setMaximumHeight( height );
61-
}
62-
63-
QgsBrowserPropertiesWidget::QgsBrowserPropertiesWidget( QWidget *parent )
64-
: QWidget( parent )
65-
{
66-
}
67-
68-
void QgsBrowserPropertiesWidget::setWidget( QWidget *paramWidget )
69-
{
70-
QVBoxLayout *layout = new QVBoxLayout( this );
71-
paramWidget->setParent( this );
72-
layout->addWidget( paramWidget );
73-
}
74-
75-
QgsBrowserPropertiesWidget *QgsBrowserPropertiesWidget::createWidget( QgsDataItem *item, QWidget *parent )
76-
{
77-
QgsBrowserPropertiesWidget *propertiesWidget = nullptr;
78-
// In general, we would like to show all items' paramWidget, but top level items like
79-
// WMS etc. have currently too large widgets which do not fit well to browser properties widget
80-
if ( item->type() == QgsDataItem::Directory )
81-
{
82-
propertiesWidget = new QgsBrowserDirectoryProperties( parent );
83-
propertiesWidget->setItem( item );
84-
}
85-
else if ( item->type() == QgsDataItem::Layer )
86-
{
87-
// prefer item's widget over standard layer widget
88-
QWidget *paramWidget = item->paramWidget();
89-
if ( paramWidget )
90-
{
91-
propertiesWidget = new QgsBrowserPropertiesWidget( parent );
92-
propertiesWidget->setWidget( paramWidget );
93-
}
94-
else
95-
{
96-
propertiesWidget = new QgsBrowserLayerProperties( parent );
97-
propertiesWidget->setItem( item );
98-
}
99-
}
100-
return propertiesWidget;
101-
}
102-
103-
QgsBrowserLayerProperties::QgsBrowserLayerProperties( QWidget *parent )
104-
: QgsBrowserPropertiesWidget( parent )
105-
{
106-
setupUi( this );
107-
108-
mUriLabel = new QgsBrowserPropertiesWrapLabel( QString(), this );
109-
mHeaderGridLayout->addItem( new QWidgetItem( mUriLabel ), 1, 1 );
110-
}
111-
112-
void QgsBrowserLayerProperties::setItem( QgsDataItem *item )
113-
{
114-
QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
115-
if ( !layerItem )
116-
return;
117-
118-
mNoticeLabel->clear();
119-
120-
QgsMapLayer::LayerType type = layerItem->mapLayerType();
121-
QString layerMetadata = tr( "Error" );
122-
QgsCoordinateReferenceSystem layerCrs;
123-
124-
// temporarily override /Projections/defaultBehavior to avoid dialog prompt
125-
QgsSettings settings;
126-
QString defaultProjectionOption = settings.value( QStringLiteral( "Projections/defaultBehavior" ), "prompt" ).toString();
127-
if ( settings.value( QStringLiteral( "Projections/defaultBehavior" ), "prompt" ).toString() == QLatin1String( "prompt" ) )
128-
{
129-
settings.setValue( QStringLiteral( "Projections/defaultBehavior" ), "useProject" );
130-
}
131-
132-
// find root item
133-
// we need to create a temporary layer to get metadata
134-
// we could use a provider but the metadata is not as complete and "pretty" and this is easier
135-
QgsDebugMsg( QString( "creating temporary layer using path %1" ).arg( layerItem->path() ) );
136-
if ( type == QgsMapLayer::RasterLayer )
137-
{
138-
QgsDebugMsg( "creating raster layer" );
139-
// should copy code from addLayer() to split uri ?
140-
QgsRasterLayer *layer = new QgsRasterLayer( layerItem->uri(), layerItem->uri(), layerItem->providerKey() );
141-
if ( layer )
142-
{
143-
if ( layer->isValid() )
144-
{
145-
layerCrs = layer->crs();
146-
layerMetadata = layer->htmlMetadata();
147-
}
148-
delete layer;
149-
}
150-
}
151-
else if ( type == QgsMapLayer::VectorLayer )
152-
{
153-
QgsDebugMsg( "creating vector layer" );
154-
QgsVectorLayer *layer = new QgsVectorLayer( layerItem->uri(), layerItem->name(), layerItem->providerKey() );
155-
if ( layer )
156-
{
157-
if ( layer->isValid() )
158-
{
159-
layerCrs = layer->crs();
160-
layerMetadata = layer->htmlMetadata();
161-
}
162-
delete layer;
163-
}
164-
}
165-
else if ( type == QgsMapLayer::PluginLayer )
166-
{
167-
// TODO: support display of properties for plugin layers
168-
return;
169-
}
170-
171-
// restore /Projections/defaultBehavior
172-
if ( defaultProjectionOption == QLatin1String( "prompt" ) )
173-
{
174-
settings.setValue( QStringLiteral( "Projections/defaultBehavior" ), defaultProjectionOption );
175-
}
176-
177-
mNameLabel->setText( layerItem->name() );
178-
mUriLabel->setText( layerItem->uri() );
179-
mProviderLabel->setText( layerItem->providerKey() );
180-
QString myStyle = QgsApplication::reportStyleSheet();
181-
mMetadataTextBrowser->document()->setDefaultStyleSheet( myStyle );
182-
mMetadataTextBrowser->setHtml( layerMetadata );
183-
184-
// report if layer was set to to project crs without prompt (may give a false positive)
185-
if ( defaultProjectionOption == QLatin1String( "prompt" ) )
186-
{
187-
QgsCoordinateReferenceSystem defaultCrs =
188-
QgsProject::instance()->crs();
189-
if ( layerCrs == defaultCrs )
190-
mNoticeLabel->setText( "NOTICE: Layer srs set from project (" + defaultCrs.authid() + ')' );
191-
}
192-
193-
if ( mNoticeLabel->text().isEmpty() )
194-
{
195-
mNoticeLabel->hide();
196-
}
197-
}
198-
199-
void QgsBrowserLayerProperties::setCondensedMode( bool condensedMode )
200-
{
201-
if ( condensedMode )
202-
{
203-
mUriLabel->setLineWrapMode( QTextEdit::NoWrap );
204-
mUriLabel->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
205-
mUriLabel->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
206-
}
207-
else
208-
{
209-
mUriLabel->setLineWrapMode( QTextEdit::WidgetWidth );
210-
mUriLabel->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
211-
mUriLabel->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
212-
}
213-
}
214-
215-
QgsBrowserDirectoryProperties::QgsBrowserDirectoryProperties( QWidget *parent )
216-
: QgsBrowserPropertiesWidget( parent )
217-
, mDirectoryWidget( nullptr )
218-
{
219-
setupUi( this );
220-
221-
mPathLabel = new QgsBrowserPropertiesWrapLabel( QString(), mHeaderWidget );
222-
mHeaderGridLayout->addItem( new QWidgetItem( mPathLabel ), 0, 1 );
223-
}
224-
225-
void QgsBrowserDirectoryProperties::setItem( QgsDataItem *item )
226-
{
227-
QgsDirectoryItem *directoryItem = qobject_cast<QgsDirectoryItem *>( item );
228-
if ( !item )
229-
return;
230-
231-
mPathLabel->setText( directoryItem->dirPath() );
232-
mDirectoryWidget = new QgsDirectoryParamWidget( directoryItem->dirPath(), this );
233-
mLayout->addWidget( mDirectoryWidget );
234-
}
235-
236-
QgsBrowserPropertiesDialog::QgsBrowserPropertiesDialog( const QString &settingsSection, QWidget *parent )
237-
: QDialog( parent )
238-
, mPropertiesWidget( nullptr )
239-
, mSettingsSection( settingsSection )
240-
{
241-
setupUi( this );
242-
QgsSettings settings;
243-
restoreGeometry( settings.value( mSettingsSection + "/propertiesDialog/geometry" ).toByteArray() );
244-
}
245-
246-
QgsBrowserPropertiesDialog::~QgsBrowserPropertiesDialog()
247-
{
248-
QgsSettings settings;
249-
settings.setValue( mSettingsSection + "/propertiesDialog/geometry", saveGeometry() );
250-
}
251-
252-
void QgsBrowserPropertiesDialog::setItem( QgsDataItem *item )
253-
{
254-
if ( !item )
255-
return;
256-
257-
mPropertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, this );
258-
mLayout->addWidget( mPropertiesWidget );
259-
setWindowTitle( item->type() == QgsDataItem::Layer ? tr( "Layer Properties" ) : tr( "Directory Properties" ) );
260-
}
261-
26241
QgsBrowserDockWidget::QgsBrowserDockWidget( const QString &name, QWidget *parent )
26342
: QgsDockWidget( parent )
26443
, mModel( nullptr )
@@ -743,218 +522,3 @@ void QgsBrowserDockWidget::splitterMoved()
743522
float total = sizes.value( 0 ) + sizes.value( 1 );
744523
mPropertiesWidgetHeight = total > 0 ? sizes.value( 1 ) / total : 0;
745524
}
746-
747-
748-
//
749-
// QgsDockBrowserTreeView
750-
//
751-
752-
QgsDockBrowserTreeView::QgsDockBrowserTreeView( QWidget *parent ) : QgsBrowserTreeView( parent )
753-
{
754-
setDragDropMode( QTreeView::DragDrop ); // sets also acceptDrops + dragEnabled
755-
setSelectionMode( QAbstractItemView::ExtendedSelection );
756-
setContextMenuPolicy( Qt::CustomContextMenu );
757-
setHeaderHidden( true );
758-
setDropIndicatorShown( true );
759-
760-
}
761-
762-
void QgsDockBrowserTreeView::dragEnterEvent( QDragEnterEvent *e )
763-
{
764-
// if this mime data come from layer tree, the proposed action will be MoveAction
765-
// but for browser we really need CopyAction
766-
if ( e->mimeData()->hasFormat( QStringLiteral( "application/qgis.layertreemodeldata" ) ) &&
767-
e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
768-
e->setDropAction( Qt::CopyAction );
769-
770-
// accept drag enter so that our widget will not get ignored
771-
// and drag events will not get passed to QgisApp
772-
e->accept();
773-
}
774-
775-
void QgsDockBrowserTreeView::dragMoveEvent( QDragMoveEvent *e )
776-
{
777-
// do not accept drops above/below items
778-
/*if ( dropIndicatorPosition() != QAbstractItemView::OnItem )
779-
{
780-
QgsDebugMsg("drag not on item");
781-
e->ignore();
782-
return;
783-
}*/
784-
785-
// if this mime data come from layer tree, the proposed action will be MoveAction
786-
// but for browser we really need CopyAction
787-
if ( e->mimeData()->hasFormat( QStringLiteral( "application/qgis.layertreemodeldata" ) ) &&
788-
e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
789-
e->setDropAction( Qt::CopyAction );
790-
791-
QTreeView::dragMoveEvent( e );
792-
793-
if ( !e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
794-
{
795-
e->ignore();
796-
return;
797-
}
798-
}
799-
800-
void QgsDockBrowserTreeView::dropEvent( QDropEvent *e )
801-
{
802-
// if this mime data come from layer tree, the proposed action will be MoveAction
803-
// but for browser we really need CopyAction
804-
if ( e->mimeData()->hasFormat( QStringLiteral( "application/qgis.layertreemodeldata" ) ) &&
805-
e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
806-
e->setDropAction( Qt::CopyAction );
807-
808-
QTreeView::dropEvent( e );
809-
}
810-
811-
812-
//
813-
// QgsBrowserTreeFilterProxyModel
814-
//
815-
816-
QgsBrowserTreeFilterProxyModel::QgsBrowserTreeFilterProxyModel( QObject *parent )
817-
: QSortFilterProxyModel( parent )
818-
, mModel( nullptr )
819-
, mPatternSyntax( QStringLiteral( "normal" ) )
820-
, mCaseSensitivity( Qt::CaseInsensitive )
821-
{
822-
setDynamicSortFilter( true );
823-
}
824-
825-
void QgsBrowserTreeFilterProxyModel::setBrowserModel( QgsBrowserModel *model )
826-
{
827-
mModel = model;
828-
setSourceModel( model );
829-
}
830-
831-
void QgsBrowserTreeFilterProxyModel::setFilterSyntax( const QString &syntax )
832-
{
833-
QgsDebugMsg( QString( "syntax = %1" ).arg( syntax ) );
834-
if ( mPatternSyntax == syntax )
835-
return;
836-
mPatternSyntax = syntax;
837-
updateFilter();
838-
}
839-
840-
void QgsBrowserTreeFilterProxyModel::setFilter( const QString &filter )
841-
{
842-
QgsDebugMsg( QString( "filter = %1" ).arg( mFilter ) );
843-
if ( mFilter == filter )
844-
return;
845-
mFilter = filter;
846-
updateFilter();
847-
}
848-
849-
void QgsBrowserTreeFilterProxyModel::setCaseSensitive( bool caseSensitive )
850-
{
851-
mCaseSensitivity = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
852-
updateFilter();
853-
}
854-
855-
void QgsBrowserTreeFilterProxyModel::updateFilter()
856-
{
857-
QgsDebugMsg( QString( "filter = %1 syntax = %2" ).arg( mFilter, mPatternSyntax ) );
858-
mREList.clear();
859-
if ( mPatternSyntax == QLatin1String( "normal" ) )
860-
{
861-
Q_FOREACH ( const QString &f, mFilter.split( '|' ) )
862-
{
863-
QRegExp rx( QString( "*%1*" ).arg( f.trimmed() ) );
864-
rx.setPatternSyntax( QRegExp::Wildcard );
865-
rx.setCaseSensitivity( mCaseSensitivity );
866-
mREList.append( rx );
867-
}
868-
}
869-
else if ( mPatternSyntax == QLatin1String( "wildcard" ) )
870-
{
871-
Q_FOREACH ( const QString &f, mFilter.split( '|' ) )
872-
{
873-
QRegExp rx( f.trimmed() );
874-
rx.setPatternSyntax( QRegExp::Wildcard );
875-
rx.setCaseSensitivity( mCaseSensitivity );
876-
mREList.append( rx );
877-
}
878-
}
879-
else
880-
{
881-
QRegExp rx( mFilter.trimmed() );
882-
rx.setPatternSyntax( QRegExp::RegExp );
883-
rx.setCaseSensitivity( mCaseSensitivity );
884-
mREList.append( rx );
885-
}
886-
invalidateFilter();
887-
}
888-
889-
bool QgsBrowserTreeFilterProxyModel::filterAcceptsString( const QString &value ) const
890-
{
891-
if ( mPatternSyntax == QLatin1String( "normal" ) || mPatternSyntax == QLatin1String( "wildcard" ) )
892-
{
893-
Q_FOREACH ( const QRegExp &rx, mREList )
894-
{
895-
QgsDebugMsg( QString( "value: [%1] rx: [%2] match: %3" ).arg( value, rx.pattern() ).arg( rx.exactMatch( value ) ) );
896-
if ( rx.exactMatch( value ) )
897-
return true;
898-
}
899-
}
900-
else
901-
{
902-
Q_FOREACH ( const QRegExp &rx, mREList )
903-
{
904-
QgsDebugMsg( QString( "value: [%1] rx: [%2] match: %3" ).arg( value, rx.pattern() ).arg( rx.indexIn( value ) ) );
905-
if ( rx.indexIn( value ) != -1 )
906-
return true;
907-
}
908-
}
909-
return false;
910-
}
911-
912-
bool QgsBrowserTreeFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
913-
{
914-
if ( mFilter.isEmpty() || !mModel )
915-
return true;
916-
917-
QModelIndex sourceIndex = mModel->index( sourceRow, 0, sourceParent );
918-
return filterAcceptsItem( sourceIndex ) || filterAcceptsAncestor( sourceIndex ) || filterAcceptsDescendant( sourceIndex );
919-
}
920-
921-
bool QgsBrowserTreeFilterProxyModel::filterAcceptsAncestor( const QModelIndex &sourceIndex ) const
922-
{
923-
if ( !mModel )
924-
return true;
925-
926-
QModelIndex sourceParentIndex = mModel->parent( sourceIndex );
927-
if ( !sourceParentIndex.isValid() )
928-
return false;
929-
if ( filterAcceptsItem( sourceParentIndex ) )
930-
return true;
931-
932-
return filterAcceptsAncestor( sourceParentIndex );
933-
}
934-
935-
bool QgsBrowserTreeFilterProxyModel::filterAcceptsDescendant( const QModelIndex &sourceIndex ) const
936-
{
937-
if ( !mModel )
938-
return true;
939-
940-
for ( int i = 0; i < mModel->rowCount( sourceIndex ); i++ )
941-
{
942-
QgsDebugMsg( QString( "i = %1" ).arg( i ) );
943-
QModelIndex sourceChildIndex = mModel->index( i, 0, sourceIndex );
944-
if ( filterAcceptsItem( sourceChildIndex ) )
945-
return true;
946-
if ( filterAcceptsDescendant( sourceChildIndex ) )
947-
return true;
948-
}
949-
return false;
950-
}
951-
952-
bool QgsBrowserTreeFilterProxyModel::filterAcceptsItem( const QModelIndex &sourceIndex ) const
953-
{
954-
if ( !mModel )
955-
return true;
956-
//accept item if either displayed text or comment role matches string
957-
QString comment = mModel->data( sourceIndex, QgsBrowserModel::CommentRole ).toString();
958-
return ( filterAcceptsString( mModel->data( sourceIndex, Qt::DisplayRole ).toString() )
959-
|| ( !comment.isEmpty() && filterAcceptsString( comment ) ) );
960-
}

‎src/gui/qgsbrowserdockwidget.h

Lines changed: 7 additions & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "qgsdataitem.h"
2424
#include "qgsbrowsertreeview.h"
2525
#include "qgsdockwidget.h"
26+
#include "qgsbrowserdockwidget_p.h"
2627
#include "qgis_gui.h"
2728
#include <QSortFilterProxyModel>
2829

@@ -33,139 +34,10 @@ class QgsLayerItem;
3334
class QgsDataItem;
3435
class QgsBrowserTreeFilterProxyModel;
3536

36-
/**
37-
* \ingroup gui
38-
* Hack to show wrapped text without spaces
39-
* \since QGIS 2.10
40-
*/
41-
class GUI_EXPORT QgsBrowserPropertiesWrapLabel : public QTextEdit
42-
{
43-
Q_OBJECT
44-
public:
45-
46-
/**
47-
* Constructor for QgsBrowserPropertiesWrapLabel
48-
* \param text label text
49-
* \param parent parent widget
50-
*/
51-
QgsBrowserPropertiesWrapLabel( const QString &text, QWidget *parent = nullptr );
52-
53-
private slots:
54-
void adjustHeight( QSizeF size );
55-
};
56-
57-
/**
58-
* \ingroup gui
59-
* The QgsBrowserPropertiesWidget base class
60-
* \since QGIS 2.10
61-
*/
62-
class GUI_EXPORT QgsBrowserPropertiesWidget : public QWidget
63-
{
64-
Q_OBJECT
65-
public:
66-
67-
/**
68-
* Constructor for QgsBrowserPropertiesWidget
69-
* \param parent parent widget
70-
*/
71-
explicit QgsBrowserPropertiesWidget( QWidget *parent = nullptr );
72-
//! Factory method to create a new browser widget
73-
static QgsBrowserPropertiesWidget *createWidget( QgsDataItem *item, QWidget *parent = nullptr ) SIP_FACTORY;
74-
//! Stub
75-
virtual void setItem( QgsDataItem *item ) { Q_UNUSED( item ) }
76-
//! Set content widget, usually item paramWidget. Takes ownership.
77-
virtual void setWidget( QWidget *widget );
78-
79-
/** Sets whether the properties widget should display in condensed mode, ie, for display in a dock
80-
* widget rather than it's own separate dialog.
81-
* \param condensedMode set to true to enable condensed mode
82-
* \since QGIS 2.10
83-
*/
84-
virtual void setCondensedMode( bool condensedMode ) { Q_UNUSED( condensedMode ); }
85-
};
86-
87-
/**
88-
* \ingroup gui
89-
* The QgsBrowserLayerProperties class
90-
* \since QGIS 2.10
91-
*/
92-
class GUI_EXPORT QgsBrowserLayerProperties : public QgsBrowserPropertiesWidget, private Ui::QgsBrowserLayerPropertiesBase
93-
{
94-
Q_OBJECT
95-
public:
96-
97-
/**
98-
* Constructor for QgsBrowserLayerProperties
99-
* \param parent parent widget
100-
*/
101-
explicit QgsBrowserLayerProperties( QWidget *parent = nullptr );
102-
//! Set item
103-
void setItem( QgsDataItem *item ) override;
104-
105-
/** Sets whether the properties widget should display in condensed mode, ie, for display in a dock
106-
* widget rather than it's own separate dialog.
107-
* \param condensedMode set to true to enable condensed mode
108-
* \since QGIS 2.10
109-
*/
110-
virtual void setCondensedMode( bool condensedMode ) override;
111-
112-
private:
113-
QgsBrowserPropertiesWrapLabel *mUriLabel = nullptr;
114-
};
115-
116-
/**
117-
* \ingroup gui
118-
* The QgsBrowserDirectoryProperties class
119-
* \since QGIS 2.10
120-
*/
121-
class GUI_EXPORT QgsBrowserDirectoryProperties : public QgsBrowserPropertiesWidget, private Ui::QgsBrowserDirectoryPropertiesBase
122-
{
123-
Q_OBJECT
124-
public:
125-
126-
/**
127-
* Constructor for QgsBrowserDirectoryProperties
128-
* \param parent parent widget
129-
*/
130-
explicit QgsBrowserDirectoryProperties( QWidget *parent = nullptr );
131-
132-
//! Create widget from the given item and add it
133-
void setItem( QgsDataItem *item ) override;
134-
private:
135-
QgsDirectoryParamWidget *mDirectoryWidget = nullptr;
136-
QgsBrowserPropertiesWrapLabel *mPathLabel = nullptr;
137-
};
138-
139-
/**
140-
* \ingroup gui
141-
* The QgsBrowserPropertiesDialog class
142-
* \since QGIS 2.10
143-
*/
144-
class GUI_EXPORT QgsBrowserPropertiesDialog : public QDialog, private Ui::QgsBrowserPropertiesDialogBase
145-
{
146-
Q_OBJECT
147-
public:
148-
149-
/**
150-
* Constructor for QgsBrowserPropertiesDialog
151-
* \param settingsSection prefix for settings (from the object name)
152-
* \param parent parent widget
153-
*/
154-
QgsBrowserPropertiesDialog( const QString &settingsSection, QWidget *parent = nullptr );
155-
~QgsBrowserPropertiesDialog();
156-
157-
//! Create dialog from the given item and add it
158-
void setItem( QgsDataItem *item );
159-
160-
private:
161-
QgsBrowserPropertiesWidget *mPropertiesWidget = nullptr;
162-
QString mSettingsSection;
163-
};
164-
16537
/**
16638
* \ingroup gui
16739
* The QgsBrowserDockWidget class
168-
* \since QGIS 2.10
40+
* \since QGIS 3.0
16941
*/
17042
class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBrowserDockWidgetBase
17143
{
@@ -177,7 +49,7 @@ class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBro
17749
* \param name name of the widget
17850
* \param parent parent widget
17951
*/
180-
explicit QgsBrowserDockWidget( const QString &name, QWidget *parent = nullptr );
52+
explicit QgsBrowserDockWidget( const QString &name, QWidget *parent SIP_TRANSFERTHIS = nullptr );
18153
~QgsBrowserDockWidget();
18254
//! Add directory to favorites
18355
void addFavoriteDirectory( const QString &favDir );
@@ -211,7 +83,6 @@ class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBro
21183
//! Update project home directory
21284
void updateProjectHome();
21385

214-
21586
//! Add selected layers to the project
21687
void addSelectedLayers();
21788
//! Show the layer properties
@@ -233,10 +104,12 @@ class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBro
233104
void handleDropUriList( const QgsMimeDataUtils::UriList & );
234105

235106
protected:
236-
//! Refresh the model
237-
void refreshModel( const QModelIndex &index );
238107
//! Show event override
239108
void showEvent( QShowEvent *event ) override;
109+
110+
private:
111+
//! Refresh the model
112+
void refreshModel( const QModelIndex &index );
240113
//! Add a layer
241114
void addLayer( QgsLayerItem *layerItem );
242115
//! Clear the properties widget
@@ -257,88 +130,8 @@ class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBro
257130
// height fraction
258131
float mPropertiesWidgetHeight;
259132

260-
private:
261-
};
262-
263-
264-
/**
265-
* \ingroup gui
266-
* Utility class for correct drag&drop handling.
267-
*
268-
* We want to allow user to drag layers to qgis window. At the same time we do not
269-
* accept drops of the items on our view - but if we ignore the drag enter action
270-
* then qgis application consumes the drag events and it is possible to drop the
271-
* items on the tree view although the drop is actually managed by qgis app.
272-
* \since QGIS 2.10
273-
*/
274-
class GUI_EXPORT QgsDockBrowserTreeView : public QgsBrowserTreeView
275-
{
276-
Q_OBJECT
277-
278-
public:
279-
280-
/**
281-
* Constructor for QgsDockBrowserTreeView
282-
* \param parent parent widget
283-
*/
284-
explicit QgsDockBrowserTreeView( QWidget *parent );
285-
//! Overrides drag enter event
286-
void dragEnterEvent( QDragEnterEvent *e ) override;
287-
//! Overrides drag move event
288-
void dragMoveEvent( QDragMoveEvent *e ) override;
289-
//! Overrides drag stop event
290-
void dropEvent( QDropEvent *e ) override;
291133
};
292134

293-
/**
294-
* \ingroup gui
295-
* Utility class for filtering browser items
296-
* \since QGIS 2.10
297-
*/
298-
class GUI_EXPORT QgsBrowserTreeFilterProxyModel : public QSortFilterProxyModel
299-
{
300-
Q_OBJECT
301-
public:
302-
303-
/**
304-
* Constructor for QgsBrowserTreeFilterProxyModel
305-
* @param parent parent widget
306-
*/
307-
explicit QgsBrowserTreeFilterProxyModel( QObject *parent );
308-
//! Set the browser model
309-
void setBrowserModel( QgsBrowserModel *model );
310-
//! Set the filter syntax
311-
void setFilterSyntax( const QString &syntax );
312-
//! Set the filter
313-
void setFilter( const QString &filter );
314-
//! Set case sensitivity
315-
void setCaseSensitive( bool caseSensitive );
316-
//! Update filter
317-
void updateFilter();
318-
319-
protected:
320-
321-
QgsBrowserModel *mModel = nullptr;
322-
QString mFilter; //filter string provided
323-
QVector<QRegExp> mREList; //list of filters, separated by "|"
324-
QString mPatternSyntax;
325-
Qt::CaseSensitivity mCaseSensitivity;
326-
327-
//! Filter accepts string
328-
bool filterAcceptsString( const QString &value ) const;
329-
330-
//! It would be better to apply the filer only to expanded (visible) items, but using mapFromSource() + view here was causing strange errors
331-
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
332-
333-
//! Returns true if at least one ancestor is accepted by filter
334-
bool filterAcceptsAncestor( const QModelIndex &sourceIndex ) const;
335-
336-
//! Returns true if at least one descendant s accepted by filter
337-
bool filterAcceptsDescendant( const QModelIndex &sourceIndex ) const;
338-
339-
//! Filter accepts item name
340-
bool filterAcceptsItem( const QModelIndex &sourceIndex ) const;
341-
};
342135

343136

344137
#endif // QGSBROWSERDOCKWIDGET_H

‎src/gui/qgsbrowserdockwidget_p.cpp

Lines changed: 483 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,483 @@
1+
/***************************************************************************
2+
qgsbrowserdockwidget_p.cpp
3+
4+
Private classes for QgsBrowserDockWidget
5+
6+
---------------------
7+
begin : May 2017
8+
copyright : (C) 2017 by Alessandro Pasotti
9+
real work done by : (C) 2011 by Martin Dobias
10+
email : a dot pasotti at itopen dot it
11+
---------------------
12+
***************************************************************************
13+
* *
14+
* This program is free software; you can redistribute it and/or modify *
15+
* it under the terms of the GNU General Public License as published by *
16+
* the Free Software Foundation; either version 2 of the License, or *
17+
* (at your option) any later version. *
18+
* *
19+
***************************************************************************/
20+
#include "qgsbrowserdockwidget_p.h"
21+
22+
#include <QAbstractTextDocumentLayout>
23+
#include <QHeaderView>
24+
#include <QTreeView>
25+
#include <QMenu>
26+
#include <QToolButton>
27+
#include <QFileDialog>
28+
#include <QPlainTextDocumentLayout>
29+
#include <QSortFilterProxyModel>
30+
31+
#include "qgsbrowsermodel.h"
32+
#include "qgsbrowsertreeview.h"
33+
#include "qgslogger.h"
34+
#include "qgsrasterlayer.h"
35+
#include "qgsvectorlayer.h"
36+
#include "qgsproject.h"
37+
#include "qgssettings.h"
38+
39+
40+
#include <QDragEnterEvent>
41+
42+
43+
/// @cond PRIVATE
44+
45+
46+
QgsBrowserPropertiesWrapLabel::QgsBrowserPropertiesWrapLabel( const QString &text, QWidget *parent )
47+
: QTextEdit( text, parent )
48+
{
49+
setReadOnly( true );
50+
setFrameStyle( QFrame::NoFrame );
51+
setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
52+
QPalette pal = palette();
53+
pal.setColor( QPalette::Base, Qt::transparent );
54+
setPalette( pal );
55+
setLineWrapMode( QTextEdit::WidgetWidth );
56+
setWordWrapMode( QTextOption::WrapAnywhere );
57+
connect( qobject_cast<QAbstractTextDocumentLayout *>( document()->documentLayout() ), &QAbstractTextDocumentLayout::documentSizeChanged,
58+
this, &QgsBrowserPropertiesWrapLabel::adjustHeight );
59+
setMaximumHeight( 20 );
60+
}
61+
62+
void QgsBrowserPropertiesWrapLabel::adjustHeight( QSizeF size )
63+
{
64+
int height = size.height() + 2 * frameWidth();
65+
setMinimumHeight( height );
66+
setMaximumHeight( height );
67+
}
68+
69+
QgsBrowserPropertiesWidget::QgsBrowserPropertiesWidget( QWidget *parent )
70+
: QWidget( parent )
71+
{
72+
}
73+
74+
void QgsBrowserPropertiesWidget::setWidget( QWidget *paramWidget )
75+
{
76+
QVBoxLayout *layout = new QVBoxLayout( this );
77+
paramWidget->setParent( this );
78+
layout->addWidget( paramWidget );
79+
}
80+
81+
QgsBrowserPropertiesWidget *QgsBrowserPropertiesWidget::createWidget( QgsDataItem *item, QWidget *parent )
82+
{
83+
QgsBrowserPropertiesWidget *propertiesWidget = nullptr;
84+
// In general, we would like to show all items' paramWidget, but top level items like
85+
// WMS etc. have currently too large widgets which do not fit well to browser properties widget
86+
if ( item->type() == QgsDataItem::Directory )
87+
{
88+
propertiesWidget = new QgsBrowserDirectoryProperties( parent );
89+
propertiesWidget->setItem( item );
90+
}
91+
else if ( item->type() == QgsDataItem::Layer )
92+
{
93+
// prefer item's widget over standard layer widget
94+
QWidget *paramWidget = item->paramWidget();
95+
if ( paramWidget )
96+
{
97+
propertiesWidget = new QgsBrowserPropertiesWidget( parent );
98+
propertiesWidget->setWidget( paramWidget );
99+
}
100+
else
101+
{
102+
propertiesWidget = new QgsBrowserLayerProperties( parent );
103+
propertiesWidget->setItem( item );
104+
}
105+
}
106+
return propertiesWidget;
107+
}
108+
109+
QgsBrowserLayerProperties::QgsBrowserLayerProperties( QWidget *parent )
110+
: QgsBrowserPropertiesWidget( parent )
111+
{
112+
setupUi( this );
113+
114+
mUriLabel = new QgsBrowserPropertiesWrapLabel( QString(), this );
115+
mHeaderGridLayout->addItem( new QWidgetItem( mUriLabel ), 1, 1 );
116+
}
117+
118+
void QgsBrowserLayerProperties::setItem( QgsDataItem *item )
119+
{
120+
QgsLayerItem *layerItem = qobject_cast<QgsLayerItem *>( item );
121+
if ( !layerItem )
122+
return;
123+
124+
mNoticeLabel->clear();
125+
126+
QgsMapLayer::LayerType type = layerItem->mapLayerType();
127+
QString layerMetadata = tr( "Error" );
128+
QgsCoordinateReferenceSystem layerCrs;
129+
130+
// temporarily override /Projections/defaultBehavior to avoid dialog prompt
131+
QgsSettings settings;
132+
QString defaultProjectionOption = settings.value( QStringLiteral( "Projections/defaultBehavior" ), "prompt" ).toString();
133+
if ( settings.value( QStringLiteral( "Projections/defaultBehavior" ), "prompt" ).toString() == QLatin1String( "prompt" ) )
134+
{
135+
settings.setValue( QStringLiteral( "Projections/defaultBehavior" ), "useProject" );
136+
}
137+
138+
// find root item
139+
// we need to create a temporary layer to get metadata
140+
// we could use a provider but the metadata is not as complete and "pretty" and this is easier
141+
QgsDebugMsg( QString( "creating temporary layer using path %1" ).arg( layerItem->path() ) );
142+
if ( type == QgsMapLayer::RasterLayer )
143+
{
144+
QgsDebugMsg( "creating raster layer" );
145+
// should copy code from addLayer() to split uri ?
146+
QgsRasterLayer *layer = new QgsRasterLayer( layerItem->uri(), layerItem->uri(), layerItem->providerKey() );
147+
if ( layer )
148+
{
149+
if ( layer->isValid() )
150+
{
151+
layerCrs = layer->crs();
152+
layerMetadata = layer->htmlMetadata();
153+
}
154+
delete layer;
155+
}
156+
}
157+
else if ( type == QgsMapLayer::VectorLayer )
158+
{
159+
QgsDebugMsg( "creating vector layer" );
160+
QgsVectorLayer *layer = new QgsVectorLayer( layerItem->uri(), layerItem->name(), layerItem->providerKey() );
161+
if ( layer )
162+
{
163+
if ( layer->isValid() )
164+
{
165+
layerCrs = layer->crs();
166+
layerMetadata = layer->htmlMetadata();
167+
}
168+
delete layer;
169+
}
170+
}
171+
else if ( type == QgsMapLayer::PluginLayer )
172+
{
173+
// TODO: support display of properties for plugin layers
174+
return;
175+
}
176+
177+
// restore /Projections/defaultBehavior
178+
if ( defaultProjectionOption == QLatin1String( "prompt" ) )
179+
{
180+
settings.setValue( QStringLiteral( "Projections/defaultBehavior" ), defaultProjectionOption );
181+
}
182+
183+
mNameLabel->setText( layerItem->name() );
184+
mUriLabel->setText( layerItem->uri() );
185+
mProviderLabel->setText( layerItem->providerKey() );
186+
QString myStyle = QgsApplication::reportStyleSheet();
187+
mMetadataTextBrowser->document()->setDefaultStyleSheet( myStyle );
188+
mMetadataTextBrowser->setHtml( layerMetadata );
189+
190+
// report if layer was set to to project crs without prompt (may give a false positive)
191+
if ( defaultProjectionOption == QLatin1String( "prompt" ) )
192+
{
193+
QgsCoordinateReferenceSystem defaultCrs =
194+
QgsProject::instance()->crs();
195+
if ( layerCrs == defaultCrs )
196+
mNoticeLabel->setText( "NOTICE: Layer srs set from project (" + defaultCrs.authid() + ')' );
197+
}
198+
199+
if ( mNoticeLabel->text().isEmpty() )
200+
{
201+
mNoticeLabel->hide();
202+
}
203+
}
204+
205+
void QgsBrowserLayerProperties::setCondensedMode( bool condensedMode )
206+
{
207+
if ( condensedMode )
208+
{
209+
mUriLabel->setLineWrapMode( QTextEdit::NoWrap );
210+
mUriLabel->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
211+
mUriLabel->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
212+
}
213+
else
214+
{
215+
mUriLabel->setLineWrapMode( QTextEdit::WidgetWidth );
216+
mUriLabel->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
217+
mUriLabel->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
218+
}
219+
}
220+
221+
QgsBrowserDirectoryProperties::QgsBrowserDirectoryProperties( QWidget *parent )
222+
: QgsBrowserPropertiesWidget( parent )
223+
, mDirectoryWidget( nullptr )
224+
{
225+
setupUi( this );
226+
227+
mPathLabel = new QgsBrowserPropertiesWrapLabel( QString(), mHeaderWidget );
228+
mHeaderGridLayout->addItem( new QWidgetItem( mPathLabel ), 0, 1 );
229+
}
230+
231+
void QgsBrowserDirectoryProperties::setItem( QgsDataItem *item )
232+
{
233+
QgsDirectoryItem *directoryItem = qobject_cast<QgsDirectoryItem *>( item );
234+
if ( !item )
235+
return;
236+
237+
mPathLabel->setText( directoryItem->dirPath() );
238+
mDirectoryWidget = new QgsDirectoryParamWidget( directoryItem->dirPath(), this );
239+
mLayout->addWidget( mDirectoryWidget );
240+
}
241+
242+
QgsBrowserPropertiesDialog::QgsBrowserPropertiesDialog( const QString &settingsSection, QWidget *parent )
243+
: QDialog( parent )
244+
, mPropertiesWidget( nullptr )
245+
, mSettingsSection( settingsSection )
246+
{
247+
setupUi( this );
248+
QgsSettings settings;
249+
restoreGeometry( settings.value( mSettingsSection + "/propertiesDialog/geometry" ).toByteArray() );
250+
}
251+
252+
QgsBrowserPropertiesDialog::~QgsBrowserPropertiesDialog()
253+
{
254+
QgsSettings settings;
255+
settings.setValue( mSettingsSection + "/propertiesDialog/geometry", saveGeometry() );
256+
}
257+
258+
void QgsBrowserPropertiesDialog::setItem( QgsDataItem *item )
259+
{
260+
if ( !item )
261+
return;
262+
263+
mPropertiesWidget = QgsBrowserPropertiesWidget::createWidget( item, this );
264+
mLayout->addWidget( mPropertiesWidget );
265+
setWindowTitle( item->type() == QgsDataItem::Layer ? tr( "Layer Properties" ) : tr( "Directory Properties" ) );
266+
}
267+
268+
269+
//
270+
// QgsDockBrowserTreeView
271+
//
272+
273+
QgsDockBrowserTreeView::QgsDockBrowserTreeView( QWidget *parent ) : QgsBrowserTreeView( parent )
274+
{
275+
setDragDropMode( QTreeView::DragDrop ); // sets also acceptDrops + dragEnabled
276+
setSelectionMode( QAbstractItemView::ExtendedSelection );
277+
setContextMenuPolicy( Qt::CustomContextMenu );
278+
setHeaderHidden( true );
279+
setDropIndicatorShown( true );
280+
281+
}
282+
283+
void QgsDockBrowserTreeView::dragEnterEvent( QDragEnterEvent *e )
284+
{
285+
// if this mime data come from layer tree, the proposed action will be MoveAction
286+
// but for browser we really need CopyAction
287+
if ( e->mimeData()->hasFormat( QStringLiteral( "application/qgis.layertreemodeldata" ) ) &&
288+
e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
289+
e->setDropAction( Qt::CopyAction );
290+
291+
// accept drag enter so that our widget will not get ignored
292+
// and drag events will not get passed to QgisApp
293+
e->accept();
294+
}
295+
296+
void QgsDockBrowserTreeView::dragMoveEvent( QDragMoveEvent *e )
297+
{
298+
// do not accept drops above/below items
299+
/*if ( dropIndicatorPosition() != QAbstractItemView::OnItem )
300+
{
301+
QgsDebugMsg("drag not on item");
302+
e->ignore();
303+
return;
304+
}*/
305+
306+
// if this mime data come from layer tree, the proposed action will be MoveAction
307+
// but for browser we really need CopyAction
308+
if ( e->mimeData()->hasFormat( QStringLiteral( "application/qgis.layertreemodeldata" ) ) &&
309+
e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
310+
e->setDropAction( Qt::CopyAction );
311+
312+
QTreeView::dragMoveEvent( e );
313+
314+
if ( !e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
315+
{
316+
e->ignore();
317+
return;
318+
}
319+
}
320+
321+
void QgsDockBrowserTreeView::dropEvent( QDropEvent *e )
322+
{
323+
// if this mime data come from layer tree, the proposed action will be MoveAction
324+
// but for browser we really need CopyAction
325+
if ( e->mimeData()->hasFormat( QStringLiteral( "application/qgis.layertreemodeldata" ) ) &&
326+
e->mimeData()->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.uri" ) ) )
327+
e->setDropAction( Qt::CopyAction );
328+
329+
QTreeView::dropEvent( e );
330+
}
331+
332+
333+
//
334+
// QgsBrowserTreeFilterProxyModel
335+
//
336+
337+
QgsBrowserTreeFilterProxyModel::QgsBrowserTreeFilterProxyModel( QObject *parent )
338+
: QSortFilterProxyModel( parent )
339+
, mModel( nullptr )
340+
, mPatternSyntax( QStringLiteral( "normal" ) )
341+
, mCaseSensitivity( Qt::CaseInsensitive )
342+
{
343+
setDynamicSortFilter( true );
344+
}
345+
346+
void QgsBrowserTreeFilterProxyModel::setBrowserModel( QgsBrowserModel *model )
347+
{
348+
mModel = model;
349+
setSourceModel( model );
350+
}
351+
352+
void QgsBrowserTreeFilterProxyModel::setFilterSyntax( const QString &syntax )
353+
{
354+
QgsDebugMsg( QString( "syntax = %1" ).arg( syntax ) );
355+
if ( mPatternSyntax == syntax )
356+
return;
357+
mPatternSyntax = syntax;
358+
updateFilter();
359+
}
360+
361+
void QgsBrowserTreeFilterProxyModel::setFilter( const QString &filter )
362+
{
363+
QgsDebugMsg( QString( "filter = %1" ).arg( mFilter ) );
364+
if ( mFilter == filter )
365+
return;
366+
mFilter = filter;
367+
updateFilter();
368+
}
369+
370+
void QgsBrowserTreeFilterProxyModel::setCaseSensitive( bool caseSensitive )
371+
{
372+
mCaseSensitivity = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
373+
updateFilter();
374+
}
375+
376+
void QgsBrowserTreeFilterProxyModel::updateFilter()
377+
{
378+
QgsDebugMsg( QString( "filter = %1 syntax = %2" ).arg( mFilter, mPatternSyntax ) );
379+
mREList.clear();
380+
if ( mPatternSyntax == QLatin1String( "normal" ) )
381+
{
382+
Q_FOREACH ( const QString &f, mFilter.split( '|' ) )
383+
{
384+
QRegExp rx( QString( "*%1*" ).arg( f.trimmed() ) );
385+
rx.setPatternSyntax( QRegExp::Wildcard );
386+
rx.setCaseSensitivity( mCaseSensitivity );
387+
mREList.append( rx );
388+
}
389+
}
390+
else if ( mPatternSyntax == QLatin1String( "wildcard" ) )
391+
{
392+
Q_FOREACH ( const QString &f, mFilter.split( '|' ) )
393+
{
394+
QRegExp rx( f.trimmed() );
395+
rx.setPatternSyntax( QRegExp::Wildcard );
396+
rx.setCaseSensitivity( mCaseSensitivity );
397+
mREList.append( rx );
398+
}
399+
}
400+
else
401+
{
402+
QRegExp rx( mFilter.trimmed() );
403+
rx.setPatternSyntax( QRegExp::RegExp );
404+
rx.setCaseSensitivity( mCaseSensitivity );
405+
mREList.append( rx );
406+
}
407+
invalidateFilter();
408+
}
409+
410+
bool QgsBrowserTreeFilterProxyModel::filterAcceptsString( const QString &value ) const
411+
{
412+
if ( mPatternSyntax == QLatin1String( "normal" ) || mPatternSyntax == QLatin1String( "wildcard" ) )
413+
{
414+
Q_FOREACH ( const QRegExp &rx, mREList )
415+
{
416+
QgsDebugMsg( QString( "value: [%1] rx: [%2] match: %3" ).arg( value, rx.pattern() ).arg( rx.exactMatch( value ) ) );
417+
if ( rx.exactMatch( value ) )
418+
return true;
419+
}
420+
}
421+
else
422+
{
423+
Q_FOREACH ( const QRegExp &rx, mREList )
424+
{
425+
QgsDebugMsg( QString( "value: [%1] rx: [%2] match: %3" ).arg( value, rx.pattern() ).arg( rx.indexIn( value ) ) );
426+
if ( rx.indexIn( value ) != -1 )
427+
return true;
428+
}
429+
}
430+
return false;
431+
}
432+
433+
bool QgsBrowserTreeFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
434+
{
435+
if ( mFilter.isEmpty() || !mModel )
436+
return true;
437+
438+
QModelIndex sourceIndex = mModel->index( sourceRow, 0, sourceParent );
439+
return filterAcceptsItem( sourceIndex ) || filterAcceptsAncestor( sourceIndex ) || filterAcceptsDescendant( sourceIndex );
440+
}
441+
442+
bool QgsBrowserTreeFilterProxyModel::filterAcceptsAncestor( const QModelIndex &sourceIndex ) const
443+
{
444+
if ( !mModel )
445+
return true;
446+
447+
QModelIndex sourceParentIndex = mModel->parent( sourceIndex );
448+
if ( !sourceParentIndex.isValid() )
449+
return false;
450+
if ( filterAcceptsItem( sourceParentIndex ) )
451+
return true;
452+
453+
return filterAcceptsAncestor( sourceParentIndex );
454+
}
455+
456+
bool QgsBrowserTreeFilterProxyModel::filterAcceptsDescendant( const QModelIndex &sourceIndex ) const
457+
{
458+
if ( !mModel )
459+
return true;
460+
461+
for ( int i = 0; i < mModel->rowCount( sourceIndex ); i++ )
462+
{
463+
QgsDebugMsg( QString( "i = %1" ).arg( i ) );
464+
QModelIndex sourceChildIndex = mModel->index( i, 0, sourceIndex );
465+
if ( filterAcceptsItem( sourceChildIndex ) )
466+
return true;
467+
if ( filterAcceptsDescendant( sourceChildIndex ) )
468+
return true;
469+
}
470+
return false;
471+
}
472+
473+
bool QgsBrowserTreeFilterProxyModel::filterAcceptsItem( const QModelIndex &sourceIndex ) const
474+
{
475+
if ( !mModel )
476+
return true;
477+
//accept item if either displayed text or comment role matches string
478+
QString comment = mModel->data( sourceIndex, QgsBrowserModel::CommentRole ).toString();
479+
return ( filterAcceptsString( mModel->data( sourceIndex, Qt::DisplayRole ).toString() )
480+
|| ( !comment.isEmpty() && filterAcceptsString( comment ) ) );
481+
}
482+
483+
///@endcond

‎src/gui/qgsbrowserdockwidget_p.h

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/***************************************************************************
2+
qgsbrowserdockwidget_p.h
3+
4+
Private classes for QgsBrowserDockWidget
5+
6+
---------------------
7+
begin : May 2017
8+
copyright : (C) 2017 by Alessandro Pasotti
9+
real work done by : (C) 2011 by Martin Dobias
10+
email : a dot pasotti at itopen dot it
11+
***************************************************************************
12+
* *
13+
* This program is free software; you can redistribute it and/or modify *
14+
* it under the terms of the GNU General Public License as published by *
15+
* the Free Software Foundation; either version 2 of the License, or *
16+
* (at your option) any later version. *
17+
* *
18+
***************************************************************************/
19+
20+
21+
#ifndef QGSBROWSERDOCKWIDGET_P_H
22+
#define QGSBROWSERDOCKWIDGET_P_H
23+
24+
/// @cond PRIVATE
25+
26+
//
27+
// W A R N I N G
28+
// -------------
29+
//
30+
// This file is not part of the QGIS API. It exists purely as an
31+
// implementation detail. This header file may change from version to
32+
// version without notice, or even be removed.
33+
//
34+
35+
36+
#include <ui_qgsbrowserdockwidgetbase.h>
37+
#include <ui_qgsbrowserlayerpropertiesbase.h>
38+
#include <ui_qgsbrowserdirectorypropertiesbase.h>
39+
#include <ui_qgsbrowserpropertiesdialogbase.h>
40+
41+
#include "qgsdataitem.h"
42+
#include "qgsbrowsertreeview.h"
43+
#include "qgsdockwidget.h"
44+
#include <QSortFilterProxyModel>
45+
46+
class QgsBrowserModel;
47+
class QModelIndex;
48+
class QgsDockBrowserTreeView;
49+
class QgsLayerItem;
50+
class QgsDataItem;
51+
class QgsBrowserTreeFilterProxyModel;
52+
53+
/**
54+
* Hack to show wrapped text without spaces
55+
*/
56+
class QgsBrowserPropertiesWrapLabel : public QTextEdit
57+
{
58+
Q_OBJECT
59+
public:
60+
61+
/**
62+
* Constructor for QgsBrowserPropertiesWrapLabel
63+
* \param text label text
64+
* \param parent parent widget
65+
*/
66+
QgsBrowserPropertiesWrapLabel( const QString &text, QWidget *parent = nullptr );
67+
68+
private slots:
69+
void adjustHeight( QSizeF size );
70+
};
71+
72+
/**
73+
* The QgsBrowserPropertiesWidget base class
74+
*/
75+
class QgsBrowserPropertiesWidget : public QWidget
76+
{
77+
Q_OBJECT
78+
public:
79+
80+
/**
81+
* Constructor for QgsBrowserPropertiesWidget
82+
* \param parent parent widget
83+
*/
84+
explicit QgsBrowserPropertiesWidget( QWidget *parent = nullptr );
85+
//! Factory method to create a new browser properties widget
86+
static QgsBrowserPropertiesWidget *createWidget( QgsDataItem *item, QWidget *parent = nullptr );
87+
//! Stub
88+
virtual void setItem( QgsDataItem *item ) { Q_UNUSED( item ) }
89+
//! Set content widget, usually item paramWidget. Takes ownership.
90+
virtual void setWidget( QWidget *widget );
91+
92+
/** Sets whether the properties widget should display in condensed mode, ie, for display in a dock
93+
* widget rather than it's own separate dialog.
94+
* \param condensedMode set to true to enable condensed mode
95+
* \since QGIS 2.10
96+
*/
97+
virtual void setCondensedMode( bool condensedMode ) { Q_UNUSED( condensedMode ); }
98+
};
99+
100+
/**
101+
* The QgsBrowserLayerProperties class
102+
*/
103+
class QgsBrowserLayerProperties : public QgsBrowserPropertiesWidget, private Ui::QgsBrowserLayerPropertiesBase
104+
{
105+
Q_OBJECT
106+
public:
107+
108+
/**
109+
* Constructor for QgsBrowserLayerProperties
110+
* \param parent parent widget
111+
*/
112+
explicit QgsBrowserLayerProperties( QWidget *parent = nullptr );
113+
//! Set item
114+
void setItem( QgsDataItem *item ) override;
115+
116+
/** Sets whether the properties widget should display in condensed mode, ie, for display in a dock
117+
* widget rather than it's own separate dialog.
118+
* \param condensedMode set to true to enable condensed mode
119+
* \since QGIS 2.10
120+
*/
121+
virtual void setCondensedMode( bool condensedMode ) override;
122+
123+
private:
124+
QgsBrowserPropertiesWrapLabel *mUriLabel = nullptr;
125+
};
126+
127+
/**
128+
* The QgsBrowserDirectoryProperties class
129+
*/
130+
class QgsBrowserDirectoryProperties : public QgsBrowserPropertiesWidget, private Ui::QgsBrowserDirectoryPropertiesBase
131+
{
132+
Q_OBJECT
133+
public:
134+
135+
/**
136+
* Constructor for QgsBrowserDirectoryProperties
137+
* \param parent parent widget
138+
*/
139+
explicit QgsBrowserDirectoryProperties( QWidget *parent = nullptr );
140+
141+
//! Create widget from the given item and add it
142+
void setItem( QgsDataItem *item ) override;
143+
private:
144+
QgsDirectoryParamWidget *mDirectoryWidget = nullptr;
145+
QgsBrowserPropertiesWrapLabel *mPathLabel = nullptr;
146+
};
147+
148+
/**
149+
* The QgsBrowserPropertiesDialog class
150+
*/
151+
class QgsBrowserPropertiesDialog : public QDialog, private Ui::QgsBrowserPropertiesDialogBase
152+
{
153+
Q_OBJECT
154+
public:
155+
156+
/**
157+
* Constructor for QgsBrowserPropertiesDialog
158+
* \param settingsSection prefix for settings (from the object name)
159+
* \param parent parent widget
160+
*/
161+
QgsBrowserPropertiesDialog( const QString &settingsSection, QWidget *parent = nullptr );
162+
~QgsBrowserPropertiesDialog();
163+
164+
//! Create dialog from the given item and add it
165+
void setItem( QgsDataItem *item );
166+
167+
private:
168+
QgsBrowserPropertiesWidget *mPropertiesWidget = nullptr;
169+
QString mSettingsSection;
170+
};
171+
172+
173+
/**
174+
* Utility class for correct drag&drop handling.
175+
*
176+
* We want to allow user to drag layers to qgis window. At the same time we do not
177+
* accept drops of the items on our view - but if we ignore the drag enter action
178+
* then qgis application consumes the drag events and it is possible to drop the
179+
* items on the tree view although the drop is actually managed by qgis app.
180+
*/
181+
class QgsDockBrowserTreeView : public QgsBrowserTreeView
182+
{
183+
Q_OBJECT
184+
185+
public:
186+
187+
/**
188+
* Constructor for QgsDockBrowserTreeView
189+
* \param parent parent widget
190+
*/
191+
explicit QgsDockBrowserTreeView( QWidget *parent );
192+
//! Overrides drag enter event
193+
void dragEnterEvent( QDragEnterEvent *e ) override;
194+
//! Overrides drag move event
195+
void dragMoveEvent( QDragMoveEvent *e ) override;
196+
//! Overrides drag stop event
197+
void dropEvent( QDropEvent *e ) override;
198+
};
199+
200+
/**
201+
* Utility class for filtering browser items
202+
*/
203+
class QgsBrowserTreeFilterProxyModel : public QSortFilterProxyModel
204+
{
205+
Q_OBJECT
206+
public:
207+
208+
/**
209+
* Constructor for QgsBrowserTreeFilterProxyModel
210+
* @param parent parent widget
211+
*/
212+
explicit QgsBrowserTreeFilterProxyModel( QObject *parent );
213+
//! Set the browser model
214+
void setBrowserModel( QgsBrowserModel *model );
215+
//! Set the filter syntax
216+
void setFilterSyntax( const QString &syntax );
217+
//! Set the filter
218+
void setFilter( const QString &filter );
219+
//! Set case sensitivity
220+
void setCaseSensitive( bool caseSensitive );
221+
//! Update filter
222+
void updateFilter();
223+
224+
protected:
225+
226+
QgsBrowserModel *mModel = nullptr;
227+
QString mFilter; //filter string provided
228+
QVector<QRegExp> mREList; //list of filters, separated by "|"
229+
QString mPatternSyntax;
230+
Qt::CaseSensitivity mCaseSensitivity;
231+
232+
//! Filter accepts string
233+
bool filterAcceptsString( const QString &value ) const;
234+
235+
//! It would be better to apply the filer only to expanded (visible) items, but using mapFromSource() + view here was causing strange errors
236+
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
237+
238+
//! Returns true if at least one ancestor is accepted by filter
239+
bool filterAcceptsAncestor( const QModelIndex &sourceIndex ) const;
240+
241+
//! Returns true if at least one descendant s accepted by filter
242+
bool filterAcceptsDescendant( const QModelIndex &sourceIndex ) const;
243+
244+
//! Filter accepts item name
245+
bool filterAcceptsItem( const QModelIndex &sourceIndex ) const;
246+
};
247+
248+
249+
/// @endcond
250+
251+
#endif // QGSBROWSERDOCKWIDGET_P_H

0 commit comments

Comments
 (0)
Please sign in to comment.