diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 7d277f814..7dac660c3 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -132,6 +132,12 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() maxSubView->setToolTip ("If the maximum number is reached and a new subview is opened " "it will be placed into a new top-level window."); + Setting *hide = createSetting (Type_CheckBox, "hide-subview", "Hide single subview"); + hide->setDefaultValue ("false"); + hide->setToolTip ("When a view contains only a single subview, hide the subview title " + "bar and if this subview is closed also close the view (unless it is the last " + "view for this document)"); + Setting *minWidth = createSetting (Type_SpinBox, "minimum-width", "Minimum subview width"); minWidth->setDefaultValue (325); @@ -155,6 +161,52 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() ritd->setDeclaredValues (values); } + declareSection ("table-input", "Table Input"); + { + QString inPlaceEdit ("Edit in Place"); + QString editRecord ("Edit Record"); + QString view ("View"); + QString editRecordAndClose ("Edit Record and Close"); + + QStringList values; + values + << "None" << inPlaceEdit << editRecord << view << "Revert" << "Delete" + << editRecordAndClose << "View and Close"; + + QString toolTip = ""; + + Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click"); + doubleClick->setDeclaredValues (values); + doubleClick->setDefaultValue (inPlaceEdit); + doubleClick->setToolTip ("Action on double click in table:

" + toolTip); + + Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s", + "Shift Double Click"); + shiftDoubleClick->setDeclaredValues (values); + shiftDoubleClick->setDefaultValue (editRecord); + shiftDoubleClick->setToolTip ("Action on shift double click in table:

" + toolTip); + + Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c", + "Control Double Click"); + ctrlDoubleClick->setDeclaredValues (values); + ctrlDoubleClick->setDefaultValue (view); + ctrlDoubleClick->setToolTip ("Action on control double click in table:

" + toolTip); + + Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc", + "Shift Control Double Click"); + shiftCtrlDoubleClick->setDeclaredValues (values); + shiftCtrlDoubleClick->setDefaultValue (editRecordAndClose); + shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:

