#include <QtWidgets>
#include "Utilities.h"
#include "MdiWindow.h"
#include "ui_ExtensibleObjectModelUI.h"
MdiWindow::MdiWindow(QWidget *parent) :
QMainWindow(parent), appWindow(nullptr)
{
//setupServer();
}
QObject* MakeTestObjectTree();
void EnumPropertyEditorTest();
void MdiWindow::init(Ui_MainWindow* ui)
{
server = 0;
appWindow = ui;
mdiArea = ui->mdiArea;//new QMdiArea;
connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(updateActions()));
connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(updatePreview()));
windowMapper = new QSignalMapper(this);
connect(windowMapper, SIGNAL(mapped(QWidget*)), this, SLOT(setActiveSubWindow(QWidget*)));
QObject::connect(appWindow->actionNew, SIGNAL(triggered(bool)), this, SLOT(newFile()));
QObject::connect(appWindow->actionOpen, SIGNAL(triggered(bool)), this, SLOT(open()));
QObject::connect(appWindow->actionSave, SIGNAL(triggered(bool)), this, SLOT(save()));
QObject::connect(appWindow->actionSave_As, SIGNAL(triggered(bool)), this, SLOT(saveAs()));
QObject::connect(appWindow->actionSwitchRTL, SIGNAL(triggered(bool)), this, SLOT(switchLayoutDirection()));
#ifndef QT_NO_CLIPBOARD
QObject::connect(appWindow->actionCut, SIGNAL(triggered(bool)), this, SLOT(cut()));
QObject::connect(appWindow->actionCopy, SIGNAL(triggered(bool)), this, SLOT(copy()));
QObject::connect(appWindow->actionPaste, SIGNAL(triggered(bool)), this, SLOT(paste()));
#endif
QObject::connect(appWindow->actionBold, SIGNAL(triggered(bool)), this, SLOT(bold()));
QObject::connect(appWindow->actionItalic, SIGNAL(triggered(bool)), this, SLOT(italic()));
QObject::connect(appWindow->actionQuote, SIGNAL(triggered(bool)), this, SLOT(quote()));
QObject::connect(appWindow->actionCode, SIGNAL(triggered(bool)), this, SLOT(code()));
QObject::connect(appWindow->actionHeading_1, SIGNAL(triggered(bool)), this, SLOT(heading1()));
QObject::connect(appWindow->actionHeading_2, SIGNAL(triggered(bool)), this, SLOT(heading2()));
QObject::connect(appWindow->actionHeading_3, SIGNAL(triggered(bool)), this, SLOT(heading3()));
QObject::connect(appWindow->actionHeading_4, SIGNAL(triggered(bool)), this, SLOT(heading4()));
QObject::connect(appWindow->actionHyperlink, SIGNAL(triggered(bool)), this, SLOT(hyperlink()));
QObject::connect(appWindow->actionImage, SIGNAL(triggered(bool)), this, SLOT(image()));
QObject::connect(appWindow->actionUnordered_List, SIGNAL(triggered(bool)), this, SLOT(unorderedList()));
QObject::connect(appWindow->actionOrdered_List, SIGNAL(triggered(bool)), this, SLOT(orderedList()));
QObject::connect(appWindow->actionHorizontal_Rule,SIGNAL(triggered(bool)), this, SLOT(horizontalRule()));
QObject::connect(appWindow->actionTimestamp, SIGNAL(triggered(bool)), this, SLOT(timestamp()));
QObject::connect(appWindow->actionPage_Number, SIGNAL(triggered(bool)), this, SLOT(pageNumber()));
QObject::connect(appWindow->actionPage_Count, SIGNAL(triggered(bool)), this, SLOT(pageCount()));
QObject::connect(appWindow->actionOptions, SIGNAL(triggered(bool)), this, SLOT(options()));
QObject::connect(appWindow->actionSave_All, SIGNAL(triggered(bool)), this, SLOT(saveAll()));
QObject::connect(appWindow->actionSelect_All, SIGNAL(triggered(bool)), this, SLOT(selectAll()));
QObject::connect(appWindow->actionDelete, SIGNAL(triggered(bool)), this, SLOT(del()));
QObject::connect(appWindow->actionUndo, SIGNAL(triggered(bool)), this, SLOT(undo()));
QObject::connect(appWindow->actionRedo, SIGNAL(triggered(bool)), this, SLOT(redo()));
QObject::connect(appWindow->actionFind, SIGNAL(triggered(bool)), this, SLOT(find()));
QObject::connect(appWindow->actionFind_Next, SIGNAL(triggered(bool)), this, SLOT(findNext()));
QObject::connect(appWindow->actionFind_Previous,SIGNAL(triggered(bool)), this, SLOT(findPrevious()));
QObject::connect(appWindow->actionGo_to_Line, SIGNAL(triggered(bool)), this, SLOT(goToLine()));
QObject::connect(appWindow->action_Tile_Windows,SIGNAL(triggered(bool)), this, SLOT(tileSubWindows()));
QObject::connect(appWindow->action_Windowed, SIGNAL(triggered(bool)), this, SLOT(cascadeSubWindows()));
QObject::connect(appWindow->actionTabbed, SIGNAL(triggered(bool)), this, SLOT(tabSubWindows()));
QObject::connect(appWindow->actionClose, SIGNAL(triggered(bool)), mdiArea, SLOT(closeActiveSubWindow()));
QObject::connect(appWindow->actionClose_All, SIGNAL(triggered(bool)), mdiArea, SLOT(closeAllSubWindows()));
QObject::connect(appWindow->actionNext, SIGNAL(triggered(bool)), mdiArea, SLOT(activateNextSubWindow()));
QObject::connect(appWindow->actionPrevious, SIGNAL(triggered(bool)), mdiArea, SLOT(activatePreviousSubWindow()));
QObject::connect(appWindow->actionSupport, SIGNAL(triggered(bool)), this, SLOT(support()));
QObject::connect(appWindow->actionWebsite, SIGNAL(triggered(bool)), this, SLOT(website()));
statusBar()->showMessage(tr("Ready"));
updateActions();
setUnifiedTitleAndToolBarOnMac(true);
#if QT_VERSION >= 0x050000
menuBar()->setNativeMenuBar(false);
#endif
/*
EnumPropertyEditorTest();
updateObjectTree(MakeTestObjectTree());
//changeProjectTree(this);
*/
Project *p = new Project;
p->setObjectName("P1");
p->m_Author = "John";
//p->m_Name = "Project Name";
/*
Output *out = new Output;
out->m_Title = "Title";
out->m_Filename = "OutFile.pdf";
out->m_FileType = Output::PDF;
p->setOutput(out);
Template *tmpl = new Template;
tmpl->m_Filename = "Templ.tmpl";
tmpl->m_Color = QColor(1,2,3);
p->setTemplate(tmpl);
*/
p->setTitle("Title");
p->setOutputFilename("OutFile.pdf");
p->setOutputFileType(Project::PDF);
p->setTemplate("Templ.tmpl");
p->setColor(QColor(1,2,3));
Input *in = new Input;
in->setObjectName("InFile1");
in->m_Filename = "InFile1.md";
p->AddInput(in);
Input *in2 = new Input;
in2->setObjectName("InFile2");
in2->m_Filename = "InFile2.md";
p->AddInput(in2);
/*
in.m_Filename = "InFile2.md";
p.m_Inputs.append(in);
in.m_Filename = "InFile3.md";
p.m_Inputs.append(in);
*/
//solution.m_Projects.append(p);
//solution.AddProject(p);
/*
p.m_Name = "Project Name 2";
p.m_Output.m_Title = "Title 2";
p.m_Output.m_Filename = "OutFile2.pdf";
solution.m_Projects.append(p);
*/
//changeProjectTree(&solution);
//tabifyDockWidget(appWindow->projectDock, appWindow->objectsDock);
//tabifyDockWidget(appWindow->projectDock, appWindow->propertiesDock);
appWindow->projectDock->raise();
appWindow->eventLogDock->hide();
appWindow->consoleDock->hide();
readSettings();
}
void MdiWindow::closeEvent(QCloseEvent *event)
{
YQ_LOG_DEBUG("Closing all documents (received MdiWindow::closeEvent)");
mdiArea->closeAllSubWindows();
if (mdiArea->currentSubWindow()) {
YQ_LOG_DEBUG("Ignoring MdiWindow::closeEvent");
event->ignore();
} else {
writeSettings();
YQ_LOG_DEBUG("Accepting MdiWindow::closeEvent");
event->accept();
}
}
void MdiWindow::newFile()
{
YQ_LOG_DEBUG("newFile");
MdiChild *child = createMdiChild();
child->newFile();
child->show();
}
void MdiWindow::open()
{
YQ_LOG_DEBUG("open");
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty()) {
QMdiSubWindow *existing = findMdiChild(fileName);
if (existing) {
mdiArea->setActiveSubWindow(existing);
return;
}
if (openFile(fileName))
statusBar()->showMessage(tr("File loaded"), 2000);
}
}
bool MdiWindow::openFile(const QString &fileName)
{
YQ_LOG_DEBUG("openFile %s", fileName.toLatin1().data());
MdiChild *child = createMdiChild();
const bool succeeded = child->loadFile(fileName);
if (succeeded)
child->show();
else
child->close();
return succeeded;
}
void MdiWindow::save()
{
YQ_LOG_DEBUG("save");
if (activeMdiChild() && activeMdiChild()->save())
statusBar()->showMessage(tr("File saved"), 2000);
}
void MdiWindow::saveAs()
{
YQ_LOG_DEBUG("saveAs");
if (activeMdiChild() && activeMdiChild()->saveAs())
statusBar()->showMessage(tr("File saved"), 2000);
}
#ifndef QT_NO_CLIPBOARD
void MdiWindow::cut()
{
if (activeMdiChild())
activeMdiChild()->cut();
}
void MdiWindow::copy()
{
if (activeMdiChild())
activeMdiChild()->copy();
}
void MdiWindow::paste()
{
if (activeMdiChild())
activeMdiChild()->paste();
}
#endif
void MdiWindow::support()
{
QDesktopServices::openUrl(QUrl("http://www.subflexion.com/MakePDF/support.html"));
lower();
}
void MdiWindow::website()
{
QDesktopServices::openUrl(QUrl("http://www.subflexion.com/MakePDF/about.html"));
}
void MdiWindow::upgradeClicked()
{
QDesktopServices::openUrl(QUrl("http://www.subflexion.com/MakePDF/register.html"));
}
void MdiWindow::bold()
{
if (activeMdiChild()) activeMdiChild()->bold();
}
void MdiWindow::italic()
{
if (activeMdiChild()) activeMdiChild()->italic();
}
void MdiWindow::quote()
{
if (activeMdiChild()) activeMdiChild()->quote();
}
void MdiWindow::code()
{
if (activeMdiChild()) activeMdiChild()->code();
}
void MdiWindow::heading1()
{
if (activeMdiChild()) activeMdiChild()->heading1();
}
void MdiWindow::heading2()
{
if (activeMdiChild()) activeMdiChild()->heading2();
}
void MdiWindow::heading3()
{
if (activeMdiChild()) activeMdiChild()->heading3();
}
void MdiWindow::heading4()
{
if (activeMdiChild()) activeMdiChild()->heading4();
}
void MdiWindow::hyperlink()
{
if (activeMdiChild()) activeMdiChild()->hyperlink();
}
void MdiWindow::image()
{
if (activeMdiChild()) activeMdiChild()->image();
}
void MdiWindow::unorderedList()
{
if (activeMdiChild()) activeMdiChild()->unorderedList();
}
void MdiWindow::orderedList()
{
if (activeMdiChild()) activeMdiChild()->orderedList();
}
void MdiWindow::horizontalRule()
{
if (activeMdiChild()) activeMdiChild()->horizontalRule();
}
void MdiWindow::timestamp()
{
if (activeMdiChild()) activeMdiChild()->timestamp();
}
void MdiWindow::pageNumber()
{
if (activeMdiChild()) activeMdiChild()->pageNumber();
}
void MdiWindow::pageCount()
{
if (activeMdiChild()) activeMdiChild()->pageCount();
}
void MdiWindow::options()
{
}
void MdiWindow::saveAll()
{
}
void MdiWindow::selectAll()
{
if (activeMdiChild()) activeMdiChild()->selectAll();
}
void MdiWindow::del()
{
if (activeMdiChild()) activeMdiChild()->del();
}
void MdiWindow::undo()
{
if (activeMdiChild()) activeMdiChild()->undo();
}
void MdiWindow::redo()
{
if (activeMdiChild()) activeMdiChild()->redo();
}
void MdiWindow::find()
{
if (activeMdiChild()) activeMdiChild()->find();
}
void MdiWindow::findNext()
{
if (activeMdiChild()) activeMdiChild()->findNext();
}
void MdiWindow::findPrevious()
{
if (activeMdiChild()) activeMdiChild()->findPrevious();
}
void MdiWindow::goToLine()
{
if (activeMdiChild()) activeMdiChild()->goToLine();
}
#include "html.h"
#include "document.h"
#include "DocConvert.h"
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QHttpPart>
void MdiWindow::handleRequest()
{
if (server->hasPendingConnections())
{
QTcpSocket* sock = server->nextPendingConnection();
sock->waitForReadyRead();
QByteArray ba = sock->readAll();
//if (sock->canReadLine())
{
QString str(ba);
QStringList tokens = str.split(QRegExp("[ \r\n][ \r\n]*"));
bool haveGet = false;
bool haveDoc = false;
for (int i = 0; i < tokens.size(); i++) {
if (tokens[i] == "GET")
haveGet = true;
if (tokens[i].contains(QString("pdf"), Qt::CaseInsensitive))
haveDoc = true;
}
if (haveGet && haveDoc) //tokens[0] == "GET" && tokens[1].contains(QString("pdf"), Qt::CaseInsensitive ))
{
QTextStream os(sock);
os.setAutoDetectUnicode(true);
os << "HTTP/1.0 200 Ok\r\n"
"Content-Type: application/pdf; charset=\"utf-8\"\r\n"
"Content-Length: " << pdfContents.size() <<
"\r\n"
"\r\n";
//os << pdfContents.data();
//"<h1>Nothing to see here</h1>\n"
//<< QDateTime::currentDateTime().toString() << "\n";
os.flush();
sock->flush();
sock->write(pdfContents.data(), pdfContents.size());
sock->flush();
//sock->write(ba);
}
else
{
QTextStream os(sock);
os.setAutoDetectUnicode(true);
os << "HTTP/1.0 404 Ok\r\n"
"\r\n"
"\r\n";
}
}
sock->waitForBytesWritten();
sock->waitForDisconnected();
sock->close();
delete sock;
}
}
void MdiWindow::setupServer()
{
// setup the web server
server = new QTcpServer;
if (!server->listen(QHostAddress::LocalHost, 12345))
{
qFatal("Failed to open web socket server.");
}
connect(server, SIGNAL(newConnection()), this, SLOT(handleRequest()));
/*
// open a browser window with the client HTML page
QUrl url = QUrl::fromLocalFile(BUILD_DIR "/index.html");
url.setQuery(QStringLiteral("webChannelBaseUrl=") + server.serverUrl().toString());
QDesktopServices::openUrl(url);
dialog.displayMessage(QObject::tr("Initialization complete, opening browser at %1.").arg(url.toDisplayString()));
*/
}
void MdiWindow::updatePreview()
{
MdiChild* child = activeMdiChild();
if (child)
{
static int ver = 0;
//char fileName[1024];
//sprintf(fileName, "test/test-%i.pdf", ver);
ver++;
const char *fileName = "test/test.pdf";
QByteArray text = child->toPlainText().toLatin1();
char* data;
size_t size;
DocConvert converter;
converter.SetSourceData(text.data(), text.size());
converter.Convert();
converter.GetHTMLData(&data, &size);
converter.OutputPDF(fileName);
appWindow->previewText->setText(QString(QLatin1String(data, size)));
pdfContents.resize(5*1024*1024);
size = 5*1024*1024;
converter.GetPDFData(pdfContents.data(), &size);
pdfContents.resize(size);
//pdfContents = QByteArray(data, size);
//QTimer::singleShot(100, this, SLOT(setWebPreviewURL()));
// ../../../build-MakePDF-Desktop-Debug/
//appWindow->webPreview->setUrl(QUrl(QString("file:///home/jryland/Code/applications/MakePDF/3rdParty/pdf.js/web/viewer.html?file=http://localhost:12345/") + fileName));
appWindow->webPreview->setUrl(QUrl(QString("http://localhost:12345/") + fileName));
QTimer::singleShot(1000, this, SLOT(refreshWebPreview()));
}
}
void MdiWindow::setWebPreviewURL()
{
const char *fileName = "test/test.pdf";
appWindow->webPreview->setUpdatesEnabled(false);
//appWindow->webPreview->setUrl(QUrl(QString("file:///home/jryland/Code/applications/MakePDF/3rdParty/pdf.js/web/viewer.html?file=../../../build-MakePDF-Desktop-Debug/") + fileName));
appWindow->webPreview->setUrl(QUrl(QString("file:///home/jryland/Code/applications/MakePDF/build-MakePDF-Desktop-Debug/pdf.js/web/viewer.html?file=../../../build-MakePDF-Desktop-Debug/") + fileName));
QTimer::singleShot(1000, this, SLOT(refreshWebPreview()));
}
void MdiWindow::refreshWebPreview()
{
appWindow->webPreview->setUpdatesEnabled(true);
}
void MdiWindow::updateActions()
{
bool hasMdiChild = (activeMdiChild() != 0);
bool hasSelection = (hasMdiChild && activeMdiChild()->textCursor().hasSelection());
appWindow->actionSave->setEnabled(hasMdiChild);
appWindow->actionSave_As->setEnabled(hasMdiChild);
appWindow->actionSave_All->setEnabled(hasMdiChild);
appWindow->actionClose->setEnabled(hasMdiChild);
#ifndef QT_NO_CLIPBOARD
appWindow->actionCut->setEnabled(hasSelection);
appWindow->actionCopy->setEnabled(hasSelection);
appWindow->actionPaste->setEnabled(hasMdiChild);
#endif
appWindow->actionSelect_All->setEnabled(hasMdiChild);
appWindow->actionDelete->setEnabled(hasMdiChild);
appWindow->actionUndo->setEnabled(hasMdiChild);
appWindow->actionRedo->setEnabled(hasMdiChild);
appWindow->actionFind->setEnabled(hasMdiChild);
appWindow->actionFind_Next->setEnabled(hasMdiChild);
appWindow->actionFind_Previous->setEnabled(hasMdiChild);
appWindow->actionGo_to_Line->setEnabled(hasMdiChild);
appWindow->actionBold->setEnabled(hasMdiChild);
appWindow->actionItalic->setEnabled(hasMdiChild);
appWindow->actionQuote->setEnabled(hasMdiChild);
appWindow->actionCode->setEnabled(hasMdiChild);
appWindow->actionHeading_1->setEnabled(hasMdiChild);
appWindow->actionHeading_2->setEnabled(hasMdiChild);
appWindow->actionHeading_3->setEnabled(hasMdiChild);
appWindow->actionHeading_4->setEnabled(hasMdiChild);
appWindow->actionHyperlink->setEnabled(hasMdiChild);
appWindow->actionImage->setEnabled(hasMdiChild);
appWindow->actionUnordered_List->setEnabled(hasMdiChild);
appWindow->actionOrdered_List->setEnabled(hasMdiChild);
appWindow->actionHorizontal_Rule->setEnabled(hasMdiChild);
appWindow->actionTimestamp->setEnabled(hasMdiChild);
appWindow->actionPage_Number->setEnabled(hasMdiChild);
appWindow->actionPage_Count->setEnabled(hasMdiChild);
appWindow->actionClose_All->setEnabled(hasMdiChild);
appWindow->actionNext->setEnabled(hasMdiChild);
appWindow->actionPrevious->setEnabled(hasMdiChild);
appWindow->action_Tile_Windows->setEnabled(hasMdiChild);
appWindow->action_Windowed->setEnabled(hasMdiChild);
//appWindow->actionTabbed->setEnabled(hasMdiChild);
//separatorAct->setVisible(hasMdiChild);
appWindow->menuView->clear();
appWindow->menuView->addAction(appWindow->action_Tile_Windows);
appWindow->menuView->addAction(appWindow->action_Windowed);
appWindow->menuView->addAction(appWindow->actionTabbed);
appWindow->menuView->addSeparator();
appWindow->menuView->addAction(appWindow->actionNext);
appWindow->menuView->addAction(appWindow->actionPrevious);
QList<QMdiSubWindow *> windows = mdiArea->subWindowList();
if (!windows.isEmpty())
appWindow->menuView->addSeparator();
for (int i = 0; i < windows.size(); ++i) {
MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget());
QString text = QString("%1 %2").arg(i + 1).arg(child->userFriendlyCurrentFile());
if (i < 9)
text = "&" + text;
QAction *action = appWindow->menuView->addAction(text);
action->setCheckable(true);
action->setChecked(child == activeMdiChild());
connect(action, SIGNAL(triggered(bool)), windowMapper, SLOT(map()));
windowMapper->setMapping(action, windows.at(i));
}
}
MdiChild *MdiWindow::createMdiChild()
{
MdiChild *child = new MdiChild;
mdiArea->addSubWindow(child);
connect(child, SIGNAL(documentContentsChanged()), this, SLOT(updatePreview()));
connect(child, SIGNAL(closing()), this, SLOT(updateActions()));
#ifndef QT_NO_CLIPBOARD
connect(child, SIGNAL(copyAvailable(bool)), appWindow->actionCut, SLOT(setEnabled(bool)));
connect(child, SIGNAL(copyAvailable(bool)), appWindow->actionCopy, SLOT(setEnabled(bool)));
#endif
return child;
}
void MdiWindow::cascadeSubWindows()
{
mdiArea->setViewMode(QMdiArea::SubWindowView);
mdiArea->cascadeSubWindows();
}
void MdiWindow::tileSubWindows()
{
mdiArea->setViewMode(QMdiArea::SubWindowView);
mdiArea->tileSubWindows();
}
void MdiWindow::tabSubWindows()
{
mdiArea->setViewMode(QMdiArea::TabbedView);
}
void MdiWindow::readLicense()
{
YQ_LOG_DEBUG("Reading license");
QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "Subflexion", "MakePDF");
}
void MdiWindow::readSettings()
{
YQ_LOG_DEBUG("Reading settings");
QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "Subflexion", "MakePDF");
settings.beginGroup("MainWindow");
restoreState(settings.value("DockLayout").toByteArray());
move(settings.value("Position", QPoint(200, 200)).toPoint());
resize(settings.value("Size", QSize(400, 400)).toSize());
settings.endGroup();
settings.beginGroup("License");
QString user = settings.value("User").toString();
QString licenseType = settings.value("Type").toString();
settings.endGroup();
}
void MdiWindow::writeSettings()
{
YQ_LOG_DEBUG("Saving settings");
QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "Subflexion", "MakePDF");
settings.beginGroup("MainWindow");
settings.setValue("DockLayout", saveState());
settings.setValue("Position", pos());
settings.setValue("Size", size());
settings.endGroup();
}
MdiChild *MdiWindow::activeMdiChild()
{
if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
return qobject_cast<MdiChild *>(activeSubWindow->widget());
return 0;
}
QMdiSubWindow *MdiWindow::findMdiChild(const QString &fileName)
{
QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
foreach (QMdiSubWindow *window, mdiArea->subWindowList()) {
MdiChild *mdiChild = qobject_cast<MdiChild *>(window->widget());
if (mdiChild && mdiChild->currentFile() == canonicalFilePath)
return window;
}
return 0;
}
void MdiWindow::switchLayoutDirection()
{
if (layoutDirection() == Qt::LeftToRight)
qApp->setLayoutDirection(Qt::RightToLeft);
else
qApp->setLayoutDirection(Qt::LeftToRight);
}
void MdiWindow::setActiveSubWindow(QWidget *window)
{
if (!window)
return;
mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
}
#include "Objects.h"
QObject* MakeTestObjectTree()
{
QObject* o = new MyObjectTest;
return o;
}
void EnumEditor::ListSelectionChanged()
{
QList<QListWidgetItem*> items = lw->selectedItems();
if (!items.count())
return;
QString combinedString = items.at(0)->text();
for (int i = 1; i < items.count(); i++)
combinedString += " | " + items.at(i)->text();
int value = m_metaEnum.keysToValue(combinedString.toLocal8Bit().data());
sb->setValue(value);
str->setText(m_metaEnum.valueToKeys(value).data());
}
void EnumEditor::ComboSelectionChanged()
{
QString combinedString = cb->currentText();
sb->setValue(m_metaEnum.keysToValue(combinedString.toLocal8Bit().data()));
str->setText(combinedString);
}
EnumEditor::EnumEditor(QMetaEnum metaEnum)
{
m_metaEnum = metaEnum;
QGridLayout* grid = new QGridLayout();
QLabel* l1 = new QLabel("Name");
QLabel* l2 = new QLabel("Enum");
QLabel* l3 = new QLabel("Value");
QLabel* l4 = new QLabel("String");
grid->addWidget(l1, 0, 0);
grid->addWidget(l2, 1, 0);
grid->addWidget(l3, 2, 0);
grid->addWidget(l4, 3, 0);
QLabel* v1 = new QLabel(metaEnum.name());
QWidget* v2 = 0;
if (metaEnum.isFlag())
{
lw = new QListWidget();
lw->setSelectionMode(QAbstractItemView::MultiSelection);
for (int i = 0; i < metaEnum.keyCount(); i++)
{
lw->addItem(metaEnum.valueToKey(metaEnum.value(i)));
}
v2 = lw;
connect(lw, SIGNAL(itemSelectionChanged()), this, SLOT(ListSelectionChanged()));
}
else
{
cb = new QComboBox();
for (int i = 0; i < metaEnum.keyCount(); i++)
{
cb->addItem(metaEnum.valueToKey(metaEnum.value(i)));
}
connect(cb, SIGNAL(currentIndexChanged(int)), this, SLOT(ComboSelectionChanged()));
v2 = cb;
}
sb = new QSpinBox();
str = new QLabel();
grid->addWidget(v1, 0, 1);
grid->addWidget(v2, 1, 1);
grid->addWidget(sb, 2, 1);
grid->addWidget(str, 3, 1);
setLayout(grid);
show();
}
void EnumPropertyEditorTest()
{
MyObjectTest* o = new MyObjectTest;
for (int i = 0; i < o->metaObject()->enumeratorCount(); i++)
new EnumEditor(o->metaObject()->enumerator(i));
}
#include "ObjectVisitor.h"
class SerializeVisitor : public Visitor
{
public:
SerializeVisitor(const char* fileName) { file = fopen(fileName, "wb"); }
virtual ~SerializeVisitor() { fclose(file); }
virtual void enterObject(const char* className, const char* objectName)
{
std::string p = (path.size()) ? path.back() + "/" : "";
path.push_back(p + objectName);
fprintf(file, "[%s]\n", path.back().c_str());
fprintf(file, "class=%s\n", className);
}
virtual void leaveObject(const char* className, const char* objectName)
{
fprintf(file, "; end of %s\n\n", objectName);
path.pop_back();
//fprintf(file, "--Leaving %s (%s)\n", objectName, className);
}
virtual void visit(const char* className,
const char* propertyName, QVariant::Type typ, QVariant& value)
{
//fprintf(file, "----Property: %s %s::%s = %s\n", QVariant::typeToName(typ),
// className, propertyName, value.toString().toLocal8Bit().data());
fprintf(file, "%s=%s\n", propertyName, value.toString().toLocal8Bit().data());
}
private:
FILE* file;
std::vector<std::string> path;
};
#include <QLayout>
#include <QAction>
#include <QActionGroup>
#include <QPdfWriter>
#define CLASS_FACTORY(ClassName, ...) \
else if (strcmp(className, #ClassName) == 0) return new ClassName(__VA_ARGS__)
QObject* classObjectFactory(const char* className)
{
if (false) {}
CLASS_FACTORY(QObject);
CLASS_FACTORY(QWidget);
CLASS_FACTORY(QTableView);
CLASS_FACTORY(QTableWidget);
CLASS_FACTORY(QLabel);
CLASS_FACTORY(QPushButton);
CLASS_FACTORY(QVBoxLayout);
CLASS_FACTORY(QHBoxLayout);
CLASS_FACTORY(QAction, nullptr);
CLASS_FACTORY(QActionGroup, nullptr);
CLASS_FACTORY(QButtonGroup);
CLASS_FACTORY(QFileSelector);
//CLASS_FACTORY(QPdfWriter);
//CLASS_FACTORY(QSound);
CLASS_FACTORY(QThread);
CLASS_FACTORY(QTimer);
printf("Unrecognized class name, ignoring\n");
return 0;
}
class DeserializeVisitor : public Visitor
{
public:
DeserializeVisitor(const char* fileName) { file = fopen(fileName, "rb"); }
virtual ~DeserializeVisitor() { fclose(file); }
virtual void enterObject(const char* className, const char* objectName)
{
std::string p = (path.size()) ? path.back() + "/" : "";
path.push_back(p + objectName);
fprintf(file, "[%s]\n", path.back().c_str());
fprintf(file, "class=%s\n", className);
}
virtual void leaveObject(const char* className, const char* objectName)
{
fprintf(file, "; end of %s\n\n", objectName);
path.pop_back();
//fprintf(file, "--Leaving %s (%s)\n", objectName, className);
}
virtual void visit(const char* className,
const char* propertyName, QVariant::Type typ, QVariant& value)
{
//fprintf(file, "----Property: %s %s::%s = %s\n", QVariant::typeToName(typ),
// className, propertyName, value.toString().toLocal8Bit().data());
fprintf(file, "%s=%s\n", propertyName, value.toString().toLocal8Bit().data());
}
virtual bool isWriting()
{
return true;
}
private:
FILE* file;
std::vector<std::string> path;
};
#include "qtpropertymanager.h"
#include "qtvariantproperty.h"
#include "qttreepropertybrowser.h"
#include "qtgroupboxpropertybrowser.h"
#include "ObjectTreeModel.h"
static QWidget *WrapWidgetInLayout(QWidget* wrapper, QWidget* w)
{
QVBoxLayout *layout = new QVBoxLayout;
wrapper->setLayout(layout);
layout->addWidget(w);
layout->setMargin(0);
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
return wrapper;
}
void MdiWindow::updatePropertiesView(QObject *object)
{
// Dynamically build the properties UI elements for the given object's properties
QtVariantPropertyManager *variantManager = new QtVariantPropertyManager();
QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory();
QtAbstractPropertyBrowser *groupEditor = new QtGroupBoxPropertyBrowser();
groupEditor->setFactoryForManager(variantManager, variantFactory);
QtTreePropertyBrowser *variantEditor = new QtTreePropertyBrowser();
variantEditor->setFactoryForManager(variantManager, variantFactory);
std::map<std::string, QtProperty*> pmap;
for (int i = 0; i < object->metaObject()->propertyCount(); i++)
{
const QMetaProperty& property = object->metaObject()->property(i);
std::string className = property.enclosingMetaObject()->className();
QtProperty *parentItem = nullptr;
if (pmap.find(className) == pmap.end()) {
parentItem = variantManager->addProperty(QtVariantPropertyManager::groupTypeId(), className.c_str());
pmap.insert(std::make_pair(className, parentItem));
groupEditor->addProperty(parentItem);
variantEditor->addProperty(parentItem);
} else {
parentItem = pmap[className];
}
QtVariantProperty *item = variantManager->addProperty(property.type(), property.name());
if ( item ) {
item->setValue(property.read(object));
parentItem->addSubProperty(item);
}
}
variantEditor->setIndentation(30);
variantEditor->setPropertiesWithoutValueMarked(true);
variantEditor->setRootIsDecorated(false);
QScrollArea *scrollArea = new QScrollArea;
scrollArea->setWidget(groupEditor);
QTabWidget *tabs = new QTabWidget;
tabs->addTab(WrapWidgetInLayout(new QWidget, variantEditor), "Property List");
tabs->addTab(WrapWidgetInLayout(new QWidget, scrollArea), "Grouped");
foreach (QObject* child, appWindow->propertiesView->children())
if (child->isWidgetType())
delete child;
QLayout* lo = appWindow->propertiesView->layout();
if (lo) {
lo->addWidget(tabs);
} else {
WrapWidgetInLayout(appWindow->propertiesView, tabs);
}
//QObject::connect(variantManager, SIGNAL(propertyChanged(QtProperty*)), &blah, SLOT(updateProp(QtProperty*)));
}
void MdiWindow::changePropertiesObject(const QModelIndex &index)
{
QObject* ptr = (QObject*)index.internalPointer();
if (ptr)
updatePropertiesView(ptr);
}
void MdiWindow::changeRootObject(const QModelIndex &index)
{
QObject* ptr = (QObject*)index.internalPointer();
if (ptr)
updateObjectTree(ptr);
}
void MdiWindow::changeProjectTree(QObject *rootObject)
{
QList<ObjPtr> list;
list.append(ObjPtr(rootObject));
if (appWindow->projectsView->model()) {
((ObjectTreeModel *)appWindow->projectsView->model())->setRootObjects(list);
} else {
ObjectTreeModel *objectTree = new ObjectTreeModel(appWindow->projectsView);
objectTree->setRootObjects(list);
appWindow->projectsView->setModel(objectTree);
}
appWindow->projectsView->header()->hide();
QObject::connect(appWindow->projectsView, SIGNAL(clicked(const QModelIndex &)),
this, SLOT(changeRootObject(const QModelIndex &)));
}
void MdiWindow::updateObjectTree(QObject *rootObject)
{
SerializeVisitor visitor("/tmp/object-dump.txt");
Visit(visitor, rootObject);
QList<ObjPtr> list;
list.append(ObjPtr(rootObject));
if (appWindow->objectsView->model()) {
((ObjectTreeModel *)appWindow->objectsView->model())->setRootObjects(list);
} else {
ObjectTreeModel *objectTree = new ObjectTreeModel(appWindow->objectsView);
objectTree->setRootObjects(list);
appWindow->objectsView->setModel(objectTree);
}
appWindow->objectsView->header()->hide();
QObject::connect(appWindow->objectsView, SIGNAL(doubleClicked(const QModelIndex &)),
this, SLOT(changeRootObject(const QModelIndex &)));
QObject::connect(appWindow->objectsView, SIGNAL(clicked(const QModelIndex &)),
this, SLOT(changePropertiesObject(const QModelIndex &)));
}