27 #include <QMessageBox>
43 if ( !layout || mLayouts.contains( layout ) )
49 if ( l->name() == layout->
name() )
64 else if ( QgsReport *r =
dynamic_cast< QgsReport *
>( layout ) )
66 connect( r, &QgsReport::nameChanged,
this, [
this, r](
const QString & newName )
84 if ( !mLayouts.contains( layout ) )
87 QString name = layout->
name();
89 mLayouts.removeAll( layout );
98 const QList< QgsMasterLayoutInterface * >
layouts = mLayouts;
112 QList<QgsPrintLayout *> result;
113 const QList<QgsMasterLayoutInterface *> _layouts( mLayouts );
114 result.reserve( _layouts.size() );
115 for (
const auto &layout : _layouts )
119 result.push_back( _item );
128 if ( l->name() == name )
138 QDomElement layoutsElem = element;
139 if ( element.tagName() != QLatin1String(
"Layouts" ) )
141 layoutsElem = element.firstChildElement( QStringLiteral(
"Layouts" ) );
143 if ( layoutsElem.isNull() )
146 layoutsElem = doc.documentElement();
151 QDomNodeList composerNodes = element.elementsByTagName( QStringLiteral(
"Composer" ) );
153 for (
int i = 0; i < composerNodes.size(); ++i )
156 QString legacyTitle = composerNodes.at( i ).toElement().attribute( QStringLiteral(
"title" ) );
158 QDomNodeList compositionNodes = composerNodes.at( i ).toElement().elementsByTagName( QStringLiteral(
"Composition" ) );
159 for (
int j = 0; j < compositionNodes.size(); ++j )
164 if ( l->name().isEmpty() )
165 l->setName( legacyTitle );
170 bool isDuplicateName =
false;
171 QString originalName = l->name();
174 isDuplicateName =
false;
177 if ( l->name() == layout->name() )
179 isDuplicateName =
true;
183 if ( isDuplicateName )
185 l->setName( QStringLiteral(
"%1 %2" ).arg( originalName ).arg(
id ) );
189 while ( isDuplicateName );
192 result = added && result;
200 profile.
switchTask( tr(
"Creating layouts" ) );
203 const QDomNodeList layoutNodes = layoutsElem.childNodes();
204 for (
int i = 0; i < layoutNodes.size(); ++i )
206 if ( layoutNodes.at( i ).nodeName() != QLatin1String(
"Layout" ) )
209 const QString layoutName = layoutNodes.at( i ).toElement().attribute( QStringLiteral(
"name" ) );
212 std::unique_ptr< QgsPrintLayout > l = std::make_unique< QgsPrintLayout >( mProject );
213 l->undoStack()->blockCommands(
true );
214 if ( !l->readLayoutXml( layoutNodes.at( i ).toElement(), doc, context ) )
219 l->undoStack()->blockCommands(
false );
226 profile.
switchTask( tr(
"Creating reports" ) );
227 const QDomNodeList reportNodes = element.elementsByTagName( QStringLiteral(
"Report" ) );
228 for (
int i = 0; i < reportNodes.size(); ++i )
230 const QString layoutName = reportNodes.at( i ).toElement().attribute( QStringLiteral(
"name" ) );
233 std::unique_ptr< QgsReport > r = std::make_unique< QgsReport >( mProject );
234 if ( !r->readLayoutXml( reportNodes.at( i ).toElement(), doc, context ) )
249 QDomElement layoutsElem = doc.createElement( QStringLiteral(
"Layouts" ) );
255 QDomElement layoutElem = l->writeLayoutXml( doc, context );
256 layoutsElem.appendChild( layoutElem );
266 std::unique_ptr< QgsMasterLayoutInterface > newLayout( layout->
clone() );
272 newLayout->setName( newName );
287 names.reserve( mLayouts.size() );
294 while ( name.isEmpty() || names.contains( name ) )
299 name = tr(
"Layout %1" ).arg(
id );
302 name = tr(
"Report %1" ).arg(
id );
312 if ( mLayouts.empty() )
321 if ( !l->layoutAccept( visitor ) )
338 : QAbstractListModel( parent )
339 , mLayoutManager( manager )
351 return ( mLayoutManager ? mLayoutManager->
layouts().count() : 0 ) + ( mAllowEmpty ? 1 : 0 );
356 if ( index.row() < 0 || index.row() >=
rowCount( QModelIndex() ) )
359 const bool isEmpty = index.row() == 0 && mAllowEmpty;
360 const int layoutRow = mAllowEmpty ? index.row() - 1 : index.row();
364 case Qt::DisplayRole:
365 case Qt::ToolTipRole:
367 return !isEmpty && mLayoutManager ? mLayoutManager->
layouts().at( layoutRow )->name() : QVariant();
371 if ( isEmpty || !mLayoutManager )
374 return QVariant::fromValue( l );
375 else if ( QgsReport *r =
dynamic_cast< QgsReport *
>( mLayoutManager->
layouts().at( layoutRow ) ) )
376 return QVariant::fromValue( r );
381 case Qt::DecorationRole:
383 return isEmpty || !mLayoutManager ? QIcon() : mLayoutManager->
layouts().at( layoutRow )->icon();
393 if ( !index.isValid() || role != Qt::EditRole )
397 if ( index.row() >= mLayoutManager->
layouts().count() )
402 if ( index.row() == 0 && mAllowEmpty )
405 if ( value.toString().isEmpty() )
413 bool changed = layout->
name() != value.toString();
418 QStringList layoutNames;
422 layoutNames << l->name();
424 if ( layoutNames.contains( value.toString() ) )
427 QMessageBox::warning(
nullptr, tr(
"Rename Layout" ), tr(
"There is already a layout named “%1”." ).arg( value.toString() ) );
431 layout->
setName( value.toString() );
437 Qt::ItemFlags
flags = QAbstractListModel::flags( index );
438 #if 0 // double-click is now used for opening the layout
439 if ( index.isValid() )
441 return flags | Qt::ItemIsEditable;
453 if ( index.row() == 0 && mAllowEmpty )
458 else if ( QgsReport *r = qobject_cast< QgsReport * >( qvariant_cast<QObject *>(
data( index,
LayoutRole ) ) ) )
466 if ( !mLayoutManager )
468 return QModelIndex();
471 const int r = mLayoutManager->
layouts().indexOf( layout );
473 return QModelIndex();
475 QModelIndex idx = index( mAllowEmpty ? r + 1 : r, 0, QModelIndex() );
481 return QModelIndex();
486 if ( allowEmpty == mAllowEmpty )
491 beginInsertRows( QModelIndex(), 0, 0 );
497 beginRemoveRows( QModelIndex(), 0, 0 );
503 void QgsLayoutManagerModel::layoutAboutToBeAdded(
const QString & )
505 int row = mLayoutManager->
layouts().count() + ( mAllowEmpty ? 1 : 0 );
506 beginInsertRows( QModelIndex(), row, row );
509 void QgsLayoutManagerModel::layoutAboutToBeRemoved(
const QString &name )
512 int row = mLayoutManager->
layouts().indexOf( l ) + ( mAllowEmpty ? 1 : 0 );
514 beginRemoveRows( QModelIndex(), row, row );
517 void QgsLayoutManagerModel::layoutAdded(
const QString & )
522 void QgsLayoutManagerModel::layoutRemoved(
const QString & )
529 int row = mLayoutManager->
layouts().indexOf( layout ) + ( mAllowEmpty ? 1 : 0 );
530 QModelIndex index = createIndex( row, 0 );
531 emit dataChanged( index, index, QVector<int>() << Qt::DisplayRole );
539 : QSortFilterProxyModel( parent )
541 setDynamicSortFilter(
true );
543 setSortCaseSensitivity( Qt::CaseInsensitive );
548 const QString leftText = sourceModel()->data( left, Qt::DisplayRole ).toString();
549 const QString rightText = sourceModel()->data( right, Qt::DisplayRole ).toString();
550 if ( leftText.isEmpty() )
552 if ( rightText.isEmpty() )
555 return QString::localeAwareCompare( leftText, rightText ) < 0;
568 if ( !mFilterString.trimmed().isEmpty() )
570 if ( !layout->
name().contains( mFilterString, Qt::CaseInsensitive ) )
597 mFilterString = filter;