Commit 4c2f6bd5 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Make guides list show clip markers when a bin clip is selected, allow editing...

Make guides list show clip markers when a bin clip is selected, allow editing several markers (only allows changing category)
parent 60304ef7
......@@ -311,7 +311,7 @@ void AssetPanel::clear()
m_timelineButton->setVisible(false);
m_switchBuiltStack->setVisible(false);
m_effectStackWidget->unsetModel();
m_assetTitle->setText(QString());
m_assetTitle->clear();
}
void AssetPanel::updatePalette()
......
......@@ -34,6 +34,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "monitor/monitor.h"
#include "monitor/monitormanager.h"
#include "profiles/profilemodel.hpp"
#include "project/dialogs/guideslist.h"
#include "project/dialogs/slideshowclip.h"
#include "project/invaliddialog.h"
#include "project/projectmanager.h"
......
......@@ -789,6 +789,44 @@ bool MarkerListModel::removeAllMarkers()
return true;
}
bool MarkerListModel::editMultipleMarkersGui(const QList<GenTime> positions, QWidget *parent)
{
bool exists;
auto marker = getMarker(positions.first(), &exists);
if (!exists) {
pCore->displayMessage(i18n("No guide found at current position"), InformationMessage);
}
QDialog d(parent);
d.setWindowTitle(m_guide ? i18n("Edit Guides Category") : i18n("Edit Markers Category"));
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
auto *l = new QVBoxLayout;
d.setLayout(l);
d.connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
d.connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
QLabel lab(m_guide ? i18n("Guides Category") : i18n("Markers Category"), &d);
MarkerCategoryChooser chooser(&d);
chooser.setMarkerModel(this);
chooser.setAllowAll(false);
chooser.setCurrentCategory(marker.markerType());
l->addWidget(&lab);
l->addWidget(&chooser);
l->addWidget(buttonBox);
if (d.exec() == QDialog::Accepted) {
int category = chooser.currentCategory();
Fun undo = []() { return true; };
Fun redo = []() { return true; };
for (auto &pos : positions) {
marker = getMarker(positions.first(), &exists);
if (exists) {
addMarker(pos, marker.comment(), category, undo, redo);
}
}
PUSH_UNDO(undo, redo, m_guide ? i18n("Edit guides") : i18n("Edit markers"));
return true;
}
return false;
}
bool MarkerListModel::editMarkerGui(const GenTime &pos, QWidget *parent, bool createIfNotFound, ClipController *clip, bool createOnly)
{
bool exists;
......
......@@ -136,6 +136,12 @@ public:
@return true if dialog was accepted and modification successful
*/
bool editMarkerGui(const GenTime &pos, QWidget *parent, bool createIfNotFound, ClipController *clip = nullptr, bool createOnly = false);
/** @brief Shows a dialog to change the category of multiple markers/guides
@param positions: List of the markers positions to edit
@param widget: qt widget that will be the parent of the dialog
@return true if dialog was accepted and modification successful
*/
bool editMultipleMarkersGui(const QList<GenTime> positions, QWidget *parent);
/** @brief Shows a dialog to add multiple markers/guide
@param pos: position of the marker to edit, or new position for a marker
@param widget: qt widget that will be the parent of the dialog
......
......@@ -23,14 +23,15 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "macros.hpp"
#include "mltcontroller/clippropertiescontroller.h"
#include "model/markerlistmodel.hpp"
#include "model/markersortmodel.h"
#include "profiles/profilemodel.hpp"
#include "project/projectmanager.h"
#include "projectfolder.h"
#include "projectitemmodel.h"
#include "projectsubclip.h"
#include "timeline2/model/snapmodel.hpp"
#include "utils/timecode.h"
#include "utils/thumbnailcache.hpp"
#include "utils/timecode.h"
#include "xml/xml.hpp"
#include "kdenlive_debug.h"
......@@ -76,6 +77,10 @@ ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, const std::share
, m_uuid(QUuid::createUuid())
{
m_markerModel = std::make_shared<MarkerListModel>(id, pCore->projectManager()->undoStack());
m_markerFilterModel.reset(new MarkerSortModel(this));
m_markerFilterModel->setSourceModel(m_markerModel.get());
m_markerFilterModel->setSortRole(MarkerListModel::PosRole);
m_markerFilterModel->sort(0, Qt::AscendingOrder);
if (producer->get_int("_placeholder") == 1) {
m_clipStatus = FileStatus::StatusMissing;
} else if (producer->get_int("_missingsource") == 1) {
......@@ -150,6 +155,10 @@ ProjectClip::ProjectClip(const QString &id, const QDomElement &description, cons
m_clipStatus = FileStatus::StatusWaiting;
m_thumbnail = thumb;
m_markerModel = std::make_shared<MarkerListModel>(m_binId, pCore->projectManager()->undoStack());
m_markerFilterModel.reset(new MarkerSortModel(this));
m_markerFilterModel->setSourceModel(m_markerModel.get());
m_markerFilterModel->setSortRole(MarkerListModel::PosRole);
m_markerFilterModel->sort(0, Qt::AscendingOrder);
if (description.hasAttribute(QStringLiteral("type"))) {
m_clipType = ClipType::ProducerType(description.attribute(QStringLiteral("type")).toInt());
if (m_clipType == ClipType::Audio) {
......
......@@ -1876,9 +1876,9 @@ QStringList KdenliveDoc::getProxyHashList()
return pCore->bin()->getProxyHashList();
}
MarkerSortModel *KdenliveDoc::getFilteredGuideModel() const
std::shared_ptr<MarkerSortModel> KdenliveDoc::getFilteredGuideModel() const
{
return m_guidesFilterModel.get();
return m_guidesFilterModel;
}
std::shared_ptr<MarkerListModel> KdenliveDoc::getGuideModel() const
......
......@@ -196,7 +196,7 @@ public:
/** @brief Returns a pointer to the guide model */
std::shared_ptr<MarkerListModel> getGuideModel() const;
MarkerSortModel *getFilteredGuideModel() const;
std::shared_ptr<MarkerSortModel> getFilteredGuideModel() const;
// TODO REFAC: delete */
Render *renderer();
......
......@@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "clipcontroller.h"
#include "bin/clipcreator.hpp"
#include "bin/model/markerlistmodel.hpp"
#include "bin/model/markersortmodel.h"
#include "doc/docundostack.hpp"
#include "doc/kdenlivedoc.h"
#include "doc/kthumb.h"
......@@ -1081,3 +1082,8 @@ bool ClipController::hasProxy() const
// qDebug()<<"::: PROXY: "<<proxy<<" = "<<getProducerProperty(QStringLiteral("resource"));
return proxy.size() > 2 && proxy == getProducerProperty(QStringLiteral("resource"));
}
std::shared_ptr<MarkerSortModel> ClipController::getFilteredMarkerModel() const
{
return m_markerFilterModel;
}
......@@ -23,6 +23,7 @@ class Bin;
class AudioStreamInfo;
class EffectStackModel;
class MarkerListModel;
class MarkerSortModel;
/** @class ClipController
* @brief Provides a convenience wrapper around the project Bin clip producers.
......@@ -156,6 +157,7 @@ public:
/** @brief Returns the marker model associated with this clip */
std::shared_ptr<MarkerListModel> getMarkerModel() const;
std::shared_ptr<MarkerSortModel> getFilteredMarkerModel() const;
void setZone(const QPoint &zone);
QPoint zone() const;
......@@ -239,6 +241,7 @@ protected:
// void rebuildEffectList(ProfileInfo info);
std::shared_ptr<EffectStackModel> m_effectStack;
std::shared_ptr<MarkerListModel> m_markerModel;
std::shared_ptr<MarkerSortModel> m_markerFilterModel;
bool m_hasAudio;
bool m_hasVideo;
QMap<int, QStringList> m_streamEffects;
......
......@@ -19,6 +19,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "lib/localeHandling.h"
#include "mainwindow.h"
#include "mltcontroller/clipcontroller.h"
#include "project/dialogs/guideslist.h"
#include "monitormanager.h"
#include "monitorproxy.h"
......@@ -1776,6 +1777,7 @@ void Monitor::slotOpenClip(const std::shared_ptr<ProjectClip> &controller, int i
if (m_controller->statusReady()) {
m_timePos->setRange(0, int(m_controller->frameDuration() - 1));
m_glMonitor->setRulerInfo(int(m_controller->frameDuration() - 1), controller->getMarkerModel());
pCore->guidesList()->setClipMarkerModel(m_controller);
loadQmlScene(MonitorSceneDefault);
updateMarkers();
connect(m_glMonitor->getControllerProxy(), &MonitorProxy::addSnap, this, &Monitor::addSnapPoint, Qt::DirectConnection);
......@@ -1821,6 +1823,7 @@ void Monitor::slotOpenClip(const std::shared_ptr<ProjectClip> &controller, int i
m_glMonitor->getControllerProxy()->setAudioThumb();
m_audioMeterWidget->audioChannels = 0;
m_glMonitor->getControllerProxy()->setClipProperties(-1, ClipType::Unknown, false, QString());
pCore->guidesList()->setClipMarkerModel(nullptr);
// m_audioChannels->menuAction()->setVisible(false);
m_streamAction->setVisible(false);
if (monitorVisible()) {
......@@ -2482,6 +2485,17 @@ void Monitor::slotSwitchAudioMonitor()
displayAudioMonitor(isActive());
}
void Monitor::updateGuidesList()
{
if (m_id == Kdenlive::ProjectMonitor) {
if (pCore->currentDoc()) {
pCore->guidesList()->setModel(pCore->currentDoc()->getGuideModel(), pCore->currentDoc()->getFilteredGuideModel());
}
} else if (m_id == Kdenlive::ClipMonitor) {
pCore->guidesList()->setClipMarkerModel(m_controller);
}
}
void Monitor::displayAudioMonitor(bool isActive)
{
bool enable = isActive && ((KdenliveSettings::monitoraudio() & m_id) != 0 || (m_id == Kdenlive::ProjectMonitor && pCore->audioMixerVisible));
......
......@@ -110,6 +110,8 @@ public:
/** @brief Set a property on the Qml scene **/
void setQmlProperty(const QString &name, const QVariant &value);
void displayAudioMonitor(bool isActive);
/** @brief Set the guides list model to currently active item (bin clip or timeline) **/
void updateGuidesList();
/** @brief Prepare split effect from timeline clip producer **/
void activateSplit();
/** @brief Clear monitor display **/
......
......@@ -183,6 +183,8 @@ bool MonitorManager::activateMonitor(Kdenlive::MonitorId name, bool raiseMonitor
} else {
m_clipMonitor->fixFocus();
}
// Set guides list to show guides
m_clipMonitor->updateGuidesList();
if (!m_clipMonitor->isVisible()) {
pCore->displayMessage(i18n("Do you want to <a href=\"#clipmonitor\">show the clip monitor</a> to view timeline?"),
MessageType::InformationMessage);
......@@ -193,6 +195,8 @@ bool MonitorManager::activateMonitor(Kdenlive::MonitorId name, bool raiseMonitor
m_projectMonitor->displayAudioMonitor(false);
m_clipMonitor->displayAudioMonitor(true);
} else if (name == Kdenlive::ProjectMonitor) {
// Set guides list to show guides
m_projectMonitor->updateGuidesList();
if (!m_projectMonitor->monitorIsFullScreen()) {
if (raiseMonitor) {
m_projectMonitor->parentWidget()->raise();
......
......@@ -7,6 +7,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "guideslist.h"
#include "bin/bin.h"
#include "bin/model/markersortmodel.h"
#include "bin/projectclip.h"
#include "core.h"
#include "doc/kdenlivedoc.h"
#include "kdenlive_debug.h"
......@@ -40,6 +41,7 @@ public:
GuidesList::GuidesList(QWidget *parent)
: QWidget(parent)
, m_markerMode(false)
{
setupUi(this);
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
......@@ -50,10 +52,22 @@ GuidesList::GuidesList(QWidget *parent)
connect(guides_list, &QListView::doubleClicked, this, &GuidesList::editGuide);
connect(guide_delete, &QToolButton::clicked, this, &GuidesList::removeGuide);
connect(guide_add, &QToolButton::clicked, this, &GuidesList::addGuide);
connect(guide_save, &QToolButton::clicked, this, &GuidesList::saveGuides);
connect(configure, &QToolButton::clicked, this, &GuidesList::configureGuides);
connect(guide_edit, &QToolButton::clicked, this, &GuidesList::editGuides);
connect(filter_line, &QLineEdit::textChanged, this, &GuidesList::filterView);
// Settings menu
QMenu *settingsMenu = new QMenu(this);
QAction *importGuides = new QAction(QIcon::fromTheme(QStringLiteral("document-import")), i18n("Import..."), this);
connect(importGuides, &QAction::triggered, this, &GuidesList::configureGuides);
settingsMenu->addAction(importGuides);
QAction *exportGuides = new QAction(QIcon::fromTheme(QStringLiteral("document-export")), i18n("Export..."), this);
connect(exportGuides, &QAction::triggered, this, &GuidesList::saveGuides);
settingsMenu->addAction(exportGuides);
QAction *categories = new QAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("Configure Categories"), this);
connect(categories, &QAction::triggered, this, &GuidesList::configureGuides);
settingsMenu->addAction(categories);
guides_settings->setMenu(settingsMenu);
// Sort menu
m_filterGroup = new QActionGroup(this);
QMenu *sortMenu = new QMenu(this);
......@@ -86,12 +100,8 @@ GuidesList::GuidesList(QWidget *parent)
guide_add->setWhatsThis(xi18nc("@info:whatsthis", "Add new guide. This will add a guide at the current frame position."));
guide_delete->setToolTip(i18n("Dereturn leftTime < rightTime;lete guide."));
guide_delete->setWhatsThis(xi18nc("@info:whatsi18nthis", "Delete guide. This will erase all selected guides."));
guide_save->setToolTip(i18n("Export guides."));
guide_save->setWhatsThis(
xi18nc("@info:whatsthis", "Export guide. This allows you to copy the guides data in a text format for use in web platforms for example."));
configure->setToolTip(i18n("Configure project guide categories."));
configure->setWhatsThis(xi18nc(
"@info:whatsthis", "Configure guide categories. This allows you to customize the guide categories used in this project (add, remove, rename, ...)."));
guide_edit->setToolTip(i18n("Edit selected guide."));
guide_edit->setWhatsThis(xi18nc("@info:whatsthis", "Edit selected guide. Selecting multiple guides allows changing their category."));
show_categories->setToolTip(i18n("Filter guide categories."));
show_categories->setWhatsThis(
xi18nc("@info:whatsthis", "Filter guide categories. This allows you to show or hide selected guide categories in this dialog and in the timeline."));
......@@ -109,6 +119,28 @@ void GuidesList::saveGuides()
}
}
void GuidesList::editGuides()
{
QModelIndexList selectedIndexes = guides_list->selectionModel()->selectedIndexes();
if (selectedIndexes.isEmpty()) {
return;
}
if (selectedIndexes.size() == 1) {
editGuide(selectedIndexes.first());
return;
}
QList<GenTime> timeList;
for (auto &ix : selectedIndexes) {
int frame = m_proxy->data(ix, MarkerListModel::FrameRole).toInt();
GenTime pos(frame, pCore->getCurrentFps());
timeList << pos;
}
std::sort(timeList.begin(), timeList.end());
if (auto markerModel = m_model.lock()) {
markerModel->editMultipleMarkersGui(timeList, qApp->activeWindow());
}
}
void GuidesList::editGuide(const QModelIndex &ix)
{
if (!ix.isValid()) return;
......@@ -162,12 +194,43 @@ void GuidesList::selectionChanged(const QItemSelection &selected, const QItemSel
GuidesList::~GuidesList() = default;
void GuidesList::setModel(std::weak_ptr<MarkerListModel> model, MarkerSortModel *viewModel)
void GuidesList::setClipMarkerModel(std::shared_ptr<ProjectClip> clip)
{
if (clip == nullptr) {
m_sortModel = nullptr;
m_proxy->setSourceModel(m_sortModel);
guides_list->setModel(m_proxy);
guideslist_label->clear();
setEnabled(false);
return;
}
setEnabled(true);
m_markerMode = true;
guideslist_label->setText(i18n("Markers for %1", clip->clipName()));
m_sortModel = clip->getFilteredMarkerModel().get();
m_model = clip->getMarkerModel();
m_proxy->setSourceModel(m_sortModel);
guides_list->setModel(m_proxy);
guides_list->setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(guides_list->selectionModel(), &QItemSelectionModel::selectionChanged, this, &GuidesList::selectionChanged);
if (auto markerModel = m_model.lock()) {
connect(markerModel.get(), &MarkerListModel::categoriesChanged, this, &GuidesList::rebuildCategories);
}
rebuildCategories();
}
void GuidesList::setModel(std::weak_ptr<MarkerListModel> model, std::shared_ptr<MarkerSortModel> viewModel)
{
if (viewModel.get() == m_sortModel) {
// already displayed
return;
}
m_model = std::move(model);
setEnabled(true);
guideslist_label->setText(i18n("Timeline Guides"));
if (auto markerModel = m_model.lock()) {
m_sortModel = viewModel;
m_proxy->setSourceModel(viewModel);
m_sortModel = viewModel.get();
m_proxy->setSourceModel(m_sortModel);
guides_list->setModel(m_proxy);
guides_list->setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(guides_list->selectionModel(), &QItemSelectionModel::selectionChanged, this, &GuidesList::selectionChanged);
......@@ -211,9 +274,7 @@ void GuidesList::updateFilter(QAbstractButton *, bool)
filters << b->property("index").toInt();
}
}
if (auto markerModel = m_model.lock()) {
pCore->currentDoc()->setGuidesFilter(filters);
}
pCore->currentDoc()->setGuidesFilter(filters);
emit pCore->refreshActiveGuides();
qDebug() << "::: GOT FILTERS: " << filters;
}
......
......@@ -14,6 +14,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
class MarkerSortModel;
class QActionGroup;
class ProjectClip;
/** @class GuidesList
@brief A widget listing project guides and allowing some advanced editing.
......@@ -25,11 +26,12 @@ class GuidesList : public QWidget, public Ui::GuidesList_UI
public:
explicit GuidesList(QWidget *parent = nullptr);
~GuidesList() override;
void setModel(std::weak_ptr<MarkerListModel> model, MarkerSortModel *viewModel);
void setModel(std::weak_ptr<MarkerListModel> model, std::shared_ptr<MarkerSortModel> viewModel);
void setClipMarkerModel(std::shared_ptr<ProjectClip> clip);
protected:
private slots:
void saveGuides();
void editGuides();
void editGuide(const QModelIndex &ix);
void selectionChanged(const QItemSelection &selected, const QItemSelection &);
void removeGuide();
......@@ -49,6 +51,7 @@ private:
QVBoxLayout m_categoriesLayout;
QButtonGroup *catGroup{nullptr};
QActionGroup *m_filterGroup;
bool m_markerMode;
signals:
};
......@@ -168,7 +168,7 @@ void TimelineWidget::setModel(const std::shared_ptr<TimelineItemModel> &model, M
// leaking from one project to another because of qml's image caching
rootContext()->setContextProperty("documentId", pCore->currentDoc()->uuid);
rootContext()->setContextProperty("audiorec", pCore->getAudioDevice());
rootContext()->setContextProperty("guidesModel", pCore->currentDoc()->getFilteredGuideModel());
rootContext()->setContextProperty("guidesModel", pCore->currentDoc()->getFilteredGuideModel().get());
rootContext()->setContextProperty("clipboard", new ClipboardProxy(this));
rootContext()->setContextProperty("miniFont", QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
rootContext()->setContextProperty("subtitleModel", pCore->getSubtitleModel().get());
......
......@@ -6,80 +6,32 @@
<rect>
<x>0</x>
<y>0</y>
<width>270</width>
<height>370</height>
<width>227</width>
<height>296</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="4">
<widget class="QToolButton" name="show_categories">
<item row="0" column="0" colspan="3">
<widget class="KSqueezedTextLabel" name="guideslist_label">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="view-filter">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
<string>KSqueezedTextLabel</string>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>77</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="7">
<widget class="QListView" name="guides_list">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="6">
<widget class="QToolButton" name="configure">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="configure">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="guide_delete">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="edit-delete">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
<item row="1" column="0">
<widget class="QLineEdit" name="filter_line">
<property name="placeholderText">
<string>Search</string>
</property>
<property name="autoRaise">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="6">
<item row="1" column="2">
<widget class="QToolButton" name="sort_guides">
<property name="text">
<string>...</string>
......@@ -96,39 +48,116 @@
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QToolButton" name="guide_save">
<item row="5" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="guide_add">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="list-add">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::DelayedPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="guide_edit">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="document-edit"/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="guide_delete">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="edit-delete">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>77</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="guides_settings">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="application-menu">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>