File indexing completed on 2024-05-12 05:40:38

0001 /*
0002     Cahoots is a crossplatform real-time collaborative text editor.
0003 
0004     Copyright (C) 2010 Chris Dimpfl, Anandi Hira, David Vega
0005 
0006     This program is free software: you can redistribute it and/or modify
0007     it under the terms of the GNU General Public License as published by
0008     the Free Software Foundation, either version 3 of the License, or
0009     (at your option) any later version.
0010 
0011     This program is distributed in the hope that it will be useful,
0012     but WITHOUT ANY WARRANTY; without even the implied warranty of
0013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014     GNU General Public License for more details.
0015 
0016     You should have received a copy of the GNU General Public License
0017     along with this program.  If not, see <http://www.gnu.org/licenses/>.
0018 */
0019 #include "sharednote.h"
0020 
0021 #include "ui_sharednote.h"
0022 #include <QCloseEvent>
0023 #include <QDebug>
0024 #include <QDesktopServices>
0025 #include <QFileInfo>
0026 #include <QFontDialog>
0027 #include <QMessageBox>
0028 #include <QPrintDialog>
0029 #include <QPrinter>
0030 #include <QScreen>
0031 #include <QTextDocument>
0032 #include <QTextDocumentFragment>
0033 
0034 #include "controller/view_controller/sharednotecontroller.h"
0035 #include "document.h"
0036 #include "enu.h"
0037 #include "utilities.h"
0038 
0039 SharedNote::SharedNote(SharedNoteController* ctrl, QWidget* parent)
0040     : QMainWindow(parent), m_sharedCtrl(ctrl), ui(new Ui::SharedNote)
0041 {
0042     ui->setupUi(this);
0043 
0044     if(!m_sharedCtrl)
0045         return;
0046 
0047     m_document= new Document(ctrl, ui->m_documentSupport);
0048     connect(m_document->getDocument(), &QTextDocument::contentsChange, this, &SharedNote::textHasChanged);
0049     auto pane= m_document->getParticipantPane();
0050 
0051     auto func= [this]() {
0052         if(!m_sharedCtrl)
0053             return;
0054         setWindowTitle(tr("%1 - Shared Note Editor").arg(m_sharedCtrl->name()));
0055     };
0056 
0057     connect(m_sharedCtrl, &SharedNoteController::nameChanged, this, func);
0058 
0059     connect(pane, &ParticipantsPane::memberCanNowRead, this, &SharedNote::populateDocumentForUser);
0060     connect(pane, &ParticipantsPane::memberPermissionsChanged, this, &SharedNote::playerPermissionsChanged);
0061     connect(m_document, &Document::contentChanged, this, [this]() { setWindowModified(true); });
0062 
0063     findDialog= new FindDialog(this);
0064     connect(findDialog, &FindDialog::findDialogFindNext, this, &SharedNote::findNextTriggered);
0065     connect(findDialog, &FindDialog::findDialogFindPrev, this, &SharedNote::findPrevTriggered);
0066     connect(findDialog, &FindDialog::findDialogReplaceAll, this, &SharedNote::replaceAllTriggered);
0067     connect(findDialog, &FindDialog::findDialogReplace, this, &SharedNote::replaceTriggered);
0068     connect(findDialog, &FindDialog::findDiaalogFindReplace, this, &SharedNote::findReplaceTriggered);
0069 
0070     QGridLayout* tabLayout= new QGridLayout;
0071     ui->m_documentSupport->setLayout(tabLayout);
0072     tabLayout->addWidget(m_document);
0073     tabLayout->setContentsMargins(0, 0, 0, 0);
0074 
0075     auto localIsOwner= (m_sharedCtrl->ownerId() == m_sharedCtrl->localId());
0076 
0077     connect(m_document, SIGNAL(undoAvailable(bool)), this, SLOT(setUndoability(bool)));
0078     connect(m_document, SIGNAL(redoAvailable(bool)), this, SLOT(setRedoability(bool)));
0079 
0080     if(localIsOwner)
0081     {
0082         connect(ui->m_showParticipants, &QAction::triggered, m_sharedCtrl,
0083                 &SharedNoteController::setParticipantPanelVisible);
0084         connect(m_sharedCtrl, &SharedNoteController::participantPanelVisibleChanged, ui->m_showParticipants,
0085                 &QAction::setChecked);
0086 
0087         connect(m_sharedCtrl, &SharedNoteController::participantPanelVisibleChanged, pane,
0088                 &ParticipantsPane::setVisible);
0089         connect(m_sharedCtrl, &SharedNoteController::participantPanelVisibleChanged, this,
0090                 [this](bool b) { m_document->setParticipantsHidden(!b); });
0091 
0092         ui->m_showParticipants->setChecked(m_sharedCtrl->participantPanelVisible());
0093     }
0094     else
0095     {
0096         ui->m_showParticipants->setChecked(false);
0097     }
0098 
0099     ui->m_showParticipants->setEnabled(localIsOwner);
0100 
0101     connect(ui->m_highlightMarkdownAction, &QAction::triggered, this, [this](bool b) {
0102         m_sharedCtrl->setHighligthedSyntax(b ? SharedNoteController::HighlightedSyntax::MarkDown :
0103                                                SharedNoteController::HighlightedSyntax::None);
0104     });
0105 
0106     connect(ui->m_markdownPreview, &QAction::triggered, m_sharedCtrl, &SharedNoteController::setMarkdownVisible);
0107 
0108     pane->setVisible(m_sharedCtrl->participantPanelVisible());
0109 
0110     readSettings();
0111 
0112     func();
0113     qApp->installEventFilter(this);
0114 }
0115 
0116 SharedNote::~SharedNote()
0117 {
0118     delete ui;
0119 }
0120 
0121 void SharedNote::readSettings()
0122 {
0123     QSettings settings("rolisteam", "SharedNote");
0124     auto screen= QApplication::primaryScreen()->availableGeometry();
0125     int width= static_cast<int>(screen.width() * 0.80);
0126     int height= static_cast<int>(screen.height() * 0.70);
0127     int screenWidth= screen.width();
0128     int screenHeight= screen.height();
0129     QPoint pos= settings.value("pos", QPoint((screenWidth - width) / 2, (screenHeight - height) / 2)).toPoint();
0130     QSize size= settings.value("size", QSize(width, height)).toSize();
0131     resize(size);
0132     move(pos);
0133 }
0134 
0135 void SharedNote::writeSettings()
0136 {
0137     QSettings settings("rolisteam", "SharedNote");
0138     settings.setValue("pos", pos());
0139     settings.setValue("size", size());
0140     settings.setValue("name", "user");
0141 }
0142 
0143 // Protected closeEvent
0144 void SharedNote::closeEvent(QCloseEvent*)
0145 {
0146     // bool okToQuit = true;
0147     /// @warning do something
0148 }
0149 void SharedNote::populateDocumentForUser(QString id)
0150 {
0151     /*NetworkMessageWriter msg(NetMsg::SharedNoteCategory, NetMsg::updateTextAndPermission, NetworkMessage::OneOrMany);
0152     QStringList ids;
0153     ids << id;
0154     msg.setRecipientList(ids, NetworkMessage::OneOrMany);
0155     msg.string8(m_id);
0156     m_document->fill(&msg);
0157     msg.sendToServer();*/
0158 }
0159 
0160 void SharedNote::setOwnerId(const QString& id)
0161 {
0162     updateWindowTitle();
0163 }
0164 bool SharedNote::eventFilter(QObject*, QEvent* event)
0165 {
0166     if(event->type() == QEvent::FileOpen)
0167     {
0168         QString fileName
0169             = static_cast<QFileOpenEvent*>(event)->file(); // for the sake of mirroring code in our open slot
0170         if(!fileName.isEmpty())
0171         {
0172         }
0173         event->accept();
0174         return true;
0175     }
0176     return false;
0177 }
0178 
0179 bool SharedNote::saveFile(QDataStream& out)
0180 {
0181     if(nullptr == m_document)
0182         return false;
0183 
0184     QApplication::setOverrideCursor(Qt::WaitCursor);
0185     out << m_document->getPlainText();
0186     QApplication::restoreOverrideCursor();
0187     m_document->setModified(false);
0188     setWindowModified(false);
0189     return true;
0190 }
0191 
0192 bool SharedNote::saveFileAsText(QTextStream& out)
0193 {
0194     if(nullptr == m_document)
0195         return false;
0196 
0197     out << m_document->getPlainText();
0198     m_document->setModified(false);
0199     setWindowModified(false);
0200     return true;
0201 }
0202 
0203 bool SharedNote::loadFileAsText(QTextStream& in, bool md)
0204 {
0205     if(nullptr == m_document)
0206         return false;
0207     QString data;
0208     data= in.readAll();
0209     m_document->setPlainText(data);
0210     if(md)
0211         m_sharedCtrl->setHighligthedSyntax(SharedNoteController::HighlightedSyntax::MarkDown);
0212 
0213     return true;
0214 }
0215 
0216 bool SharedNote::loadFile(QDataStream& in)
0217 {
0218     if(nullptr == m_document)
0219         return false;
0220 
0221     QString data;
0222     in >> data;
0223     m_document->setPlainText(data);
0224     return true;
0225 }
0226 
0227 QString SharedNote::strippedName(const QString& fullFileName)
0228 {
0229     return QFileInfo(fullFileName).fileName();
0230 }
0231 
0232 void SharedNote::on_actionFile_Print_triggered()
0233 {
0234     QTextDocument document(m_document->getPlainText(), this);
0235     document.setDefaultFont(QFont("Courier", 10, -1));
0236 
0237     QPrinter printer(QPrinter::HighResolution);
0238 
0239     QPrintDialog* dialog= new QPrintDialog(&printer, this);
0240     dialog->setWindowTitle("Print");
0241     if(dialog->exec() == QDialog::Accepted)
0242     {
0243         document.print(&printer);
0244     }
0245 }
0246 
0247 // Edit menu items
0248 void SharedNote::on_actionEdit_Undo_triggered()
0249 {
0250     m_document->undo();
0251 }
0252 
0253 void SharedNote::on_actionEdit_Redo_triggered()
0254 {
0255     m_document->redo();
0256 }
0257 
0258 void SharedNote::on_actionEdit_Cut_triggered()
0259 {
0260     m_document->cut();
0261 }
0262 
0263 void SharedNote::on_actionEdit_Copy_triggered()
0264 {
0265     m_document->copy();
0266 }
0267 
0268 void SharedNote::on_actionEdit_Paste_triggered()
0269 {
0270     m_document->paste();
0271 }
0272 
0273 void SharedNote::on_actionEdit_Find_All_triggered()
0274 {
0275     m_document->findAll();
0276 }
0277 
0278 void SharedNote::on_actionEdit_Find_triggered()
0279 {
0280     findDialog->show();
0281 }
0282 
0283 void SharedNote::on_actionView_Line_Wrap_triggered()
0284 {
0285     m_document->toggleLineWrap();
0286 }
0287 
0288 //#include "userlist/playersList.h"
0289 void SharedNote::textHasChanged(int pos, int charsRemoved, int charsAdded)
0290 {
0291     if(!m_sharedCtrl->localCanWrite())
0292         return;
0293 
0294     QString toSend;
0295     QString data;
0296 
0297     if(charsRemoved > 0 && charsAdded == 0)
0298     {
0299         data= "";
0300     }
0301     else if(charsAdded > 0)
0302     {
0303         QTextCursor cursor= QTextCursor(m_document->getDocument());
0304         cursor.setPosition(pos, QTextCursor::MoveAnchor);
0305         cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, charsAdded);
0306         data= cursor.selection().toPlainText();
0307     }
0308 
0309     toSend= QString("doc:%1 %2 %3 %4").arg(pos).arg(charsRemoved).arg(charsAdded).arg(data);
0310 
0311     m_sharedCtrl->setTextUpdate(toSend);
0312 }
0313 
0314 void SharedNote::displaySharingPanel()
0315 {
0316     m_document->displayParticipantPanel();
0317 }
0318 
0319 void SharedNote::updateDocumentToAll(NetworkMessageWriter* msg)
0320 {
0321     /* if(nullptr != m_document)
0322      {
0323          m_document->fill(msg);
0324      }*/
0325 }
0326 
0327 void SharedNote::on_actionText_Shift_Left_triggered()
0328 {
0329     m_document->shiftLeft();
0330 }
0331 
0332 void SharedNote::on_actionText_Shift_Right_triggered()
0333 {
0334     m_document->shiftRight();
0335 }
0336 
0337 void SharedNote::on_actionText_Comment_Line_triggered()
0338 {
0339     m_document->unCommentSelection();
0340 }
0341 
0342 void SharedNote::setUndoability(bool b)
0343 {
0344     if(sender() == m_document)
0345     {
0346         ui->actionEdit_Undo->setEnabled(b);
0347     }
0348 }
0349 
0350 void SharedNote::setRedoability(bool b)
0351 {
0352     if(sender() == m_document)
0353     {
0354         ui->actionEdit_Redo->setEnabled(b);
0355     }
0356 }
0357 
0358 void SharedNote::documentChanged()
0359 {
0360     Document* document= m_document;
0361     ui->actionEdit_Undo->setEnabled(document->isUndoable());
0362     ui->actionEdit_Redo->setEnabled(document->isRedoable());
0363     // ui->actionWindow_Split->setDisabled(document->isEditorSplit() && !document->isEditorSplitSideBySide());
0364     // ui->actionWindow_Split_Side_by_Side->setDisabled(document->isEditorSplit() &&
0365     // document->isEditorSplitSideBySide());
0366 
0367     // ui->actionWindow_Remove_Split->setEnabled(document->isEditorSplit());
0368     ui->actionTools_Announce_Document->setDisabled(document->docHasCollaborated());
0369 }
0370 
0371 void SharedNote::tabCloseClicked()
0372 {
0373     /*   if (maybeSave(index)) {
0374            if (ui->tabWidget->count() == 1) {
0375                on_actionFile_New_triggered();
0376            }
0377            ui->tabWidget->widget(index)->deleteLater();
0378            tabWidgetToDocumentMap.remove(ui->tabWidget->widget(index));
0379            ui->tabWidget->removeTab(index);
0380        }*/
0381 }
0382 
0383 void SharedNote::findNextTriggered(QString str, Qt::CaseSensitivity sensitivity, bool wrapAround, Enu::FindMode mode)
0384 {
0385     m_document->findNext(str, sensitivity, wrapAround, mode);
0386 }
0387 
0388 void SharedNote::findPrevTriggered(QString str, Qt::CaseSensitivity sensitivity, bool wrapAround, Enu::FindMode mode)
0389 {
0390     m_document->findPrev(str, sensitivity, wrapAround, mode);
0391 }
0392 
0393 void SharedNote::replaceAllTriggered(QString find, QString replace, Qt::CaseSensitivity sensitivity, Enu::FindMode mode)
0394 {
0395     m_document->replaceAll(find, replace, sensitivity, mode);
0396 }
0397 
0398 void SharedNote::replaceTriggered(QString replace)
0399 {
0400     m_document->replace(replace);
0401 }
0402 
0403 void SharedNote::findReplaceTriggered(QString find, QString replace, Qt::CaseSensitivity sensitivity, bool wrapAround,
0404                                       Enu::FindMode mode)
0405 {
0406     m_document->findReplace(find, replace, sensitivity, wrapAround, mode);
0407 }
0408 
0409 void SharedNote::playerPermissionsChanged(QString id, int perm)
0410 {
0411     // QString toSend = QString("updateperm:%1").arg(permissions);
0412     /*NetworkMessageWriter msg(NetMsg::SharedNoteCategory, NetMsg::updatePermissionOneUser);
0413     msg.string8(m_id); // MediaId
0414     msg.string8(id);   // playerId
0415     msg.int8(perm);    // Permission
0416     msg.sendToServer();*/
0417 }
0418 
0419 void SharedNote::setEditorFont(QFont font)
0420 {
0421     m_document->setEditorFont(font);
0422 }
0423 
0424 void SharedNote::setParticipantsFont(QFont font)
0425 {
0426     m_document->setParticipantsFont(font);
0427 }
0428 
0429 QString SharedNote::id() const
0430 {
0431     return m_id;
0432 }
0433 
0434 void SharedNote::setId(const QString& id)
0435 {
0436     m_id= id;
0437 }
0438 
0439 void SharedNote::updateWindowTitle()
0440 {
0441 
0442     /*PlayerModel* list= PlayerModel::instance();
0443     Player* player= list->getLocalPlayer();
0444     setWindowTitle(
0445         tr("%1[*] - SharedNote - %2").arg(m_fileName, m_document->canWrite(player) ? tr("ReadWrite") :
0446     tr("ReadOnly")));*/
0447 }
0448 
0449 void SharedNote::on_m_markdownPreview_triggered()
0450 {
0451     if(nullptr == m_document)
0452         return;
0453 
0454     m_document->renderMarkdown();
0455 }