00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "mainwindow.h"
00025 #include "colorswatch.h"
00026 #include "toolbar.h"
00027
00028 #include <QAction>
00029 #include <QLayout>
00030 #include <QMenu>
00031 #include <QMenuBar>
00032 #include <QStatusBar>
00033 #include <QTextEdit>
00034 #include <QFile>
00035 #include <QDataStream>
00036 #include <QFileDialog>
00037 #include <QMessageBox>
00038 #include <QSignalMapper>
00039 #include <QApplication>
00040 #include <qdebug.h>
00041
00042 static const char * const message =
00043 "<p><b>Qt Main Window Demo</b></p>"
00044
00045 "<p>This is a demonstration of the QMainWindow, QToolBar and "
00046 "QDockWidget classes.</p>"
00047
00048 "<p>The tool bar and dock widgets can be dragged around and rearranged "
00049 "using the mouse or via the menu.</p>"
00050
00051 "<p>Each dock widget contains a colored frame and a context "
00052 "(right-click) menu.</p>"
00053
00054 #ifdef Q_WS_MAC
00055 "<p>On Mac OS X, the \"Black\" dock widget has been created as a "
00056 "<em>Drawer</em>, which is a special kind of QDockWidget.</p>"
00057 #endif
00058 ;
00059
00060 MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags)
00061 : QMainWindow(parent, flags)
00062 {
00063 setObjectName("MainWindow");
00064 setWindowTitle("Qt Main Window Demo");
00065
00066 setupToolBar();
00067 setupMenuBar();
00068 setupDockWidgets();
00069
00070 QTextEdit *center = new QTextEdit(this);
00071 center->setReadOnly(true);
00072 center->setHtml(tr(message));
00073 center->setMinimumSize(400, 205);
00074 setCentralWidget(center);
00075
00076 statusBar()->showMessage(tr("Status Bar"));
00077 }
00078
00079 void MainWindow::actionTriggered(QAction *action)
00080 {
00081 qDebug("action '%s' triggered", action->text().toLocal8Bit().data());
00082 }
00083
00084 void MainWindow::setupToolBar()
00085 {
00086 toolbar = new ToolBar(this);
00087 toolbar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
00088 addToolBar(toolbar);
00089 }
00090
00091 void MainWindow::setupMenuBar()
00092 {
00093 QMenu *menu = menuBar()->addMenu(tr("&File"));
00094
00095 QAction *action = menu->addAction(tr("Save layout..."));
00096 connect(action, SIGNAL(triggered()), this, SLOT(saveLayout()));
00097
00098 action = menu->addAction(tr("Load layout..."));
00099 connect(action, SIGNAL(triggered()), this, SLOT(loadLayout()));
00100
00101 action = menu->addAction(tr("Switch layout direction"));
00102 connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection()));
00103
00104 menu->addSeparator();
00105
00106 menu->addAction(tr("&Quit"), this, SLOT(close()));
00107
00108 menuBar()->addMenu(toolbar->menu);
00109 dockWidgetMenu = menuBar()->addMenu(tr("&Dock Widgets"));
00110 }
00111
00112 static void dump(const QByteArray &array)
00113 {
00114 QString s;
00115 for (int i = 0; i < array.count(); ++i) {
00116 s += ' ';
00117 s += QString::number((uchar)array.at(i));
00118 }
00119 qDebug() << "dump():" << s;
00120 }
00121
00122 void MainWindow::saveLayout()
00123 {
00124 QString fileName
00125 = QFileDialog::getSaveFileName(this, tr("Save layout"));
00126 if (fileName.isEmpty())
00127 return;
00128 QFile file(fileName);
00129 if (!file.open(QFile::WriteOnly)) {
00130 QString msg = tr("Failed to open %1\n%2")
00131 .arg(fileName)
00132 .arg(file.errorString());
00133 QMessageBox::warning(this, tr("Error"), msg);
00134 return;
00135 }
00136
00137 QByteArray geo_data = saveGeometry();
00138 QByteArray layout_data = saveState();
00139
00140 bool ok = file.putChar((uchar)geo_data.size());
00141 if (ok)
00142 ok = file.write(geo_data) == geo_data.size();
00143 if (ok)
00144 ok = file.write(layout_data) == layout_data.size();
00145
00146 if (!ok) {
00147 QString msg = tr("Error writing to %1\n%2")
00148 .arg(fileName)
00149 .arg(file.errorString());
00150 QMessageBox::warning(this, tr("Error"), msg);
00151 return;
00152 }
00153 }
00154
00155 void MainWindow::loadLayout()
00156 {
00157 QString fileName
00158 = QFileDialog::getOpenFileName(this, tr("Load layout"));
00159 if (fileName.isEmpty())
00160 return;
00161 QFile file(fileName);
00162 if (!file.open(QFile::ReadOnly)) {
00163 QString msg = tr("Failed to open %1\n%2")
00164 .arg(fileName)
00165 .arg(file.errorString());
00166 QMessageBox::warning(this, tr("Error"), msg);
00167 return;
00168 }
00169
00170 uchar geo_size;
00171 QByteArray geo_data;
00172 QByteArray layout_data;
00173
00174 bool ok = file.getChar((char*)&geo_size);
00175 if (ok) {
00176 geo_data = file.read(geo_size);
00177 ok = geo_data.size() == geo_size;
00178 }
00179 if (ok) {
00180 layout_data = file.readAll();
00181 ok = layout_data.size() > 0;
00182 }
00183
00184 if (ok)
00185 ok = restoreGeometry(geo_data);
00186 if (ok)
00187 ok = restoreState(layout_data);
00188
00189 if (!ok) {
00190 QString msg = tr("Error reading %1")
00191 .arg(fileName);
00192 QMessageBox::warning(this, tr("Error"), msg);
00193 return;
00194 }
00195 }
00196
00197 QAction *addAction(QMenu *menu, const QString &text, QActionGroup *group, QSignalMapper *mapper,
00198 int id)
00199 {
00200 bool first = group->actions().isEmpty();
00201 QAction *result = menu->addAction(text);
00202 result->setCheckable(true);
00203 result->setChecked(first);
00204 group->addAction(result);
00205 QObject::connect(result, SIGNAL(triggered()), mapper, SLOT(map()));
00206 mapper->setMapping(result, id);
00207 return result;
00208 }
00209
00210 void MainWindow::setupDockWidgets()
00211 {
00212 QAction *action = dockWidgetMenu->addAction(tr("Animation"));
00213 action->setCheckable(true);
00214 action->setChecked(isAnimated());
00215 connect(action, SIGNAL(toggled(bool)), this, SLOT(setAnimated(bool)));
00216
00217 action = dockWidgetMenu->addAction(tr("Nesting"));
00218 action->setCheckable(true);
00219 action->setChecked(isDockNestingEnabled());
00220 connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockNestingEnabled(bool)));
00221
00222 dockWidgetMenu->addSeparator();
00223
00224 mapper = new QSignalMapper(this);
00225 connect(mapper, SIGNAL(mapped(int)), this, SLOT(setCorner(int)));
00226
00227 QMenu *corner_menu = dockWidgetMenu->addMenu(tr("Top left corner"));
00228 QActionGroup *group = new QActionGroup(this);
00229 group->setExclusive(true);
00230 ::addAction(corner_menu, tr("Top dock area"), group, mapper, 0);
00231 ::addAction(corner_menu, tr("Left dock area"), group, mapper, 1);
00232
00233 corner_menu = dockWidgetMenu->addMenu(tr("Top right corner"));
00234 group = new QActionGroup(this);
00235 group->setExclusive(true);
00236 ::addAction(corner_menu, tr("Top dock area"), group, mapper, 2);
00237 ::addAction(corner_menu, tr("Right dock area"), group, mapper, 3);
00238
00239 corner_menu = dockWidgetMenu->addMenu(tr("Bottom left corner"));
00240 group = new QActionGroup(this);
00241 group->setExclusive(true);
00242 ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 4);
00243 ::addAction(corner_menu, tr("Left dock area"), group, mapper, 5);
00244
00245 corner_menu = dockWidgetMenu->addMenu(tr("Bottom right corner"));
00246 group = new QActionGroup(this);
00247 group->setExclusive(true);
00248 ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 6);
00249 ::addAction(corner_menu, tr("Right dock area"), group, mapper, 7);
00250
00251 dockWidgetMenu->addSeparator();
00252
00253 static const struct Set {
00254 const char * name;
00255 uint flags;
00256 Qt::DockWidgetArea area;
00257 } sets [] = {
00258 #ifndef Q_WS_MAC
00259 { "Black", 0, Qt::LeftDockWidgetArea },
00260 #else
00261 { "Black", Qt::Drawer, Qt::LeftDockWidgetArea },
00262 #endif
00263 { "White", 0, Qt::RightDockWidgetArea },
00264 { "Red", 0, Qt::TopDockWidgetArea },
00265 { "Green", 0, Qt::TopDockWidgetArea },
00266 { "Blue", 0, Qt::BottomDockWidgetArea },
00267 { "Yellow", 0, Qt::BottomDockWidgetArea }
00268 };
00269 const int setCount = sizeof(sets) / sizeof(Set);
00270
00271 for (int i = 0; i < setCount; ++i) {
00272 ColorSwatch *swatch = new ColorSwatch(tr(sets[i].name), this, Qt::WindowFlags(sets[i].flags));
00273 if (i%2)
00274 swatch->setWindowIcon(QIcon(QPixmap(":/res/qt.png")));
00275 addDockWidget(sets[i].area, swatch);
00276 dockWidgetMenu->addMenu(swatch->menu);
00277 }
00278 }
00279
00280 void MainWindow::setCorner(int id)
00281 {
00282 switch (id) {
00283 case 0:
00284 QMainWindow::setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea);
00285 break;
00286 case 1:
00287 QMainWindow::setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
00288 break;
00289 case 2:
00290 QMainWindow::setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea);
00291 break;
00292 case 3:
00293 QMainWindow::setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
00294 break;
00295 case 4:
00296 QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
00297 break;
00298 case 5:
00299 QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
00300 break;
00301 case 6:
00302 QMainWindow::setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
00303 break;
00304 case 7:
00305 QMainWindow::setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
00306 break;
00307 }
00308 }
00309
00310 void MainWindow::switchLayoutDirection()
00311 {
00312 if (layoutDirection() == Qt::LeftToRight)
00313 qApp->setLayoutDirection(Qt::RightToLeft);
00314 else
00315 qApp->setLayoutDirection(Qt::LeftToRight);
00316 }