1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include <QtWidgets>
52
53#include "mainwindow.h"
54#include "xbelreader.h"
55#include "xbelwriter.h"
56
57//! [0]
58MainWindow::MainWindow()
59{
60 QStringList labels;
61 labels << tr("Title") << tr("Location");
62
63 treeWidget = new QTreeWidget;
64 treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch);
65 treeWidget->setHeaderLabels(labels);
66#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
67 treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
68 connect(treeWidget, &QWidget::customContextMenuRequested,
69 this, &MainWindow::onCustomContextMenuRequested);
70#endif
71 setCentralWidget(treeWidget);
72
73 createMenus();
74
75 statusBar()->showMessage(tr("Ready"));
76
77 setWindowTitle(tr("QXmlStream Bookmarks"));
78 const QSize availableSize = screen()->availableGeometry().size();
79 resize(availableSize.width() / 2, availableSize.height() / 3);
80}
81//! [0]
82
83#if !defined(QT_NO_CONTEXTMENU) && !defined(QT_NO_CLIPBOARD)
84void MainWindow::onCustomContextMenuRequested(const QPoint &pos)
85{
86 const QTreeWidgetItem *item = treeWidget->itemAt(pos);
87 if (!item)
88 return;
89 const QString url = item->text(1);
90 QMenu contextMenu;
91 QAction *copyAction = contextMenu.addAction(tr("Copy Link to Clipboard"));
92 QAction *openAction = contextMenu.addAction(tr("Open"));
93 QAction *action = contextMenu.exec(treeWidget->viewport()->mapToGlobal(pos));
94 if (action == copyAction)
95 QGuiApplication::clipboard()->setText(url);
96 else if (action == openAction)
97 QDesktopServices::openUrl(QUrl(url));
98}
99#endif // !QT_NO_CONTEXTMENU && !QT_NO_CLIPBOARD
100
101//! [1]
102void MainWindow::open()
103{
104 QString fileName =
105 QFileDialog::getOpenFileName(this, tr("Open Bookmark File"),
106 QDir::currentPath(),
107 tr("XBEL Files (*.xbel *.xml)"));
108 if (fileName.isEmpty())
109 return;
110
111 treeWidget->clear();
112
113
114 QFile file(fileName);
115 if (!file.open(QFile::ReadOnly | QFile::Text)) {
116 QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
117 tr("Cannot read file %1:\n%2.")
118 .arg(QDir::toNativeSeparators(fileName),
119 file.errorString()));
120 return;
121 }
122
123 XbelReader reader(treeWidget);
124 if (!reader.read(&file)) {
125 QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
126 tr("Parse error in file %1:\n\n%2")
127 .arg(QDir::toNativeSeparators(fileName),
128 reader.errorString()));
129 } else {
130 statusBar()->showMessage(tr("File loaded"), 2000);
131 }
132
133}
134//! [1]
135
136//! [2]
137void MainWindow::saveAs()
138{
139 QString fileName =
140 QFileDialog::getSaveFileName(this, tr("Save Bookmark File"),
141 QDir::currentPath(),
142 tr("XBEL Files (*.xbel *.xml)"));
143 if (fileName.isEmpty())
144 return;
145
146 QFile file(fileName);
147 if (!file.open(QFile::WriteOnly | QFile::Text)) {
148 QMessageBox::warning(this, tr("QXmlStream Bookmarks"),
149 tr("Cannot write file %1:\n%2.")
150 .arg(QDir::toNativeSeparators(fileName),
151 file.errorString()));
152 return;
153 }
154
155 XbelWriter writer(treeWidget);
156 if (writer.writeFile(&file))
157 statusBar()->showMessage(tr("File saved"), 2000);
158}
159//! [2]
160
161//! [3]
162void MainWindow::about()
163{
164 QMessageBox::about(this, tr("About QXmlStream Bookmarks"),
165 tr("The <b>QXmlStream Bookmarks</b> example demonstrates how to use Qt's "
166 "QXmlStream classes to read and write XML documents."));
167}
168//! [3]
169
170//! [5]
171void MainWindow::createMenus()
172{
173 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
174 QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &MainWindow::open);
175 openAct->setShortcuts(QKeySequence::Open);
176
177 QAction *saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &MainWindow::saveAs);
178 saveAsAct->setShortcuts(QKeySequence::SaveAs);
179
180 QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
181 exitAct->setShortcuts(QKeySequence::Quit);
182
183 menuBar()->addSeparator();
184
185 QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
186 helpMenu->addAction(tr("&About"), this, &MainWindow::about);
187 helpMenu->addAction(tr("About &Qt"), qApp, &QCoreApplication::quit);
188}
189//! [5]
190