" + toolTip); + } { /****************************************************************** diff --git a/apps/opencs/view/doc/subview.cpp b/apps/opencs/view/doc/subview.cpp index ab4325cfc..a9dce25be 100644 --- a/apps/opencs/view/doc/subview.cpp +++ b/apps/opencs/view/doc/subview.cpp @@ -3,7 +3,7 @@ #include "view.hpp" CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) - : mUniversalId (id), mParent (NULL) + : mUniversalId (id) { /// \todo add a button to the title bar that clones this sub view @@ -31,7 +31,15 @@ void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id) void CSVDoc::SubView::closeEvent (QCloseEvent *event) { - // update title bars of view and subviews - if(mParent) - mParent->updateSubViewIndicies(this); + emit updateSubViewIndicies (this); } + +std::string CSVDoc::SubView::getTitle() const +{ + return mUniversalId.toString(); +} + +void CSVDoc::SubView::closeRequest() +{ + emit closeRequest (this); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/subview.hpp b/apps/opencs/view/doc/subview.hpp index 6a3ddd8bd..a8aa3cda1 100644 --- a/apps/opencs/view/doc/subview.hpp +++ b/apps/opencs/view/doc/subview.hpp @@ -25,12 +25,13 @@ namespace CSVDoc Q_OBJECT CSMWorld::UniversalId mUniversalId; - View *mParent; // not implemented SubView (const SubView&); SubView& operator= (SubView&); + protected: + void setUniversalId(const CSMWorld::UniversalId& id); public: @@ -47,7 +48,9 @@ namespace CSVDoc virtual void useHint (const std::string& hint); ///< Default implementation: ignored - void setParent(View *parent) { mParent = parent; } + virtual std::string getTitle() const; + + virtual void updateUserSetting (const QString& name, const QStringList& value); private: @@ -57,9 +60,15 @@ namespace CSVDoc void focusId (const CSMWorld::UniversalId& universalId, const std::string& hint); - public slots: - virtual void updateUserSetting - (const QString &, const QStringList &); + void closeRequest (SubView *subView); + + void updateTitle(); + + void updateSubViewIndicies (SubView *view = 0); + + protected slots: + + void closeRequest(); }; } diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index bef0c170d..8a6665cf2 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -300,7 +300,7 @@ void CSVDoc::View::setupUi() setupDebugMenu(); } -void CSVDoc::View::updateTitle(const std::string subview) +void CSVDoc::View::updateTitle() { std::ostringstream stream; @@ -312,8 +312,13 @@ void CSVDoc::View::updateTitle(const std::string subview) if (mViewTotal>1) stream << " [" << (mViewIndex+1) << "/" << mViewTotal << "]"; - if (subview != "") - stream << " - " << subview; + CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); + + bool hideTitle = userSettings.setting ("window/hide-subview", QString ("false"))=="true" && + mSubViews.size()==1 && !mSubViews.at (0)->isFloating(); + + if (hideTitle) + stream << " - " << mSubViews.at (0)->getTitle(); setWindowTitle (stream.str().c_str()); } @@ -323,24 +328,26 @@ void CSVDoc::View::updateSubViewIndicies(SubView *view) if(view && mSubViews.contains(view)) mSubViews.removeOne(view); - if(mSubViews.size() == 1) - { - if(!mSubViews.at(0)->isFloating()) - { - mSubViews.at(0)->setTitleBarWidget(new QWidget(this)); - updateTitle(mSubViews.at(0)->getUniversalId().getTypeName().c_str()); - } - } - else + CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); + + bool hideTitle = userSettings.setting ("window/hide-subview", QString ("false"))=="true" && + mSubViews.size()==1 && !mSubViews.at (0)->isFloating(); + + updateTitle(); + + foreach (SubView *subView, mSubViews) { - updateTitle(); - if(mSubViews.size() > 1) + if (!subView->isFloating()) { - foreach(SubView * sb, mSubViews) + if (hideTitle) { - QWidget * tb = sb->titleBarWidget(); - if(tb) delete tb; - sb->setTitleBarWidget(0); + subView->setTitleBarWidget (new QWidget (this)); + subView->setWindowTitle (QString::fromUtf8 (subView->getTitle().c_str())); + } + else + { + delete subView->titleBarWidget(); + subView->setTitleBarWidget (0); } } } @@ -513,10 +520,12 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this, SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&))); - connect (&CSMSettings::UserSettings::instance(), - SIGNAL (userSettingUpdated (const QString &, const QStringList &)), - view, - SLOT (updateUserSetting (const QString &, const QStringList &))); + connect (view, SIGNAL (closeRequest (SubView *)), this, SLOT (closeRequest (SubView *))); + + connect (view, SIGNAL (updateTitle()), this, SLOT (updateTitle())); + + connect (view, SIGNAL (updateSubViewIndicies (SubView *)), + this, SLOT (updateSubViewIndicies (SubView *))); view->show(); } @@ -729,9 +738,16 @@ void CSVDoc::View::resizeViewHeight (int height) resize (geometry().width(), height); } -void CSVDoc::View::updateUserSetting - (const QString &name, const QStringList &list) -{} +void CSVDoc::View::updateUserSetting (const QString &name, const QStringList &list) +{ + if (name=="window/hide-subview") + updateSubViewIndicies (0); + + foreach (SubView *subView, mSubViews) + { + subView->updateUserSetting (name, list); + } +} void CSVDoc::View::toggleShowStatusBar (bool show) { @@ -761,3 +777,14 @@ void CSVDoc::View::stop() { mDocument->stopRunning(); } + +void CSVDoc::View::closeRequest (SubView *subView) +{ + CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); + + if (mSubViews.size()>1 || mViewTotal<=1 || + userSettings.setting ("window/hide-subview", QString ("false"))!="true") + subView->deleteLater(); + else if (mViewManager.closeRequest (this)) + mViewManager.removeDocAndView (mDocument); +} diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index e3ada1f2e..55ea5ee51 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -75,8 +75,6 @@ namespace CSVDoc void setupUi(); - void updateTitle(const std::string subview = ""); - void updateActions(); void exitApplication(); @@ -114,9 +112,6 @@ namespace CSVDoc /// Function called by view manager when user preferences are updated void updateEditorSetting (const QString &, const QString &); - // called when subviews are added or removed - void updateSubViewIndicies(SubView *view = 0); - signals: void newGameRequest(); @@ -139,6 +134,11 @@ namespace CSVDoc void updateUserSetting (const QString &, const QStringList &); + void updateTitle(); + + // called when subviews are added or removed + void updateSubViewIndicies (SubView *view = 0); + private slots: void newView(); @@ -222,6 +222,8 @@ namespace CSVDoc void run (const std::string& profile, const std::string& startupInstruction = ""); void stop(); + + void closeRequest (SubView *subView); }; } diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 1e106c69f..1ae466f42 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -9,7 +9,7 @@ #include "../widget/scenetoolmode.hpp" CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id) +: SubView (id), mTitle (id.toString().c_str()) { QHBoxLayout *layout = new QHBoxLayout; @@ -52,15 +52,19 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo void CSVWorld::PreviewSubView::setEditLock (bool locked) {} -void CSVWorld::PreviewSubView::closeRequest() +std::string CSVWorld::PreviewSubView::getTitle() const { - deleteLater(); + return mTitle; } void CSVWorld::PreviewSubView::referenceableIdChanged (const std::string& id) { if (id.empty()) - setWindowTitle ("Preview: Reference to "); + mTitle = "Preview: Reference to "; else - setWindowTitle (("Preview: Reference to " + id).c_str()); + mTitle = "Preview: Reference to " + id; + + setWindowTitle (QString::fromUtf8 (mTitle.c_str())); + + emit updateTitle(); } \ No newline at end of file diff --git a/apps/opencs/view/world/previewsubview.hpp b/apps/opencs/view/world/previewsubview.hpp index 4ca25c3cb..a28be5c36 100644 --- a/apps/opencs/view/world/previewsubview.hpp +++ b/apps/opencs/view/world/previewsubview.hpp @@ -20,6 +20,7 @@ namespace CSVWorld Q_OBJECT CSVRender::PreviewWidget *mScene; + std::string mTitle; public: @@ -27,9 +28,9 @@ namespace CSVWorld virtual void setEditLock (bool locked); - private slots: + virtual std::string getTitle() const; - void closeRequest(); + private slots: void referenceableIdChanged (const std::string& id); }; diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index d10eebb30..ce68da362 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -150,9 +150,9 @@ void CSVWorld::SceneSubView::useHint (const std::string& hint) mScene->useViewHint (hint); } -void CSVWorld::SceneSubView::closeRequest() +std::string CSVWorld::SceneSubView::getTitle() const { - deleteLater(); + return mTitle; } void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id) @@ -161,10 +161,11 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& std::ostringstream stream; stream << "Scene: " << getUniversalId().getId(); - setWindowTitle (QString::fromUtf8 (stream.str().c_str())); + mTitle = stream.str(); + setWindowTitle (QString::fromUtf8 (mTitle.c_str())); + emit updateTitle(); } - void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection) { setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Scene, "sys::default")); @@ -189,7 +190,9 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection stream << "cell around it)"; } - setWindowTitle (QString::fromUtf8 (stream.str().c_str())); + mTitle = stream.str(); + setWindowTitle (QString::fromUtf8 (mTitle.c_str())); + emit updateTitle(); } void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalId >& data) diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index c0905f0d6..fc45347d0 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -44,6 +44,7 @@ namespace CSVWorld QHBoxLayout* mLayout; CSMDoc::Document& mDocument; CSVWidget::SceneToolbar* mToolbar; + std::string mTitle; public: @@ -57,6 +58,8 @@ namespace CSVWorld virtual void useHint (const std::string& hint); + virtual std::string getTitle() const; + private: void makeConnections(CSVRender::PagedWorldspaceWidget* widget); @@ -75,8 +78,6 @@ namespace CSVWorld private slots: - void closeRequest(); - void cellSelectionChanged (const CSMWorld::CellSelection& selection); void cellSelectionChanged (const CSMWorld::UniversalId& id); diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index df3fd87be..22d8e7e51 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -81,6 +81,6 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); if (!parent.isValid() && index.row()>=start && index.row()<=end) - deleteLater(); + emit closeRequest(); } diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 6adf3e0c1..ce53dcf5c 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -177,6 +177,79 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) menu.exec (event->globalPos()); } +void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event) +{ + Qt::KeyboardModifiers modifiers = + event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier); + + QModelIndex index = currentIndex(); + + selectionModel()->select (index, + QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows); + + std::map::iterator iter = + mDoubleClickActions.find (modifiers); + + if (iter==mDoubleClickActions.end()) + { + event->accept(); + return; + } + + switch (iter->second) + { + case Action_None: + + event->accept(); + break; + + case Action_InPlaceEdit: + + DragRecordTable::mouseDoubleClickEvent (event); + break; + + case Action_EditRecord: + + event->accept(); + editRecord(); + break; + + case Action_View: + + event->accept(); + viewRecord(); + break; + + case Action_Revert: + + event->accept(); + if (mDispatcher->canRevert()) + mDispatcher->executeRevert(); + break; + + case Action_Delete: + + event->accept(); + if (mDispatcher->canDelete()) + mDispatcher->executeDelete(); + break; + + case Action_EditRecordAndClose: + + event->accept(); + editRecord(); + emit closeRequest(); + break; + + case Action_ViewAndClose: + + event->accept(); + viewRecord(); + emit closeRequest(); + break; + } +} + CSVWorld::Table::Table (const CSMWorld::UniversalId& id, bool createAndDelete, bool sorting, CSMDoc::Document& document) : mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0), @@ -284,6 +357,11 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, this, SLOT (selectionSizeUpdate ())); setAcceptDrops(true); + + mDoubleClickActions.insert (std::make_pair (0, Action_InPlaceEdit)); + mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_EditRecord)); + mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_View)); + mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier | Qt::ControlModifier, Action_EditRecordAndClose)); } void CSVWorld::Table::setEditLock (bool locked) @@ -404,6 +482,9 @@ void CSVWorld::Table::editCell() void CSVWorld::Table::viewRecord() { + if (!(mModel->getFeatures() & CSMWorld::IdTableBase::Feature_View)) + return; + QModelIndexList selectedRows = selectionModel()->selectedRows(); if (selectedRows.size()==1) @@ -439,18 +520,59 @@ void CSVWorld::Table::previewRecord() void CSVWorld::Table::updateUserSetting (const QString &name, const QStringList &list) { - int columns = mModel->columnCount(); + if (name=="records/type-format" || name=="records/status-format") + { + int columns = mModel->columnCount(); - for (int i=0; i - (*delegate).updateUserSetting (name, list); + for (int i=0; iindex (0, i), - mModel->index (mModel->rowCount()-1, i)); + dynamic_cast + (*delegate).updateUserSetting (name, list); + { + emit dataChanged (mModel->index (0, i), + mModel->index (mModel->rowCount()-1, i)); + } } - } + return; + } + + QString base ("table-input/double"); + if (name.startsWith (base)) + { + QString modifierString = name.mid (base.size()); + Qt::KeyboardModifiers modifiers = 0; + + if (modifierString=="-s") + modifiers = Qt::ShiftModifier; + else if (modifierString=="-c") + modifiers = Qt::ControlModifier; + else if (modifierString=="-sc") + modifiers = Qt::ShiftModifier | Qt::ControlModifier; + + DoubleClickAction action = Action_None; + + QString value = list.at (0); + + if (value=="Edit in Place") + action = Action_InPlaceEdit; + else if (value=="Edit Record") + action = Action_EditRecord; + else if (value=="View") + action = Action_View; + else if (value=="Revert") + action = Action_Revert; + else if (value=="Delete") + action = Action_Delete; + else if (value=="Edit Record and Close") + action = Action_EditRecordAndClose; + else if (value=="View and Close") + action = Action_ViewAndClose; + + mDoubleClickActions[modifiers] = action; + + return; + } } void CSVWorld::Table::tableSizeUpdate() @@ -567,7 +689,6 @@ std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDraggedRecords() const { - QModelIndexList selectedRows = selectionModel()->selectedRows(); std::vector idToDrag; diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index a80a0b362..75161b8b6 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -36,6 +36,18 @@ namespace CSVWorld { Q_OBJECT + enum DoubleClickAction + { + Action_None, + Action_InPlaceEdit, + Action_EditRecord, + Action_View, + Action_Revert, + Action_Delete, + Action_EditRecordAndClose, + Action_ViewAndClose + }; + std::vector mDelegates; QAction *mEditAction; QAction *mCreateAction; @@ -53,8 +65,8 @@ namespace CSVWorld CSMWorld::IdTableBase *mModel; int mRecordStatusDisplay; CSMWorld::CommandDispatcher *mDispatcher; - CSMWorld::UniversalId mEditCellId; + std::map mDoubleClickActions; private: @@ -64,6 +76,10 @@ namespace CSVWorld void dropEvent(QDropEvent *event); + protected: + + virtual void mouseDoubleClickEvent (QMouseEvent *event); + public: Table (const CSMWorld::UniversalId& id, bool createAndDelete, @@ -94,6 +110,8 @@ namespace CSVWorld void cloneRequest(const CSMWorld::UniversalId&); + void closeRequest(); + private slots: void editCell(); diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index e2c8d5c1e..54518023b 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -69,6 +69,8 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D connect(mFilterBox, SIGNAL(recordDropped(std::vector&, Qt::DropAction)), this, SLOT(createFilterRequest(std::vector&, Qt::DropAction))); + + connect (mTable, SIGNAL (closeRequest()), this, SLOT (closeRequest())); } void CSVWorld::TableSubView::setEditLock (bool locked) @@ -150,3 +152,4 @@ bool CSVWorld::TableSubView::eventFilter (QObject* object, QEvent* event) } return false; } +