Commit bf8d8955 authored by Victor Yacovlev's avatar Victor Yacovlev

New secondary window/docking implemenetation (X11 only)

parent ddf8580b
This diff is collapsed.
This diff is collapsed.
......@@ -2,26 +2,79 @@
<!DOCTYPE TS>
<TS version="2.0" language="ru_RU">
<context>
<name>Widgets::SecondaryWindowPrivate</name>
<name>Widgets::DeclarativeSettingsPageImpl</name>
<message>
<location filename="../../../src/shared/widgets/declarativesettingspage_impl.cpp" line="136"/>
<source>Choose color</source>
<translation>Выбор цвета</translation>
</message>
</context>
<context>
<name>Widgets::DockWindowPlaceContainer</name>
<message>
<location filename="../../../src/shared/widgets/dockwindowplace_container.cpp" line="106"/>
<source>Detach to separate window</source>
<translation>Сделать отдельным окном</translation>
</message>
</context>
<context>
<name>Widgets::MultiPageDialogImpl</name>
<message>
<location filename="../../../src/shared/widgets/multipagedialog_impl.cpp" line="34"/>
<source>OK</source>
<translation>ОК</translation>
</message>
<message>
<location filename="../../../src/shared/widgets/multipagedialog_impl.cpp" line="38"/>
<source>Cancel</source>
<translation>Отмена</translation>
</message>
<message>
<location filename="../../../src/shared/widgets/multipagedialog_impl.cpp" line="42"/>
<source>Reset to Defaults</source>
<translation>Сброс настроек</translation>
</message>
</context>
<context>
<name>Widgets::SecondaryWindowGenericImplementation</name>
<message>
<location filename="../../../src/shared/widgets/secondarywindow.cpp" line="482"/>
<location filename="../../../src/shared/widgets/secondarywindow_generic.cpp" line="50"/>
<source>Toggle stay on top</source>
<translation>Поверх всех окон</translation>
</message>
<message>
<location filename="../../../src/shared/widgets/secondarywindow.cpp" line="511"/>
<source>Minimize</source>
<location filename="../../../src/shared/widgets/secondarywindow_generic.cpp" line="56"/>
<source>Minimize window</source>
<translation>Свернуть</translation>
</message>
<message>
<location filename="../../../src/shared/widgets/secondarywindow.cpp" line="522"/>
<location filename="../../../src/shared/widgets/secondarywindow_generic.cpp" line="61"/>
<source>Dock to main window</source>
<translation>Прикрепить к главному окну</translation>
</message>
<message>
<location filename="../../../src/shared/widgets/secondarywindow_generic.cpp" line="67"/>
<source>Close window</source>
<translation>Закрыть</translation>
</message>
</context>
<context>
<name>Widgets::SecondaryWindowPrivate</name>
<message>
<source>Toggle stay on top</source>
<translation type="obsolete">Поверх всех окон</translation>
</message>
<message>
<source>Minimize</source>
<translation type="obsolete">Свернуть</translation>
</message>
<message>
<source>Docking</source>
<translation>Прикрепление к главному окну</translation>
<translation type="obsolete">Прикрепление к главному окну</translation>
</message>
<message>
<location filename="../../../src/shared/widgets/secondarywindow.cpp" line="533"/>
<source>Close</source>
<translation>Закрыть</translation>
<translation type="obsolete">Закрыть</translation>
</message>
</context>
</TS>
[Dolphin]
PreviewsShown=true
Timestamp=2013,8,29,20,48,18
Version=3
......@@ -68,7 +68,7 @@ if(NOT APPLE)
add_subdirectory(kumir2-highgrade)
add_subdirectory(kumir2-ide)
add_subdirectory(kumir2-teacher)
add_subdirectory(kumir2-python)
#add_subdirectory(kumir2-python)
endif(NOT APPLE)
......
......@@ -10,7 +10,7 @@ add_subdirectory(coursemanager)
# add_subdirectory(pascalanalizer)
find_package(PythonLibs 3.2)
if(PYTHONLIBS_FOUND)
add_subdirectory(python3language)
#add_subdirectory(python3language)
else()
message(WARNING "No Python 3.x libs found, building of Python language support disabled")
endif()
......@@ -43,19 +43,27 @@ MainWindow::MainWindow(Plugin * p) :
helpPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/HelpDockPlace");
centralRow_->addComponent(helpPlace_, false);
connect(helpPlace_, SIGNAL(visiblityRequest(bool,QSize)), centralRow_, SLOT(handleVisiblityRequest(bool,QSize)));
connect(helpPlace_, SIGNAL(visiblityRequest(bool,QSize)),
centralRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
debuggerPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/DebuggerDockPlace");
bottomRow_->addComponent(debuggerPlace_, false);
connect(debuggerPlace_, SIGNAL(visiblityRequest(bool,QSize)), bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)));
connect(debuggerPlace_, SIGNAL(visiblityRequest(bool,QSize)),
bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
consoleAndCourcesPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/ConsoleDockPlace");
bottomRow_->addComponent(consoleAndCourcesPlace_, true);
connect(consoleAndCourcesPlace_, SIGNAL(visiblityRequest(bool,QSize)), bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)));
connect(consoleAndCourcesPlace_, SIGNAL(visiblityRequest(bool,QSize)),
bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
actorsPlace_ = new Widgets::DockWindowPlace(this, "MainWindow/ActorsDockPlace");
bottomRow_->addComponent(actorsPlace_, false);
connect(actorsPlace_, SIGNAL(visiblityRequest(bool,QSize)), bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)));
connect(actorsPlace_, SIGNAL(visiblityRequest(bool,QSize)),
bottomRow_, SLOT(handleVisiblityRequest(bool,QSize)),
Qt::DirectConnection);
connect(ui->actionShow_Console_Pane, SIGNAL(triggered(bool)), this, SLOT(setBottomVisible(bool)));
......@@ -219,13 +227,13 @@ QSize MainWindow::minimumSizeHint() const
statusBar_->minimumHeight() + 10;
int minDockedH = m_plugin->terminal_->minimumHeight();
int minDockedW = 0;
for (int i=0; i<m_plugin->secondaryWindows_.size(); i++) {
Widgets::SecondaryWindow * w = m_plugin->secondaryWindows_[i];
if (w->isVisible() && !w->isFloating()) {
minDockedH = qMax(minDockedH, w->minimumHeight());
minDockedW = qMax(minDockedW, w->minimumWidth());
}
}
// for (int i=0; i<m_plugin->secondaryWindows_.size(); i++) {
// Widgets::SecondaryWindow * w = m_plugin->secondaryWindows_[i];
// if (w->isVisible() && !w->isFloating()) {
// minDockedH = qMax(minDockedH, w->minimumHeight());
// minDockedW = qMax(minDockedW, w->minimumWidth());
// }
// }
int minBottom = m_plugin->terminal_->minimumWidth() +
minDockedW + 10;
minW = qMax(minW, minBottom);
......@@ -880,7 +888,7 @@ void MainWindow::newProgram()
void MainWindow::showAlgorithmHelp(const QString &name)
{
m_plugin->helpWindow_->show();
m_plugin->helpWindow_->activate();
m_plugin->helpViewer_->selectAlgorithm(name);
}
......
......@@ -94,7 +94,8 @@ QString Plugin::initialize(const QStringList & parameters, const ExtensionSystem
if (!plugin_editor)
return "Can't load editor plugin!";
terminal_ = new Term(mainWindow_);
mainWindow_->consoleAndCourcesPlace_->addPersistentWidget(terminal_);
mainWindow_->consoleAndCourcesPlace_->addPersistentWidget(terminal_,
tr("Input/Output"));
connect(terminal_, SIGNAL(showWindowRequest()),
mainWindow_, SLOT(ensureBottomVisible()));
......@@ -171,19 +172,18 @@ QString Plugin::initialize(const QStringList & parameters, const ExtensionSystem
helpViewer_->addDocument(QUrl::fromLocalFile(helpPath + "default.xml"));
helpWindow_ = new Widgets::SecondaryWindow(
helpWindow_ = Widgets::SecondaryWindow::createSecondaryWindow(
helpViewer_,
mainWindow_->helpPlace_,
tr("Help"),
mainWindow_,
mySettings(),
"HelpViewerWindow");
helpWindow_->setWindowTitle(tr("Help"));
helpWindow_->toggleViewAction()->setShortcut(QKeySequence("F1"));
mainWindow_->helpPlace_,
"HelpViewerWindow",
true
);
connect(mainWindow_->ui->actionUsage, SIGNAL(triggered()),
helpWindow_->toggleViewAction(), SLOT(trigger()));
connect(helpWindow_->toggleViewAction(), SIGNAL(toggled(bool)),
mainWindow_->ui->actionUsage, SLOT(setChecked(bool)));
helpWindow_, SLOT(activate()));
secondaryWindows_ << helpWindow_;
courseManager_ = ExtensionSystem::PluginManager::instance()
......@@ -194,16 +194,23 @@ QString Plugin::initialize(const QStringList & parameters, const ExtensionSystem
mainWindow_->ui->menubar->insertMenu(mainWindow_->ui->menuHelp->menuAction(), menu);
}
Widgets::SecondaryWindow * coursesWindow = new Widgets::SecondaryWindow(
coursesWindow_ = Widgets::SecondaryWindow::createSecondaryWindow(
courseManager_->mainWindow(),
mainWindow_->consoleAndCourcesPlace_,
tr("Courses"),
mainWindow_,
mySettings(),
"CoursesWindow"
mainWindow_->consoleAndCourcesPlace_,
"CoursesWindow",
true
);
QAction * showCourses =
mainWindow_->ui->menuWindow->addAction(
tr("Courses"),
coursesWindow_, SLOT(activate())
);
mainWindow_->ui->menuWindow->addAction(coursesWindow->toggleViewAction());
mainWindow_->gr_otherActions->addAction(coursesWindow->toggleViewAction());
mainWindow_->gr_otherActions->addAction(showCourses);
secondaryWindows_ << coursesWindow_;
}
KPlugin * kumirRunner = ExtensionSystem::PluginManager::instance()
......@@ -223,34 +230,34 @@ QString Plugin::initialize(const QStringList & parameters, const ExtensionSystem
if (actor->mainWidget()) {
QWidget * actorWidget = actor->mainWidget();
QList<QMenu*> actorMenus = actor->moduleMenus();
bool priv = o->property("privilegedActor").toBool();
// w = m_mainWindow->addSecondaryComponent(actor->name(),
// actorWidget,
// QList<QAction*>(),
// actorMenus,
// priv? MainWindow::StandardActor : MainWindow::WorldActor);
Widgets::SecondaryWindow * actorWindow = new Widgets::SecondaryWindow(
Widgets::SecondaryWindow * actorWindow =
Widgets::SecondaryWindow::createSecondaryWindow(
actorWidget,
mainWindow_->actorsPlace_,
actor->name(),
mainWindow_,
o->pluginSettings(),
o->pluginSpec().name
mainWindow_->actorsPlace_,
o->pluginSpec().name,
true
);
const QString actorName = actor->name();
actorWindow->setWindowTitle(actorName);
w = actorWindow;
mainWindow_->ui->menuWindow->addAction(actorWindow->toggleViewAction());
secondaryWindows_ << actorWindow;
QAction * showActor =
mainWindow_->ui->menuWindow->addAction(
actor->name(),
actorWindow,
SLOT(activate())
);
mainWindow_->gr_otherActions->addAction(showActor);
if (!actor->mainIconName().isEmpty()) {
const QString iconFileName = QCoreApplication::instance()->property("sharePath").toString()+"/icons/actors/"+actor->mainIconName()+".png";
const QString smallIconFileName = QCoreApplication::instance()->property("sharePath").toString()+"/icons/actors/"+actor->mainIconName()+"_22x22.png";
QIcon mainIcon = QIcon(iconFileName);
if (QFile::exists(smallIconFileName))
mainIcon.addFile(smallIconFileName, QSize(22,22));
actorWindow->setWindowIcon(mainIcon);
actorWindow->toggleViewAction()->setIcon(mainIcon);
mainWindow_->gr_otherActions->addAction(actorWindow->toggleViewAction());
showActor->setIcon(mainIcon);
}
foreach (QMenu* menu, actorMenus) {
......@@ -258,22 +265,34 @@ QString Plugin::initialize(const QStringList & parameters, const ExtensionSystem
}
if (actor->pultWidget()) {
Widgets::SecondaryWindow * pultWindow = new Widgets::SecondaryWindow(
Widgets::SecondaryWindow * pultWindow =
Widgets::SecondaryWindow::createSecondaryWindow(
actor->pultWidget(),
actor->name() + " - " + tr("Remote Control"),
mainWindow_,
mySettings(),
actor->name()+"Pult");
pultWindow->setWindowTitle(actor->name()+" - "+tr("Remote Control"));
mainWindow_->ui->menuWindow->addAction(pultWindow->toggleViewAction());
nullptr,
o->pluginSpec().name + "Pult",
false
);
secondaryWindows_ << pultWindow;
QAction * showPult =
mainWindow_->ui->menuWindow->addAction(
actor->name() + " - " + tr("Remote Control"),
pultWindow,
SLOT(activate())
);
mainWindow_->gr_otherActions->addAction(showPult);
if (!actor->pultIconName().isEmpty()) {
const QString iconFileName = QCoreApplication::instance()->property("sharePath").toString()+"/icons/actors/"+actor->pultIconName()+".png";
const QString smallIconFileName = QCoreApplication::instance()->property("sharePath").toString()+"/icons/actors/"+actor->pultIconName()+"_22x22.png";
QIcon pultIcon = QIcon(iconFileName);
if (QFile::exists(smallIconFileName))
pultIcon.addFile(smallIconFileName, QSize(22,22));
pultWindow->setWindowIcon(pultIcon);
pultWindow->toggleViewAction()->setIcon(pultIcon);
mainWindow_->gr_otherActions->addAction(pultWindow->toggleViewAction());
showPult->setIcon(pultIcon);
}
}
......@@ -298,20 +317,20 @@ QString Plugin::initialize(const QStringList & parameters, const ExtensionSystem
mainWindow_, SLOT(newText(QString,QString)));
debugger_ = new DebuggerView(plugin_kumirCodeRun);
Widgets::SecondaryWindow * debuggerWindow = new Widgets::SecondaryWindow(
Widgets::SecondaryWindow * debuggerWindow =
Widgets::SecondaryWindow::createSecondaryWindow(
debugger_,
mainWindow_->debuggerPlace_,
tr("Variables"),
mainWindow_,
mySettings(),
"DebuggerWindow");
mainWindow_->debuggerPlace_,
"DebuggerWindow",
true
);
secondaryWindows_ << debuggerWindow;
debuggerWindow->setWindowTitle(tr("Variables"));
debuggerWindow->toggleViewAction()->setShortcut(QKeySequence("F2"));
connect(mainWindow_->ui->actionVariables, SIGNAL(triggered()),
debuggerWindow->toggleViewAction(), SLOT(trigger()));
connect(debuggerWindow->toggleViewAction(), SIGNAL(toggled(bool)),
mainWindow_->ui->actionVariables, SLOT(setChecked(bool)));
debuggerWindow, SLOT(activate()));
return "";
}
......@@ -320,13 +339,26 @@ QString Plugin::initialize(const QStringList & parameters, const ExtensionSystem
void Plugin::updateSettings(const QStringList & keys)
{
foreach (Widgets::SecondaryWindow * window, secondaryWindows_) {
window->setSettingsObject(mySettings());
const QString prefix = window->settingsKey() + "/";
bool hasPrefix = false;
foreach (const QString & key, keys) {
if (key.startsWith(prefix)) {
hasPrefix = true;
break;
}
}
if (keys.isEmpty() || hasPrefix) {
QStringList windowKeys;
foreach (const QString & key , keys) {
if (key.startsWith(prefix)) {
windowKeys.push_back(key);
}
}
window->updateSettings(mySettings(), windowKeys);
}
}
if (mainWindow_)
mainWindow_->updateSettings(mySettings(), keys);
if (helpViewer_ && keys.contains("HelpViewer")) {
helpViewer_->updateSettings(mySettings(), "HelpViewer");
}
}
......
......@@ -83,6 +83,7 @@ protected:
Browser::InstanceInterface * startPage_;
QList<Widgets::SecondaryWindow*> secondaryWindows_;
Widgets::SecondaryWindow* helpWindow_;
Widgets::SecondaryWindow* coursesWindow_;
Term * terminal_;
QMap<QString,QObject*> m_browserObjects;
KumirProgram * kumirProgram_;
......
......@@ -11,25 +11,28 @@ set(SOURCES
groupbox.cpp
cyrillicmenu.cpp
secondarywindow.cpp
secondarywindow_impl.cpp
dockwindowplace.cpp
dockwindowplace_impl.cpp
dockwindowplace_container.cpp
multipagedialog.cpp
multipagedialog_impl.cpp
declarativesettingspage.cpp
declarativesettingspage_impl.cpp
secondarywindow_generic.cpp
)
set(MOC_HEADERS
groupbox.h
cyrillicmenu.h
secondarywindow.h
secondarywindow_impl.h
dockwindowplace.h
dockwindowplace_container.h
dockwindowplace_impl.h
multipagedialog.h
multipagedialog_impl.h
declarativesettingspage.h
declarativesettingspage_impl.h
secondarywindow_generic.h
)
qt4_wrap_cpp(MOC_SOURCES ${MOC_HEADERS})
......
#include "dockwindowplace.h"
#include "dockwindowplace_impl.h"
#include "extensionsystem/settings.h"
#include <QTabBar>
#include <QResizeEvent>
#include <QDebug>
namespace Widgets {
DockWindowPlace::DockWindowPlace(QWidget *parent,
......@@ -10,6 +16,52 @@ DockWindowPlace::DockWindowPlace(QWidget *parent,
{
setAutoFillBackground(true);
setTabPosition(QTabWidget::South);
setVisible(false);
}
void DockWindowPlace::tabInserted(int)
{
updateGeometry();
setVisible(true);
tabBar()->setVisible(count() > 1);
emit visiblityRequest(true, sizeHint());
}
void DockWindowPlace::tabRemoved(int)
{
updateGeometry();
setVisible(count() > 0);
tabBar()->setVisible(count() > 1);
emit visiblityRequest(isVisible(), QSize());
}
void DockWindowPlace::resizeEvent(QResizeEvent *e)
{
const QSize minSize = minimumSizeHint();
if (e->size().width() < minSize.width() || e->size().height() < minSize.height()) {
}
else {
QWidget * curW = currentWidget();
if (curW) {
pImpl_->preferredSize_ = curW->size();
}
}
QTabWidget::resizeEvent(e);
}
void DockWindowPlace::setPreferredItemSize(const QSize &size)
{
if (count() == 0) {
pImpl_->preferredSize_ = size;
}
else {
pImpl_->preferredSize_.rwidth() = qMax(
pImpl_->preferredSize_.width(), size.width()
);
pImpl_->preferredSize_.rheight() = qMax(
pImpl_->preferredSize_.height(), size.height()
);
}
}
void DockWindowPlace::registerWindowHere(SecondaryWindow *window)
......@@ -17,9 +69,10 @@ void DockWindowPlace::registerWindowHere(SecondaryWindow *window)
pImpl_->registerWindowHere(window);
}
void DockWindowPlace::addPersistentWidget(QWidget *widget)
void DockWindowPlace::addPersistentWidget(QWidget *widget,
const QString & title)
{
pImpl_->addPersistentWidget(widget);
pImpl_->addPersistentWidget(widget, title);
}
QSize DockWindowPlace::minimumSizeHint() const
......@@ -34,17 +87,29 @@ QSize DockWindowPlace::sizeHint() const
void DockWindowPlace::updateSettings(ExtensionSystem::SettingsPtr settings)
{
pImpl_->updateSettings(settings);
saveState();
pImpl_->settings_ = settings;
restoreState();
}
void DockWindowPlace::saveState()
{
pImpl_->saveState();
if (!pImpl_->settings_) return;
const QString key1 = pImpl_->settingsKey_ + "/DockPlaceSize";
const QString key2 = pImpl_->settingsKey_ + "/NewWidgetSize";
pImpl_->settings_->setValue(key1, size());
pImpl_->settings_->setValue(key2, pImpl_->preferredSize_);
}
void DockWindowPlace::restoreState()
{
pImpl_->restoreState();
if (!pImpl_->settings_) return;
const QString key1 = pImpl_->settingsKey_ + "/DockPlaceSize";
const QString key2 = pImpl_->settingsKey_ + "/NewWidgetSize";
const QSize sz = pImpl_->settings_->value(key1, QSize()).toSize();
resize(sz);
pImpl_->preferredSize_ = pImpl_->settings_->value(key2, QSize()).toSize();
}
} // namespace Widgets