Compare commits
	
		
			1 Commits
		
	
	
		
			qt-5-15-re
			...
			wip-proper
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 83246f04ae | 
@ -8,6 +8,8 @@
 | 
				
			|||||||
#include "graphicsscene.h"
 | 
					#include "graphicsscene.h"
 | 
				
			||||||
#include "settingsdialog.h"
 | 
					#include "settingsdialog.h"
 | 
				
			||||||
#include "aboutdialog.h"
 | 
					#include "aboutdialog.h"
 | 
				
			||||||
 | 
					#include "metadatadialog.h"
 | 
				
			||||||
 | 
					#include "metadatamodel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QMouseEvent>
 | 
					#include <QMouseEvent>
 | 
				
			||||||
#include <QMovie>
 | 
					#include <QMovie>
 | 
				
			||||||
@ -480,6 +482,17 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
 | 
				
			|||||||
        ad->deleteLater();
 | 
					        ad->deleteLater();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QAction * propertiesAction = new QAction(tr("Properties"));
 | 
				
			||||||
 | 
					    connect(propertiesAction, &QAction::triggered, this, [ = ](){
 | 
				
			||||||
 | 
					        MetadataModel * md = new MetadataModel();
 | 
				
			||||||
 | 
					        md->setFile(currentFileUrl.toLocalFile());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MetadataDialog * ad = new MetadataDialog(this);
 | 
				
			||||||
 | 
					        ad->setMetadataModel(md);
 | 
				
			||||||
 | 
					        ad->exec();
 | 
				
			||||||
 | 
					        ad->deleteLater();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (copyMenu->actions().count() == 1) {
 | 
					    if (copyMenu->actions().count() == 1) {
 | 
				
			||||||
        menu->addActions(copyMenu->actions());
 | 
					        menu->addActions(copyMenu->actions());
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -496,6 +509,10 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
 | 
				
			|||||||
    menu->addSeparator();
 | 
					    menu->addSeparator();
 | 
				
			||||||
    menu->addAction(toggleSettings);
 | 
					    menu->addAction(toggleSettings);
 | 
				
			||||||
    menu->addAction(helpAction);
 | 
					    menu->addAction(helpAction);
 | 
				
			||||||
 | 
					    if (currentFileUrl.isValid()) {
 | 
				
			||||||
 | 
					        menu->addSeparator();
 | 
				
			||||||
 | 
					        menu->addAction(propertiesAction);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    menu->exec(mapToGlobal(event->pos()));
 | 
					    menu->exec(mapToGlobal(event->pos()));
 | 
				
			||||||
    menu->deleteLater();
 | 
					    menu->deleteLater();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										81
									
								
								metadata.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								metadata.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					#include "metadata.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Section::Section()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Section::~Section()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Warning! this method won't copy anything from the given argument!
 | 
				
			||||||
 | 
					// we actually doesn't care about this, but since QList and QMap are not movable
 | 
				
			||||||
 | 
					// so there won't be a (not ill-formed) default ctor to use and we won't get a
 | 
				
			||||||
 | 
					// proper copy ctor, thus the operator= will be deleted.
 | 
				
			||||||
 | 
					// When accessing QMap value if not exist, we just use this to create a new Section.
 | 
				
			||||||
 | 
					Section & Section::operator=(const Section &)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Section::count() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_propertiesValueMap.count();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Section::setSectionName(const QString &displayName)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_displayName = displayName;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Section::setValue(PropertyType type, const QString &value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!m_propertiesValueMap.contains(type)) {
 | 
				
			||||||
 | 
					        m_propertyIndexes.append(type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_propertiesValueMap[type] = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Section::valueAt(int index) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_ASSERT(index >= 0 && index < m_propertyIndexes.count());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return m_propertiesValueMap[m_propertyIndexes[index]];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Section::value(Section::PropertyType type) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_propertiesValueMap.value(type, tr("Unknown"));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Section::propertyName(PropertyType type) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_propertiesOverrideDisplayNameMap.value(
 | 
				
			||||||
 | 
					                type,
 | 
				
			||||||
 | 
					                m_builtinPropDisplayNameMap.value(type, tr("Unknown"))
 | 
				
			||||||
 | 
					           );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Metadata::Metadata()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Metadata::~Metadata()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Metadata::setSectionName(SectionType type, const QString &displayName)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_sections[type].setSectionName(displayName);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Metadata::setPropertyValue(Metadata::SectionType type, Section::PropertyType propType, QString value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_sections[type].setValue(propType, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										66
									
								
								metadata.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								metadata.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					#ifndef METADATA_H
 | 
				
			||||||
 | 
					#define METADATA_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QMap>
 | 
				
			||||||
 | 
					#include <QPair>
 | 
				
			||||||
 | 
					#include <QCoreApplication>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Section
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_DECLARE_TR_FUNCTIONS(Section)
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    Section();
 | 
				
			||||||
 | 
					    ~Section();
 | 
				
			||||||
 | 
					    Section & operator=(const Section& other);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: maybe use QString instead of a enum? different section won't share a same
 | 
				
			||||||
 | 
					    //       enum value in any way...
 | 
				
			||||||
 | 
					    enum PropertyType : int {
 | 
				
			||||||
 | 
					        NameProp,
 | 
				
			||||||
 | 
					        FileSizeProp,
 | 
				
			||||||
 | 
					        LastModifiedProp,
 | 
				
			||||||
 | 
					        ImageSizeProp,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int count() const;
 | 
				
			||||||
 | 
					    void setSectionName(const QString & displayName);
 | 
				
			||||||
 | 
					    void setValue(PropertyType type, const QString & value);
 | 
				
			||||||
 | 
					    QString value(PropertyType type) const;
 | 
				
			||||||
 | 
					    QString valueAt(int index) const;
 | 
				
			||||||
 | 
					    QString propertyName(PropertyType type) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QString m_displayName;
 | 
				
			||||||
 | 
					    QList<PropertyType> m_propertyIndexes;
 | 
				
			||||||
 | 
					    QMap<PropertyType, QString> m_propertiesValueMap;
 | 
				
			||||||
 | 
					    QMap<PropertyType, QString> m_propertiesOverrideDisplayNameMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const QMap<PropertyType, QString> m_builtinPropDisplayNameMap {
 | 
				
			||||||
 | 
					        {NameProp, tr("Name")},
 | 
				
			||||||
 | 
					        {FileSizeProp, tr("File Size")},
 | 
				
			||||||
 | 
					        {LastModifiedProp, tr("Last Modified")},
 | 
				
			||||||
 | 
					        {ImageSizeProp, tr("Image Size")},
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Metadata
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    enum SectionType : int {
 | 
				
			||||||
 | 
					        GeneralSection,
 | 
				
			||||||
 | 
					        ExifSection,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Metadata();
 | 
				
			||||||
 | 
					    ~Metadata();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QList<SectionType> m_sectionIndexes;
 | 
				
			||||||
 | 
					    QMap<SectionType, Section> m_sections;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setSectionName(SectionType type, const QString & displayName);
 | 
				
			||||||
 | 
					    void setPropertyValue(SectionType type, Section::PropertyType propType, QString value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // METADATA_H
 | 
				
			||||||
							
								
								
									
										41
									
								
								metadatadialog.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								metadatadialog.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					#include "metadatadialog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QDialogButtonBox>
 | 
				
			||||||
 | 
					#include <QTreeView>
 | 
				
			||||||
 | 
					#include <QVBoxLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "metadatamodel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MetadataDialog::MetadataDialog(QWidget *parent)
 | 
				
			||||||
 | 
					    : QDialog(parent)
 | 
				
			||||||
 | 
					    , m_treeView(new QTreeView(this))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					//    m_treeView->setRootIsDecorated(false);
 | 
				
			||||||
 | 
					    m_treeView->setIndentation(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setWindowTitle(tr("Image Metadata"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setLayout(new QVBoxLayout);
 | 
				
			||||||
 | 
					    layout()->addWidget(m_treeView);
 | 
				
			||||||
 | 
					    layout()->addWidget(buttonBox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    connect(buttonBox, &QDialogButtonBox::close, this, &QDialog::close);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MetadataDialog::~MetadataDialog()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MetadataDialog::setMetadataModel(MetadataModel * model)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_treeView->setModel(model);
 | 
				
			||||||
 | 
					    m_treeView->expandAll();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QSize MetadataDialog::sizeHint() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return QSize(520, 350);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								metadatadialog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								metadatadialog.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					#ifndef METADATADIALOG_H
 | 
				
			||||||
 | 
					#define METADATADIALOG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QDialog>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QT_BEGIN_NAMESPACE
 | 
				
			||||||
 | 
					class QTreeView;
 | 
				
			||||||
 | 
					QT_END_NAMESPACE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MetadataModel;
 | 
				
			||||||
 | 
					class MetadataDialog : public QDialog
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MetadataDialog(QWidget * parent);
 | 
				
			||||||
 | 
					    ~MetadataDialog() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setMetadataModel(MetadataModel * model);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QSize sizeHint() const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QTreeView * m_treeView = nullptr;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // METADATADIALOG_H
 | 
				
			||||||
							
								
								
									
										267
									
								
								metadatamodel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								metadatamodel.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,267 @@
 | 
				
			|||||||
 | 
					#include "metadatamodel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QFileInfo>
 | 
				
			||||||
 | 
					#include <QDateTime>
 | 
				
			||||||
 | 
					#include <QLocale>
 | 
				
			||||||
 | 
					#include <QSize>
 | 
				
			||||||
 | 
					#include <QImageReader>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This model is very similar to imagemetainfomodel.cpp in
 | 
				
			||||||
 | 
					// Gwenview, since We don't care about ABI here and we won't
 | 
				
			||||||
 | 
					// have any KDE lib as dept (KIO is a tier 3 framework from
 | 
				
			||||||
 | 
					// KDE for example) which might cause this project no longer
 | 
				
			||||||
 | 
					// tiny and easy to maintain, I'll just create a simpler
 | 
				
			||||||
 | 
					// implementation than do a simple copy-paste...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Sections : int {
 | 
				
			||||||
 | 
					    GeneralSection,
 | 
				
			||||||
 | 
					    ExifSection,
 | 
				
			||||||
 | 
					    CustomSection = 61,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MetadataSection
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    class Entry
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        // key: for internal indexing.
 | 
				
			||||||
 | 
					        // label: display name of the key.
 | 
				
			||||||
 | 
					        Entry(const QString & key, const QString & label, const QString & value)
 | 
				
			||||||
 | 
					            : m_key(key)
 | 
				
			||||||
 | 
					            , m_label(label.trimmed())
 | 
				
			||||||
 | 
					            , m_value(value.trimmed())
 | 
				
			||||||
 | 
					        {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QString m_key;
 | 
				
			||||||
 | 
					        QString m_label;
 | 
				
			||||||
 | 
					        QString m_value;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MetadataSection(const QString & sectionName)
 | 
				
			||||||
 | 
					        : m_sectionName(sectionName)
 | 
				
			||||||
 | 
					    {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~MetadataSection()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        qDeleteAll(m_entries);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void clear()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        qDeleteAll(m_entries);
 | 
				
			||||||
 | 
					        m_entries.clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void addEnrty(const QString & key, const QString & label, const QString & value = QString())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Entry * e = new Entry(key, label, value);
 | 
				
			||||||
 | 
					        m_entries << e;
 | 
				
			||||||
 | 
					        m_keyEntryMap[e->m_key] = m_entries.size() - 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QString keyAt(int index) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Q_ASSERT(index < m_entries.size());
 | 
				
			||||||
 | 
					        return m_entries[index]->m_key;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QString valueAt(int index) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Q_ASSERT(index < m_entries.size());
 | 
				
			||||||
 | 
					        return m_entries[index]->m_value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setValueAt(int index, const QString & value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Q_ASSERT(index < m_entries.size());
 | 
				
			||||||
 | 
					        m_entries[index]->m_value = value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QString labelAt(int index) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Q_ASSERT(index < m_entries.size());
 | 
				
			||||||
 | 
					        return m_entries[index]->m_label;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int keyIndex(const QString & key) {
 | 
				
			||||||
 | 
					        return m_keyEntryMap.value(key, -1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QString sectionName() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return m_sectionName;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int size() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return m_entries.size();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QList<Entry*> m_entries;
 | 
				
			||||||
 | 
					    QHash<QString, int> m_keyEntryMap;
 | 
				
			||||||
 | 
					    QString m_sectionName;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MetadataModel::MetadataModel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sectionRegister(GeneralSection, new MetadataSection(tr("General", "General info about the image, section name in metadata dialog")));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    initGeneralSection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MetadataModel::~MetadataModel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    qDeleteAll(m_sections);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MetadataModel::setFile(const QString &path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QFileInfo fileInfo(path);
 | 
				
			||||||
 | 
					    const QString sizeString = QLocale().formattedDataSize(fileInfo.size());
 | 
				
			||||||
 | 
					    const QString timeString = QLocale().toString(fileInfo.lastModified(), QLocale::LongFormat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME: this implementation is very dirty!
 | 
				
			||||||
 | 
					    QImageReader imgReader(path);
 | 
				
			||||||
 | 
					    setImageSize(imgReader.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setSectionEntryValue(GeneralSection, QStringLiteral("General.Name"), fileInfo.fileName());
 | 
				
			||||||
 | 
					    setSectionEntryValue(GeneralSection, QStringLiteral("General.Size"), sizeString);
 | 
				
			||||||
 | 
					    setSectionEntryValue(GeneralSection, QStringLiteral("General.Time"), timeString);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MetadataModel::setImageSize(const QSize &size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QString imageSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (size.isValid()) {
 | 
				
			||||||
 | 
					        imageSize = tr("%1 x %2").arg(QString::number(size.width()), QString::number(size.height()));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        imageSize = QLatin1Char('-');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setSectionEntryValue(GeneralSection, QStringLiteral("General.ImageSize"), imageSize);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QModelIndex MetadataModel::index(int row, int col, const QModelIndex &parent) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (col < 0 || col > 1) {
 | 
				
			||||||
 | 
					        return QModelIndex();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!parent.isValid()) {
 | 
				
			||||||
 | 
					        // This is a group
 | 
				
			||||||
 | 
					        if (row < 0 || row >= m_sections.size()) {
 | 
				
			||||||
 | 
					            return QModelIndex();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return createIndex(row, col, col == 0 ? 2 : 3); // ????????
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // This is an entry
 | 
				
			||||||
 | 
					        int group = parent.row();
 | 
				
			||||||
 | 
					        if (row < 0 || row >= m_sections[group]->size()) {
 | 
				
			||||||
 | 
					            return QModelIndex();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return createIndex(row, col, static_cast<quintptr>(group));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QModelIndex MetadataModel::parent(const QModelIndex & index) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!index.isValid()) {
 | 
				
			||||||
 | 
					        return QModelIndex();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (index.internalId() == 2 || index.internalId() == 3) {
 | 
				
			||||||
 | 
					        return QModelIndex();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return createIndex(static_cast<int>(index.internalId()), 0, 2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int MetadataModel::rowCount(const QModelIndex & parent) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!parent.isValid()) {
 | 
				
			||||||
 | 
					        return m_sections.size();
 | 
				
			||||||
 | 
					    } else if (parent.internalId() == 2) {
 | 
				
			||||||
 | 
					        return m_sections[parent.row()]->size();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int MetadataModel::columnCount(const QModelIndex &) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QVariant MetadataModel::data(const QModelIndex &index, int role) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!index.isValid()) {
 | 
				
			||||||
 | 
					        return QVariant();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (role) {
 | 
				
			||||||
 | 
					    case Qt::DisplayRole:
 | 
				
			||||||
 | 
					        return displayData(index);
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        return QVariant();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MetadataModel::initGeneralSection()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MetadataSection * s = section(GeneralSection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->addEnrty(QStringLiteral("General.Name"), tr("File Name"));
 | 
				
			||||||
 | 
					    s->addEnrty(QStringLiteral("General.Size"), tr("File Size"));
 | 
				
			||||||
 | 
					    s->addEnrty(QStringLiteral("General.Time"), tr("Last Modified"));
 | 
				
			||||||
 | 
					    s->addEnrty(QStringLiteral("General.ImageSize"), tr("Image Size"));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool MetadataModel::sectionRegister(Sections sectionType, MetadataSection *section)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (m_sectionEnumIndexMap.contains(sectionType)) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m_sections.append(section);
 | 
				
			||||||
 | 
					    m_sectionEnumIndexMap[sectionType] = section;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MetadataModel::setSectionEntryValue(Sections sectionType, const QString &key, const QString &value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MetadataSection * s = section(sectionType);
 | 
				
			||||||
 | 
					    int entryIndex = s->keyIndex(key);
 | 
				
			||||||
 | 
					    if (entryIndex < 0) {
 | 
				
			||||||
 | 
					        // no such entry
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    s->setValueAt(entryIndex, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MetadataSection *MetadataModel::section(Sections sectionType)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_sectionEnumIndexMap[sectionType];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QVariant MetadataModel::displayData(const QModelIndex &index) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (index.internalId() == 2) {
 | 
				
			||||||
 | 
					        if (index.column() != 0) {
 | 
				
			||||||
 | 
					            return QVariant();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        QString label = m_sections[index.row()]->sectionName();
 | 
				
			||||||
 | 
					        return QVariant(label);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (index.internalId() == 3) {
 | 
				
			||||||
 | 
					        return QString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MetadataSection* group = m_sections[index.internalId()];
 | 
				
			||||||
 | 
					    if (index.column() == 0) {
 | 
				
			||||||
 | 
					        return group->labelAt(index.row());
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return group->valueAt(index.row());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								metadatamodel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								metadatamodel.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					#ifndef METADATAMODEL_H
 | 
				
			||||||
 | 
					#define METADATAMODEL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QVector>
 | 
				
			||||||
 | 
					#include <QAbstractItemModel>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Sections : int;
 | 
				
			||||||
 | 
					class MetadataSection;
 | 
				
			||||||
 | 
					class MetadataModel : public QAbstractItemModel
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    MetadataModel();
 | 
				
			||||||
 | 
					    ~MetadataModel() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setFile(const QString & url);
 | 
				
			||||||
 | 
					    void setImageSize(const QSize & size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const override;
 | 
				
			||||||
 | 
					    QModelIndex parent(const QModelIndex & index) const override;
 | 
				
			||||||
 | 
					    int rowCount(const QModelIndex & parent = QModelIndex()) const override;
 | 
				
			||||||
 | 
					    int columnCount(const QModelIndex & = QModelIndex()) const override;
 | 
				
			||||||
 | 
					    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QList<MetadataSection *> m_sections; // associated pointers free at destructor function.
 | 
				
			||||||
 | 
					    QMap<Sections, MetadataSection *> m_sectionEnumIndexMap; // pointer shared with m_sections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void initGeneralSection();
 | 
				
			||||||
 | 
					    bool sectionRegister(Sections sectionType, MetadataSection * section);
 | 
				
			||||||
 | 
					    void setSectionEntryValue(Sections sectionType, const QString & key, const QString & value);
 | 
				
			||||||
 | 
					    MetadataSection * section(Sections sectionType);
 | 
				
			||||||
 | 
					    QVariant displayData(const QModelIndex & index) const;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // METADATAMODEL_H
 | 
				
			||||||
@ -29,6 +29,9 @@ SOURCES += \
 | 
				
			|||||||
    graphicsview.cpp \
 | 
					    graphicsview.cpp \
 | 
				
			||||||
    bottombuttongroup.cpp \
 | 
					    bottombuttongroup.cpp \
 | 
				
			||||||
    graphicsscene.cpp \
 | 
					    graphicsscene.cpp \
 | 
				
			||||||
 | 
					    metadata.cpp \
 | 
				
			||||||
 | 
					    metadatadialog.cpp \
 | 
				
			||||||
 | 
					    metadatamodel.cpp \
 | 
				
			||||||
    navigatorview.cpp \
 | 
					    navigatorview.cpp \
 | 
				
			||||||
    opacityhelper.cpp \
 | 
					    opacityhelper.cpp \
 | 
				
			||||||
    toolbutton.cpp \
 | 
					    toolbutton.cpp \
 | 
				
			||||||
@ -41,6 +44,9 @@ HEADERS += \
 | 
				
			|||||||
    graphicsview.h \
 | 
					    graphicsview.h \
 | 
				
			||||||
    bottombuttongroup.h \
 | 
					    bottombuttongroup.h \
 | 
				
			||||||
    graphicsscene.h \
 | 
					    graphicsscene.h \
 | 
				
			||||||
 | 
					    metadata.h \
 | 
				
			||||||
 | 
					    metadatadialog.h \
 | 
				
			||||||
 | 
					    metadatamodel.h \
 | 
				
			||||||
    navigatorview.h \
 | 
					    navigatorview.h \
 | 
				
			||||||
    opacityhelper.h \
 | 
					    opacityhelper.h \
 | 
				
			||||||
    toolbutton.h \
 | 
					    toolbutton.h \
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user