26 #include <QMessageBox>
42 if ( !layout || mLayouts.contains( layout ) )
48 if ( l->name() == layout->
name() )
63 else if ( QgsReport *r =
dynamic_cast< QgsReport *
>( layout ) )
65 connect( r, &QgsReport::nameChanged,
this, [
this, r](
const QString & newName )
83 if ( !mLayouts.contains( layout ) )
86 QString name = layout->
name();
88 mLayouts.removeAll( layout );
97 const QList< QgsMasterLayoutInterface * >
layouts = mLayouts;
111 QList<QgsPrintLayout *> result;
112 const QList<QgsMasterLayoutInterface *> _layouts( mLayouts );
113 result.reserve( _layouts.size() );
114 for (
const auto &layout : _layouts )
118 result.push_back( _item );
127 if ( l->name() == name )
137 QDomElement layoutsElem = element;
138 if ( element.tagName() != QStringLiteral(
"Layouts" ) )
140 layoutsElem = element.firstChildElement( QStringLiteral(
"Layouts" ) );
142 if ( layoutsElem.isNull() )
145 layoutsElem = doc.documentElement();
150 QDomNodeList composerNodes = element.elementsByTagName( QStringLiteral(
"Composer" ) );
151 for (
int i = 0; i < composerNodes.size(); ++i )
154 QString legacyTitle = composerNodes.at( i ).toElement().attribute( QStringLiteral(
"title" ) );
156 QDomNodeList compositionNodes = composerNodes.at( i ).toElement().elementsByTagName( QStringLiteral(
"Composition" ) );
157 for (
int j = 0; j < compositionNodes.size(); ++j )
162 if ( l->name().isEmpty() )
163 l->setName( legacyTitle );
168 bool isDuplicateName =
false;
169 QString originalName = l->name();
172 isDuplicateName =
false;
175 if ( l->name() == layout->name() )
177 isDuplicateName =
true;
181 if ( isDuplicateName )
183 l->setName( QStringLiteral(
"%1 %2" ).arg( originalName ).arg(
id ) );
187 while ( isDuplicateName );
190 result = added && result;
199 const QDomNodeList layoutNodes = layoutsElem.childNodes();
200 for (
int i = 0; i < layoutNodes.size(); ++i )
202 if ( layoutNodes.at( i ).nodeName() != QStringLiteral(
"Layout" ) )
205 std::unique_ptr< QgsPrintLayout > l = qgis::make_unique< QgsPrintLayout >( mProject );
206 l->undoStack()->blockCommands(
true );
207 if ( !l->readLayoutXml( layoutNodes.at( i ).toElement(), doc, context ) )
212 l->undoStack()->blockCommands(
false );
219 const QDomNodeList reportNodes = element.elementsByTagName( QStringLiteral(
"Report" ) );
220 for (
int i = 0; i < reportNodes.size(); ++i )
222 std::unique_ptr< QgsReport > r = qgis::make_unique< QgsReport >( mProject );
223 if ( !r->readLayoutXml( reportNodes.at( i ).toElement(), doc, context ) )
238 QDomElement layoutsElem = doc.createElement( QStringLiteral(
"Layouts" ) );
244 QDomElement layoutElem = l->writeLayoutXml( doc, context );
245 layoutsElem.appendChild( layoutElem );
255 std::unique_ptr< QgsMasterLayoutInterface > newLayout( layout->
clone() );
261 newLayout->setName( newName );
276 names.reserve( mLayouts.size() );
283 while ( name.isEmpty() || names.contains( name ) )
288 name = tr(
"Layout %1" ).arg(
id );
291 name = tr(
"Report %1" ).arg(
id );
301 if ( mLayouts.empty() )
310 if ( !l->layoutAccept( visitor ) )
327 : QAbstractListModel( parent )
328 , mLayoutManager( manager )
340 return ( mLayoutManager ? mLayoutManager->
layouts().count() : 0 ) + ( mAllowEmpty ? 1 : 0 );
345 if ( index.row() < 0 || index.row() >=
rowCount( QModelIndex() ) )
348 const bool isEmpty = index.row() == 0 && mAllowEmpty;
349 const int layoutRow = mAllowEmpty ? index.row() - 1 : index.row();
353 case Qt::DisplayRole:
354 case Qt::ToolTipRole:
356 return !isEmpty && mLayoutManager ? mLayoutManager->
layouts().at( layoutRow )->name() : QVariant();
360 if ( isEmpty || !mLayoutManager )
363 return QVariant::fromValue( l );
364 else if ( QgsReport *r =
dynamic_cast< QgsReport *
>( mLayoutManager->
layouts().at( layoutRow ) ) )
365 return QVariant::fromValue( r );
370 case Qt::DecorationRole:
372 return isEmpty || !mLayoutManager ? QIcon() : mLayoutManager->
layouts().at( layoutRow )->icon();
382 if ( !index.isValid() || role != Qt::EditRole )
386 if ( index.row() >= mLayoutManager->
layouts().count() )
391 if ( index.row() == 0 && mAllowEmpty )
394 if ( value.toString().isEmpty() )
402 bool changed = layout->
name() != value.toString();
407 QStringList layoutNames;
411 layoutNames << l->name();
413 if ( layoutNames.contains( value.toString() ) )
416 QMessageBox::warning(
nullptr, tr(
"Rename Layout" ), tr(
"There is already a layout named “%1”." ).arg( value.toString() ) );
420 layout->
setName( value.toString() );
426 Qt::ItemFlags
flags = QAbstractListModel::flags( index );
427 #if 0 // double-click is now used for opening the layout
428 if ( index.isValid() )
430 return flags | Qt::ItemIsEditable;
442 if ( index.row() == 0 && mAllowEmpty )
447 else if ( QgsReport *r = qobject_cast< QgsReport * >( qvariant_cast<QObject *>(
data( index,
LayoutRole ) ) ) )
455 if ( !mLayoutManager )
457 return QModelIndex();
460 const int r = mLayoutManager->
layouts().indexOf( layout );
462 return QModelIndex();
464 QModelIndex idx = index( mAllowEmpty ? r + 1 : r, 0, QModelIndex() );
470 return QModelIndex();
475 if ( allowEmpty == mAllowEmpty )
480 beginInsertRows( QModelIndex(), 0, 0 );
486 beginRemoveRows( QModelIndex(), 0, 0 );
492 void QgsLayoutManagerModel::layoutAboutToBeAdded(
const QString & )
494 int row = mLayoutManager->
layouts().count() + ( mAllowEmpty ? 1 : 0 );
495 beginInsertRows( QModelIndex(), row, row );
498 void QgsLayoutManagerModel::layoutAboutToBeRemoved(
const QString &name )
501 int row = mLayoutManager->
layouts().indexOf( l ) + ( mAllowEmpty ? 1 : 0 );
503 beginRemoveRows( QModelIndex(), row, row );
506 void QgsLayoutManagerModel::layoutAdded(
const QString & )
511 void QgsLayoutManagerModel::layoutRemoved(
const QString & )
518 int row = mLayoutManager->
layouts().indexOf( layout ) + ( mAllowEmpty ? 1 : 0 );
519 QModelIndex index = createIndex( row, 0 );
520 emit dataChanged( index, index, QVector<int>() << Qt::DisplayRole );
528 : QSortFilterProxyModel( parent )
530 setDynamicSortFilter(
true );
532 setSortCaseSensitivity( Qt::CaseInsensitive );
537 const QString leftText = sourceModel()->data( left, Qt::DisplayRole ).toString();
538 const QString rightText = sourceModel()->data( right, Qt::DisplayRole ).toString();
539 if ( leftText.isEmpty() )
541 if ( rightText.isEmpty() )
544 return QString::localeAwareCompare( leftText, rightText ) < 0;
557 if ( !mFilterString.trimmed().isEmpty() )
559 if ( !layout->
name().contains( mFilterString, Qt::CaseInsensitive ) )
586 mFilterString = filter;